[android] Added JNI for guides gallery and code to activate guides gallery on tap

This commit is contained in:
Александр Зацепин 2020-04-23 18:17:18 +03:00 committed by Daria Volvenkova
parent 5d71c4d313
commit 0eb7259e4c
5 changed files with 446 additions and 11 deletions

View file

@ -22,13 +22,13 @@ set(
SRC
# JNI headers
../../private.h
com/mapswithme/util/FeatureIdBuilder.hpp
com/mapswithme/core/jni_helper.hpp
com/mapswithme/core/logging.hpp
com/mapswithme/core/ScopedEnv.hpp
com/mapswithme/core/ScopedLocalRef.hpp
com/mapswithme/maps/discovery/Locals.hpp
com/mapswithme/maps/Framework.hpp
com/mapswithme/maps/guides/Guides.hpp
com/mapswithme/maps/promo/Promo.hpp
com/mapswithme/maps/SearchEngine.hpp
com/mapswithme/opengl/android_gl_utils.hpp
@ -37,6 +37,8 @@ set(
com/mapswithme/opengl/gl3stub.h
com/mapswithme/platform/GuiThread.hpp
com/mapswithme/platform/Platform.hpp
com/mapswithme/util/FeatureIdBuilder.hpp
com/mapswithme/vulkan/android_vulkan_context_factory.hpp
# JNI sources
com/mapswithme/core/jni_helper.cpp
@ -47,17 +49,19 @@ set(
com/mapswithme/maps/discovery/Locals.cpp
com/mapswithme/maps/DisplayedCategories.cpp
com/mapswithme/maps/DownloadResourcesLegacyActivity.cpp
com/mapswithme/maps/editor/OpeningHours.cpp
com/mapswithme/maps/editor/Editor.cpp
com/mapswithme/maps/editor/OpeningHours.cpp
com/mapswithme/maps/editor/OsmOAuth.cpp
com/mapswithme/maps/Framework.cpp
com/mapswithme/maps/guides/Guides.cpp
com/mapswithme/maps/isolines/IsolinesManager.cpp
com/mapswithme/maps/LightFramework.cpp
com/mapswithme/maps/LocationState.cpp
com/mapswithme/maps/LocationHelper.cpp
com/mapswithme/maps/LocationState.cpp
com/mapswithme/maps/MapFragment.cpp
com/mapswithme/maps/MapManager.cpp
com/mapswithme/maps/MwmApplication.cpp
com/mapswithme/maps/metrics/UserActionsLogger.cpp
com/mapswithme/maps/MwmApplication.cpp
com/mapswithme/maps/onboarding/Onboarding.cpp
com/mapswithme/maps/PrivateVariables.cpp
com/mapswithme/maps/promo/Promo.cpp
@ -67,20 +71,19 @@ set(
com/mapswithme/maps/settings/UnitLocale.cpp
com/mapswithme/maps/sound/tts.cpp
com/mapswithme/maps/Sponsored.cpp
com/mapswithme/maps/subway/SubwayManager.cpp
com/mapswithme/maps/taxi/TaxiManager.cpp
com/mapswithme/maps/TrackRecorder.cpp
com/mapswithme/maps/TrafficState.cpp
com/mapswithme/maps/isolines/IsolinesManager.cpp
com/mapswithme/maps/subway/SubwayManager.cpp
com/mapswithme/maps/ugc/UGC.cpp
com/mapswithme/maps/UserMarkHelper.cpp
com/mapswithme/opengl/android_gl_utils.cpp
com/mapswithme/opengl/androidoglcontext.cpp
com/mapswithme/opengl/androidoglcontextfactory.cpp
com/mapswithme/opengl/gl3stub.c
com/mapswithme/platform/GuiThread.cpp
com/mapswithme/platform/HttpThread.cpp
com/mapswithme/platform/HttpUserAgent.cpp
com/mapswithme/platform/GuiThread.cpp
com/mapswithme/platform/Language.cpp
com/mapswithme/platform/Localization.cpp
com/mapswithme/platform/MarketingService.cpp
@ -90,17 +93,16 @@ set(
com/mapswithme/platform/SocketImpl.cpp
com/mapswithme/util/Config.cpp
com/mapswithme/util/GeoUtils.cpp
com/mapswithme/util/HttpBackgroundUploader.cpp
com/mapswithme/util/HttpClient.cpp
com/mapswithme/util/HttpUploader.cpp
com/mapswithme/util/HttpBackgroundUploader.cpp
com/mapswithme/util/HttpUploaderUtils.cpp
com/mapswithme/util/Language.cpp
com/mapswithme/util/LoggerFactory.cpp
com/mapswithme/util/NetworkPolicy.cpp
com/mapswithme/util/StringUtils.cpp
com/mapswithme/util/statistics/PushwooshHelper.cpp
com/mapswithme/util/StringUtils.cpp
com/mapswithme/vulkan/android_vulkan_context_factory.cpp
com/mapswithme/vulkan/android_vulkan_context_factory.hpp
)
omim_add_library(mapswithme SHARED ${SRC})

View file

@ -1,10 +1,12 @@
#include "com/mapswithme/maps/Framework.hpp"
#include "com/mapswithme/core/jni_helper.hpp"
#include "com/mapswithme/maps/guides/Guides.hpp"
#include "com/mapswithme/maps/UserMarkHelper.hpp"
#include "com/mapswithme/opengl/androidoglcontextfactory.hpp"
#include "com/mapswithme/platform/Platform.hpp"
#include "com/mapswithme/util/NetworkPolicy.hpp"
#include "com/mapswithme/util/FeatureIdBuilder.hpp"
#include "com/mapswithme/util/NetworkPolicy.hpp"
#include "com/mapswithme/vulkan/android_vulkan_context_factory.hpp"
#include "map/chart_generator.hpp"
@ -1039,6 +1041,12 @@ Java_com_mapswithme_maps_Framework_nativePlacePageActivationListener(JNIEnv *env
auto const elevationInfo = frm()->GetBookmarkManager().MakeElevationInfo(info.GetTrackId());
placePageDataRef.reset(usermark_helper::CreateElevationInfo(env, serverId, elevationInfo));
}
else if (info.IsGuide())
{
auto const & guidesManager = frm()->GetGuidesManager();
auto const gallery = guidesManager.GetGallery();
placePageDataRef.reset(guides::CreateGallery(env, gallery));
}
else
{
placePageDataRef.reset(usermark_helper::CreateMapObject(env, info));

View file

@ -0,0 +1,85 @@
#include "com/mapswithme/maps/guides/Guides.hpp"
namespace
{
jclass g_galleryClass = nullptr;
jclass g_itemClass = nullptr;
jclass g_cityParamsClass = nullptr;
jclass g_outdoorParamsClass = nullptr;
jmethodID g_galleryConstructor = nullptr;
jmethodID g_itemConstructor = nullptr;
jmethodID g_cityParamsConstructor = nullptr;
jmethodID g_outdoorParamsConstructor = nullptr;
void PrepareClassRefs(JNIEnv *env)
{
if (g_galleryClass != nullptr)
return;
g_galleryClass = jni::GetGlobalClassRef(env, "com/mapswithme/maps/guides/GuidesGallery");
g_galleryConstructor = jni::GetConstructorID(env, g_galleryClass,
"([Lcom/mapswithme/maps/guides/GuidesGallery$Item;)V");
g_itemClass = jni::GetGlobalClassRef(env, "com/mapswithme/maps/guides/GuidesGallery$Item");
// public Item(@NonNull String guideId, @NonNull String url, @NonNull String imageUrl,
// @NonNull String title, @NonNull String subTitle, int type,
// boolean downloaded, @Nullable CityParams cityParams,
// @Nullable OutdoorParams outdoorParams)
g_itemConstructor
= jni::GetConstructorID(env, g_itemClass, "(Ljava/lang/String;Ljava/lang/String;"
"Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;"
"IZLcom/mapswithme/maps/guides/GuidesGallery$CityParams;"
"Lcom/mapswithme/maps/guides/GuidesGallery$OutdoorParams;)"
"V");
g_cityParamsClass
= jni::GetGlobalClassRef(env, "com/mapswithme/maps/guides/GuidesGallery$CityParams");
// public CityParams(int bookmarksCount, boolean isTrackAvailable)
g_cityParamsConstructor = jni::GetConstructorID(env, g_cityParamsClass, "(IZ)V");
g_outdoorParamsClass
= jni::GetGlobalClassRef(env, "com/mapswithme/maps/guides/GuidesGallery$OutdoorParams");
// public OutdoorParams(double distance, long duration, int ascent)
g_outdoorParamsConstructor
= jni::GetConstructorID(env, g_outdoorParamsClass, "(DJI)V");
jni::HandleJavaException(env);
}
} // namespace
namespace guides
{
jobject CreateGallery(JNIEnv *env, GuidesManager::GuidesGallery const & gallery)
{
PrepareClassRefs(env);
auto const itemBuilder = [](JNIEnv *env, GuidesManager::GuidesGallery::Item const & item)
{
jni::TScopedLocalRef guideId(env, jni::ToJavaString(env, item.m_guideId));
jni::TScopedLocalRef url(env, jni::ToJavaString(env, item.m_url));
jni::TScopedLocalRef imageUrl(env, jni::ToJavaString(env, item.m_imageUrl));
jni::TScopedLocalRef title(env, jni::ToJavaString(env, item.m_title));
jni::TScopedLocalRef subtitle(env, jni::ToJavaString(env, item.m_subTitle));
auto const type = static_cast<jint>(item.m_type);
auto const downloaded = static_cast<jboolean>(item.m_downloaded);
jni::TScopedLocalRef cityParams(env, nullptr);
jni::TScopedLocalRef outdoorParams(env, nullptr);
if (item.m_type == GuidesManager::GuidesGallery::Item::Type::City)
{
cityParams.reset(env->NewObject(g_cityParamsClass, g_cityParamsConstructor,
static_cast<jint>(item.m_cityParams.m_bookmarksCount),
static_cast<jboolean>(item.m_cityParams.m_trackIsAvailable)));
} else if (item.m_type == GuidesManager::GuidesGallery::Item::Type::Outdoor)
{
outdoorParams.reset(env->NewObject(g_outdoorParamsClass, g_outdoorParamsConstructor,
static_cast<jdouble>(item.m_outdoorsParams.m_distance),
static_cast<jlong>(item.m_outdoorsParams.m_duration),
static_cast<jint>(item.m_outdoorsParams.m_ascent)));
}
return env->NewObject(g_itemClass, g_itemConstructor, guideId.get(), url.get(), imageUrl.get(),
title.get(), subtitle.get(), type, downloaded, cityParams.get(),
outdoorParams.get());
};
jni::TScopedLocalObjectArrayRef items(env, jni::ToJavaArray(env, g_itemClass, gallery.m_items,
itemBuilder));
return env->NewObject(g_galleryClass, g_galleryConstructor, items.get());
}
} // namespace guides

View file

@ -0,0 +1,9 @@
#pragma once
#include "com/mapswithme/core/jni_helper.hpp"
#include "map/guides_manager.hpp"
namespace guides
{
jobject CreateGallery(JNIEnv * env, GuidesManager::GuidesGallery const & gallery);
} // namespace

View file

@ -0,0 +1,331 @@
package com.mapswithme.maps.guides;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.mapswithme.maps.widget.placepage.PlacePageData;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class GuidesGallery implements PlacePageData
{
@NonNull
private final List<Item> mItems;
public GuidesGallery(@NonNull Item[] items)
{
mItems = Arrays.asList(items);
}
@NonNull
public List<Item> getItems()
{
return Collections.unmodifiableList(mItems);
}
protected GuidesGallery(Parcel in)
{
List<Item> items = new ArrayList<>();
in.readTypedList(items, Item.CREATOR);
mItems = items;
}
@Override
public int describeContents()
{
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
// All collections are deserialized AFTER non-collection and primitive type objects,
// so collections must be always serialized at the end.
dest.writeTypedList(mItems);
}
public static final Creator<GuidesGallery> CREATOR = new Creator<GuidesGallery>()
{
@Override
public GuidesGallery createFromParcel(Parcel in)
{
return new GuidesGallery(in);
}
@Override
public GuidesGallery[] newArray(int size)
{
return new GuidesGallery[size];
}
};
public static class Item implements Parcelable
{
@NonNull
private final String mGuideId;
@NonNull
private final String mUrl;
@NonNull
private final String mImageUrl;
@NonNull
private final String mTitle;
@NonNull
private final String mSubTitle;
@NonNull
private final Type mType;
private final boolean mDownloaded;
@Nullable
private final CityParams mCityParams;
@Nullable
private final OutdoorParams mOutdoorParams;
public Item(@NonNull String guideId, @NonNull String url, @NonNull String imageUrl,
@NonNull String title, @NonNull String subTitle, int type,
boolean downloaded, @Nullable CityParams cityParams,
@Nullable OutdoorParams outdoorParams)
{
mGuideId = guideId;
mUrl = url;
mImageUrl = imageUrl;
mTitle = title;
mSubTitle = subTitle;
mType = Type.values()[type];
mDownloaded = downloaded;
mCityParams = cityParams;
mOutdoorParams = outdoorParams;
}
protected Item(Parcel in)
{
mGuideId = in.readString();
mUrl = in.readString();
mImageUrl = in.readString();
mTitle = in.readString();
mSubTitle = in.readString();
mType = Type.values()[in.readInt()];
mDownloaded = in.readByte() != 0;
mCityParams = in.readParcelable(CityParams.class.getClassLoader());
mOutdoorParams = in.readParcelable(OutdoorParams.class.getClassLoader());
}
public static final Creator<Item> CREATOR = new Creator<Item>()
{
@Override
public Item createFromParcel(Parcel in)
{
return new Item(in);
}
@Override
public Item[] newArray(int size)
{
return new Item[size];
}
};
@NonNull
public String getGuideId()
{
return mGuideId;
}
@NonNull
public String getUrl()
{
return mUrl;
}
@NonNull
public String getImageUrl()
{
return mImageUrl;
}
@NonNull
public String getTitle()
{
return mTitle;
}
@NonNull
public String getSubTitle()
{
return mSubTitle;
}
@NonNull
public Type getType()
{
return mType;
}
public boolean isDownloaded()
{
return mDownloaded;
}
@Nullable
public CityParams getCityParams()
{
return mCityParams;
}
@Nullable
public OutdoorParams getOutdoorParams()
{
return mOutdoorParams;
}
@Override
public int describeContents()
{
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeString(mGuideId);
dest.writeString(mUrl);
dest.writeString(mImageUrl);
dest.writeString(mTitle);
dest.writeString(mSubTitle);
dest.writeInt(mType.ordinal());
dest.writeByte((byte) (mDownloaded ? 1 : 0));
dest.writeParcelable(mCityParams, flags);
dest.writeParcelable(mOutdoorParams, flags);
}
}
public static class CityParams implements Parcelable
{
private final int mBookmarksCount;
private final boolean mIsTrackAvailable;
public CityParams(int bookmarksCount, boolean isTrackAvailable)
{
mBookmarksCount = bookmarksCount;
mIsTrackAvailable = isTrackAvailable;
}
protected CityParams(Parcel in)
{
mBookmarksCount = in.readInt();
mIsTrackAvailable = in.readByte() != 0;
}
public static final Creator<CityParams> CREATOR = new Creator<CityParams>()
{
@Override
public CityParams createFromParcel(Parcel in)
{
return new CityParams(in);
}
@Override
public CityParams[] newArray(int size)
{
return new CityParams[size];
}
};
public int getBookmarksCount()
{
return mBookmarksCount;
}
public boolean isTrackAvailable()
{
return mIsTrackAvailable;
}
@Override
public int describeContents()
{
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeInt(mBookmarksCount);
dest.writeByte((byte) (mIsTrackAvailable ? 1 : 0));
}
}
public static class OutdoorParams implements Parcelable
{
private final double mDistance;
private final long mDuration;
private final int mAscent;
public OutdoorParams(double distance, long duration, int ascent)
{
mDistance = distance;
mDuration = duration;
mAscent = ascent;
}
protected OutdoorParams(Parcel in)
{
mDistance = in.readDouble();
mDuration = in.readLong();
mAscent = in.readInt();
}
public static final Creator<OutdoorParams> CREATOR = new Creator<OutdoorParams>()
{
@Override
public OutdoorParams createFromParcel(Parcel in)
{
return new OutdoorParams(in);
}
@Override
public OutdoorParams[] newArray(int size)
{
return new OutdoorParams[size];
}
};
public double getDistance()
{
return mDistance;
}
public long getDuration()
{
return mDuration;
}
public int getAscent()
{
return mAscent;
}
@Override
public int describeContents()
{
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeDouble(mDistance);
dest.writeLong(mDuration);
dest.writeInt(mAscent);
}
}
enum Type
{
City,
Outdoor
}
}