This commit is contained in:
Andrei Shkrob 2025-03-09 10:12:07 +00:00 committed by GitHub
commit 72f0705aaa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
83 changed files with 1384 additions and 1059 deletions

View file

@ -25,6 +25,20 @@ set(SRC
app/organicmaps/sdk/search/DisplayedCategories.cpp
app/organicmaps/sdk/search/SearchEngine.cpp
app/organicmaps/sdk/search/SearchRecents.cpp
app/organicmaps/sdk/routing/JunctionInfo.hpp
app/organicmaps/sdk/routing/RouteMarkData.hpp
app/organicmaps/sdk/routing/RouteMarkType.hpp
app/organicmaps/sdk/routing/RoutePointInfo.hpp
app/organicmaps/sdk/routing/RouteRecommendationType.hpp
app/organicmaps/sdk/routing/RoutingInfo.hpp
app/organicmaps/sdk/routing/RoutingOptions.cpp
app/organicmaps/sdk/routing/SingleLaneInfo.hpp
app/organicmaps/sdk/routing/TransitRouteInfo.hpp
app/organicmaps/sdk/routing/TransitStepInfo.hpp
app/organicmaps/sdk/ChoosePositionMode.cpp
app/organicmaps/sdk/MapStyle.cpp
app/organicmaps/sdk/OrganicMaps.cpp
app/organicmaps/sdk/Router.cpp
app/organicmaps/core/jni_helper.cpp
app/organicmaps/core/jni_java_methods.cpp
app/organicmaps/core/logging.cpp
@ -38,8 +52,6 @@ set(SRC
app/organicmaps/LocationState.cpp
app/organicmaps/Map.cpp
app/organicmaps/MapManager.cpp
app/organicmaps/MwmApplication.cpp
app/organicmaps/routing/RoutingOptions.cpp
app/organicmaps/settings/UnitLocale.cpp
app/organicmaps/settings/MapLanguageCode.cpp
app/organicmaps/sound/tts.cpp

View file

@ -4,6 +4,12 @@
#include "app/organicmaps/UserMarkHelper.hpp"
#include "app/organicmaps/opengl/androidoglcontextfactory.hpp"
#include "app/organicmaps/platform/AndroidPlatform.hpp"
#include "app/organicmaps/sdk/routing/JunctionInfo.hpp"
#include "app/organicmaps/sdk/routing/RouteMarkData.hpp"
#include "app/organicmaps/sdk/routing/RouteMarkType.hpp"
#include "app/organicmaps/sdk/routing/RouteRecommendationType.hpp"
#include "app/organicmaps/sdk/routing/RoutingInfo.hpp"
#include "app/organicmaps/sdk/routing/TransitRouteInfo.hpp"
#include "app/organicmaps/util/Distance.hpp"
#include "app/organicmaps/util/FeatureIdBuilder.hpp"
#include "app/organicmaps/util/NetworkPolicy.hpp"
@ -804,8 +810,8 @@ void CallRouteRecommendationListener(shared_ptr<jobject> listener,
RoutingManager::Recommendation recommendation)
{
JNIEnv * env = jni::GetEnv();
jmethodID const methodId = jni::GetMethodID(env, *listener, "onRecommend", "(I)V");
env->CallVoidMethod(*listener, methodId, static_cast<int>(recommendation));
jmethodID const methodId = jni::GetMethodID(env, *listener, "onRecommend", "(Lapp/organicmaps/sdk/routing/RouteRecommendationType;)V");
env->CallVoidMethod(*listener, methodId, GetRouteRecommendationType(env, recommendation));
}
void CallSetRoutingLoadPointsListener(shared_ptr<jobject> listener, bool success)
@ -1241,7 +1247,7 @@ Java_app_organicmaps_Framework_nativeDisableFollowing(JNIEnv * env, jclass)
}
JNIEXPORT jobjectArray JNICALL
Java_app_organicmaps_Framework_nativeGenerateNotifications(JNIEnv * env, jclass, bool announceStreets)
Java_app_organicmaps_Framework_nativeGenerateNotifications(JNIEnv * env, jclass, jboolean announceStreets)
{
::Framework * fr = frm();
if (!fr->GetRoutingManager().IsRoutingActive())
@ -1271,64 +1277,16 @@ Java_app_organicmaps_Framework_nativeGetSpeedCamManagerMode(JNIEnv * env, jclass
JNIEXPORT jobject JNICALL
Java_app_organicmaps_Framework_nativeGetRouteFollowingInfo(JNIEnv * env, jclass)
{
::Framework * fr = frm();
if (!fr->GetRoutingManager().IsRoutingActive())
RoutingManager & rm = frm()->GetRoutingManager();
if (!rm.IsRoutingActive())
return nullptr;
routing::FollowingInfo info;
fr->GetRoutingManager().GetRouteFollowingInfo(info);
rm.GetRouteFollowingInfo(info);
if (!info.IsValid())
return nullptr;
static jclass const klass = jni::GetGlobalClassRef(env, "app/organicmaps/routing/RoutingInfo");
// Java signature : RoutingInfo(Distance distToTarget, Distance distToTurn,
// String currentStreet, String nextStreet, String nextNextStreet,
// double completionPercent, int vehicleTurnOrdinal, int
// vehicleNextTurnOrdinal, int pedestrianTurnOrdinal, int exitNum,
// int totalTime, SingleLaneInfo[] lanes)
static jmethodID const ctorRouteInfoID =
jni::GetConstructorID(env, klass,
"(Lapp/organicmaps/util/Distance;Lapp/organicmaps/util/Distance;"
"Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;DIIIII"
"[Lapp/organicmaps/routing/SingleLaneInfo;DZZ)V");
vector<routing::FollowingInfo::SingleLaneInfoClient> const & lanes = info.m_lanes;
jobjectArray jLanes = nullptr;
if (!lanes.empty())
{
static jclass const laneClass = jni::GetGlobalClassRef(env, "app/organicmaps/routing/SingleLaneInfo");
auto const lanesSize = static_cast<jsize>(lanes.size());
jLanes = env->NewObjectArray(lanesSize, laneClass, nullptr);
ASSERT(jLanes, (jni::DescribeException()));
static jmethodID const ctorSingleLaneInfoID = jni::GetConstructorID(env, laneClass, "([BZ)V");
for (jsize j = 0; j < lanesSize; ++j)
{
auto const laneSize = static_cast<jsize>(lanes[j].m_lane.size());
jni::TScopedLocalByteArrayRef singleLane(env, env->NewByteArray(laneSize));
ASSERT(singleLane.get(), (jni::DescribeException()));
env->SetByteArrayRegion(singleLane.get(), 0, laneSize, lanes[j].m_lane.data());
jni::TScopedLocalRef singleLaneInfo(
env, env->NewObject(laneClass, ctorSingleLaneInfoID, singleLane.get(),
lanes[j].m_isRecommended));
ASSERT(singleLaneInfo.get(), (jni::DescribeException()));
env->SetObjectArrayElement(jLanes, j, singleLaneInfo.get());
}
}
auto const & rm = frm()->GetRoutingManager();
auto const isSpeedCamLimitExceeded = rm.IsRoutingActive() ? rm.IsSpeedCamLimitExceeded() : false;
auto const shouldPlaySignal = frm()->GetRoutingManager().GetSpeedCamManager().ShouldPlayBeepSignal();
jobject const result = env->NewObject(
klass, ctorRouteInfoID, ToJavaDistance(env, info.m_distToTarget),
ToJavaDistance(env, info.m_distToTurn), jni::ToJavaString(env, info.m_currentStreetName),
jni::ToJavaString(env, info.m_nextStreetName), jni::ToJavaString(env, info.m_nextNextStreetName),
info.m_completionPercent, info.m_turn, info.m_nextTurn, info.m_pedestrianTurn, info.m_exitNum,
info.m_time, jLanes, info.m_speedLimitMps, static_cast<jboolean>(isSpeedCamLimitExceeded),
static_cast<jboolean>(shouldPlaySignal));
ASSERT(result, (jni::DescribeException()));
return result;
return CreateRoutingInfo(env, info, rm);
}
JNIEXPORT jobjectArray JNICALL
@ -1341,17 +1299,7 @@ Java_app_organicmaps_Framework_nativeGetRouteJunctionPoints(JNIEnv * env, jclass
return nullptr;
}
static jclass const junctionClazz = jni::GetGlobalClassRef(env, "app/organicmaps/routing/JunctionInfo");
// Java signature : JunctionInfo(double lat, double lon)
static jmethodID const junctionConstructor = jni::GetConstructorID(env, junctionClazz, "(DD)V");
return jni::ToJavaArray(env, junctionClazz, junctionPoints,
[](JNIEnv * env, m2::PointD const & point)
{
return env->NewObject(junctionClazz, junctionConstructor,
mercator::YToLat(point.y),
mercator::XToLon(point.x));
});
return CreateJunctionInfoArray(env, junctionPoints);
}
JNIEXPORT jintArray JNICALL
@ -1500,69 +1448,9 @@ Java_app_organicmaps_Framework_nativeDeactivateMapSelectionCircle(JNIEnv * env,
return g_framework->DeactivateMapSelectionCircle();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_Framework_nativeSetMapStyle(JNIEnv * env, jclass, jint mapStyle)
{
MapStyle const val = static_cast<MapStyle>(mapStyle);
if (val != g_framework->GetMapStyle())
g_framework->SetMapStyle(val);
}
JNIEXPORT jint JNICALL
Java_app_organicmaps_Framework_nativeGetMapStyle(JNIEnv * env, jclass)
{
return g_framework->GetMapStyle();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_Framework_nativeMarkMapStyle(JNIEnv * env, jclass, jint mapStyle)
{
MapStyle const val = static_cast<MapStyle>(mapStyle);
if (val != g_framework->GetMapStyle())
g_framework->MarkMapStyle(val);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_Framework_nativeSetRouter(JNIEnv * env, jclass, jint routerType)
{
using Type = routing::RouterType;
Type type = Type::Vehicle;
switch (routerType)
{
case 0: break;
case 1: type = Type::Pedestrian; break;
case 2: type = Type::Bicycle; break;
case 3: type = Type::Transit; break;
case 4: type = Type::Ruler; break;
default: assert(false); break;
}
g_framework->GetRoutingManager().SetRouter(type);
}
JNIEXPORT jint JNICALL
Java_app_organicmaps_Framework_nativeGetRouter(JNIEnv * env, jclass)
{
return static_cast<jint>(g_framework->GetRoutingManager().GetRouter());
}
JNIEXPORT jint JNICALL
Java_app_organicmaps_Framework_nativeGetLastUsedRouter(JNIEnv * env, jclass)
{
return static_cast<jint>(g_framework->GetRoutingManager().GetLastUsedRouter());
}
JNIEXPORT jint JNICALL
Java_app_organicmaps_Framework_nativeGetBestRouter(JNIEnv * env, jclass,
jdouble srcLat, jdouble srcLon,
jdouble dstLat, jdouble dstLon)
{
return static_cast<jint>(frm()->GetRoutingManager().GetBestRouter(
mercator::FromLatLon(srcLat, srcLon), mercator::FromLatLon(dstLat, dstLon)));
}
JNIEXPORT void JNICALL
Java_app_organicmaps_Framework_nativeAddRoutePoint(JNIEnv * env, jclass, jstring title,
jstring subtitle, jint markType,
jstring subtitle, jobject markType,
jint intermediateIndex,
jboolean isMyPosition,
jdouble lat, jdouble lon)
@ -1570,7 +1458,7 @@ Java_app_organicmaps_Framework_nativeAddRoutePoint(JNIEnv * env, jclass, jstring
RouteMarkData data;
data.m_title = jni::ToNativeString(env, title);
data.m_subTitle = jni::ToNativeString(env, subtitle);
data.m_pointType = static_cast<RouteMarkType>(markType);
data.m_pointType = GetRouteMarkType(env, markType);
data.m_intermediateIndex = static_cast<size_t>(intermediateIndex);
data.m_isMyPosition = static_cast<bool>(isMyPosition);
data.m_position = m2::PointD(mercator::FromLatLon(lat, lon));
@ -1585,10 +1473,9 @@ Java_app_organicmaps_Framework_nativeRemoveRoutePoints(JNIEnv * env, jclass)
}
JNIEXPORT void JNICALL
Java_app_organicmaps_Framework_nativeRemoveRoutePoint(JNIEnv * env, jclass,
jint markType, jint intermediateIndex)
Java_app_organicmaps_Framework_nativeRemoveRoutePoint(JNIEnv * env, jclass, jobject markType, jint intermediateIndex)
{
frm()->GetRoutingManager().RemoveRoutePoint(static_cast<RouteMarkType>(markType),
frm()->GetRoutingManager().RemoveRoutePoint(GetRouteMarkType(env, markType),
static_cast<size_t>(intermediateIndex));
}
@ -1607,30 +1494,7 @@ Java_app_organicmaps_Framework_nativeCouldAddIntermediatePoint(JNIEnv * env, jcl
JNIEXPORT jobjectArray JNICALL
Java_app_organicmaps_Framework_nativeGetRoutePoints(JNIEnv * env, jclass)
{
auto const points = frm()->GetRoutingManager().GetRoutePoints();
static jclass const pointClazz = jni::GetGlobalClassRef(env,
"app/organicmaps/routing/RouteMarkData");
// Java signature : RouteMarkData(String title, String subtitle,
// @RoutePointInfo.RouteMarkType int pointType,
// int intermediateIndex, boolean isVisible, boolean isMyPosition,
// boolean isPassed, double lat, double lon)
static jmethodID const pointConstructor = jni::GetConstructorID(env, pointClazz,
"(Ljava/lang/String;Ljava/lang/String;IIZZZDD)V");
return jni::ToJavaArray(env, pointClazz, points, [&](JNIEnv * jEnv, RouteMarkData const & data)
{
jni::TScopedLocalRef const title(env, jni::ToJavaString(env, data.m_title));
jni::TScopedLocalRef const subtitle(env, jni::ToJavaString(env, data.m_subTitle));
return env->NewObject(pointClazz, pointConstructor,
title.get(), subtitle.get(),
static_cast<jint>(data.m_pointType),
static_cast<jint>(data.m_intermediateIndex),
static_cast<jboolean>(data.m_isVisible),
static_cast<jboolean>(data.m_isMyPosition),
static_cast<jboolean>(data.m_isPassed),
mercator::YToLat(data.m_position.y),
mercator::XToLon(data.m_position.x));
});
return CreateRouteMarkDataArray(env, frm()->GetRoutingManager().GetRoutePoints());
}
JNIEXPORT void JNICALL
@ -1643,49 +1507,7 @@ Java_app_organicmaps_Framework_nativeMoveRoutePoint(JNIEnv * env, jclass,
JNIEXPORT jobject JNICALL
Java_app_organicmaps_Framework_nativeGetTransitRouteInfo(JNIEnv * env, jclass)
{
auto const routeInfo = frm()->GetRoutingManager().GetTransitRouteInfo();
static jclass const transitStepClass = jni::GetGlobalClassRef(env,
"app/organicmaps/routing/TransitStepInfo");
// Java signature : TransitStepInfo(@TransitType int type, @Nullable String distance, @Nullable String distanceUnits,
// int timeInSec, @Nullable String number, int color, int intermediateIndex)
static jmethodID const transitStepConstructor = jni::GetConstructorID(env, transitStepClass,
"(ILjava/lang/String;Ljava/lang/String;ILjava/lang/String;II)V");
jni::TScopedLocalRef const steps(env, jni::ToJavaArray(env, transitStepClass,
routeInfo.m_steps,
[&](JNIEnv * jEnv, TransitStepInfo const & stepInfo)
{
jni::TScopedLocalRef const distance(env, jni::ToJavaString(env, stepInfo.m_distanceStr));
jni::TScopedLocalRef const distanceUnits(env, jni::ToJavaString(env, stepInfo.m_distanceUnitsSuffix));
jni::TScopedLocalRef const number(env, jni::ToJavaString(env, stepInfo.m_number));
return env->NewObject(transitStepClass, transitStepConstructor,
static_cast<jint>(stepInfo.m_type),
distance.get(),
distanceUnits.get(),
static_cast<jint>(stepInfo.m_timeInSec),
number.get(),
static_cast<jint>(stepInfo.m_colorARGB),
static_cast<jint>(stepInfo.m_intermediateIndex));
}));
static jclass const transitRouteInfoClass = jni::GetGlobalClassRef(env,
"app/organicmaps/routing/TransitRouteInfo");
// Java signature : TransitRouteInfo(@NonNull String totalDistance, @NonNull String totalDistanceUnits, int totalTimeInSec,
// @NonNull String totalPedestrianDistance, @NonNull String totalPedestrianDistanceUnits,
// int totalPedestrianTimeInSec, @NonNull TransitStepInfo[] steps)
static jmethodID const transitRouteInfoConstructor = jni::GetConstructorID(env, transitRouteInfoClass,
"(Ljava/lang/String;Ljava/lang/String;I"
"Ljava/lang/String;Ljava/lang/String;I"
"[Lapp/organicmaps/routing/TransitStepInfo;)V");
jni::TScopedLocalRef const distance(env, jni::ToJavaString(env, routeInfo.m_totalDistanceStr));
jni::TScopedLocalRef const distanceUnits(env, jni::ToJavaString(env, routeInfo.m_totalDistanceUnitsSuffix));
jni::TScopedLocalRef const distancePedestrian(env, jni::ToJavaString(env, routeInfo.m_totalPedestrianDistanceStr));
jni::TScopedLocalRef const distancePedestrianUnits(env, jni::ToJavaString(env, routeInfo.m_totalPedestrianUnitsSuffix));
return env->NewObject(transitRouteInfoClass, transitRouteInfoConstructor,
distance.get(), distanceUnits.get(), static_cast<jint>(routeInfo.m_totalTimeInSec),
distancePedestrian.get(), distancePedestrianUnits.get(), static_cast<jint>(routeInfo.m_totalPedestrianTimeInSec),
steps.get());
return CreateTransitRouteInfo(env, frm()->GetRoutingManager().GetTransitRouteInfo());
}
JNIEXPORT void JNICALL
@ -1821,25 +1643,6 @@ Java_app_organicmaps_Framework_nativeGetPoiContactUrl(JNIEnv *env, jclass, jint
return jni::ToJavaString(env, value);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_Framework_nativeSetChoosePositionMode(JNIEnv *, jclass, jint mode, jboolean isBusiness,
jboolean applyPosition)
{
// TODO(AB): Move this code into the Framework to share with iOS and other platforms.
auto const f = frm();
if (applyPosition && f->HasPlacePageInfo())
g_framework->SetChoosePositionMode(static_cast<android::ChoosePositionMode>(mode), isBusiness,
&f->GetCurrentPlacePageInfo().GetMercator());
else
g_framework->SetChoosePositionMode(static_cast<android::ChoosePositionMode>(mode), isBusiness, nullptr);
}
JNIEXPORT jint JNICALL
Java_app_organicmaps_Framework_nativeGetChoosePositionMode(JNIEnv *, jclass)
{
return static_cast<jint>(g_framework->GetChoosePositionMode());
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_Framework_nativeIsDownloadedMapAtScreenCenter(JNIEnv *, jclass)
{

View file

@ -1,60 +0,0 @@
#include "app/organicmaps/Framework.hpp"
#include "app/organicmaps/platform/AndroidPlatform.hpp"
#include "app/organicmaps/core/jni_helper.hpp"
extern "C"
{
// static void nativeSetSettingsDir(String settingsPath);
JNIEXPORT void JNICALL
Java_app_organicmaps_MwmApplication_nativeSetSettingsDir(JNIEnv * env, jclass clazz, jstring settingsPath)
{
android::Platform::Instance().SetSettingsDir(jni::ToNativeString(env, settingsPath));
}
// static void nativeInitPlatform(Context context, String apkPath, String storagePath, String privatePath, String tmpPath,
// String flavorName, String buildType, boolean isTablet);
JNIEXPORT void JNICALL
Java_app_organicmaps_MwmApplication_nativeInitPlatform(JNIEnv * env, jclass clazz, jobject context,
jstring apkPath, jstring writablePath,
jstring privatePath, jstring tmpPath,
jstring flavorName, jstring buildType,
jboolean isTablet)
{
android::Platform::Instance().Initialize(env, context, apkPath, writablePath, privatePath, tmpPath,
flavorName, buildType, isTablet);
}
// static void nativeInitFramework(@NonNull Runnable onComplete);
JNIEXPORT void JNICALL
Java_app_organicmaps_MwmApplication_nativeInitFramework(JNIEnv * env, jclass clazz, jobject onComplete)
{
if (!g_framework)
{
g_framework = std::make_unique<android::Framework>([onComplete = jni::make_global_ref(onComplete)]()
{
JNIEnv * env = jni::GetEnv();
jmethodID const methodId = jni::GetMethodID(env, *onComplete, "run", "()V");
env->CallVoidMethod(*onComplete, methodId);
});
}
}
// static void nativeAddLocalization(String name, String value);
JNIEXPORT void JNICALL
Java_app_organicmaps_MwmApplication_nativeAddLocalization(JNIEnv * env, jclass clazz, jstring name, jstring value)
{
g_framework->AddString(jni::ToNativeString(env, name),
jni::ToNativeString(env, value));
}
JNIEXPORT void JNICALL
Java_app_organicmaps_MwmApplication_nativeOnTransit(JNIEnv *, jclass, jboolean foreground)
{
if (static_cast<bool>(foreground))
g_framework->NativeFramework()->EnterForeground();
else
g_framework->NativeFramework()->EnterBackground();
}
}

View file

@ -1,5 +1,7 @@
#include "UserMarkHelper.hpp"
#include "app/organicmaps/sdk/routing/RoutePointInfo.hpp"
#include "map/elevation_info.hpp"
#include "map/place_page_info.hpp"
@ -47,7 +49,7 @@ jobject CreateMapObject(JNIEnv * env, place_page::Info const & info, int mapObje
static jmethodID const ctorId = jni::GetConstructorID(
env, g_mapObjectClazz,
"("
"Lapp/organicmaps/bookmarks/data/FeatureId;" // featureId
"Lapp/organicmaps/bookmarks/data/FeatureId;" // featureId
"I" // mapObjectType
"Ljava/lang/String;" // title
"Ljava/lang/String;" // secondaryTitle
@ -55,7 +57,7 @@ jobject CreateMapObject(JNIEnv * env, place_page::Info const & info, int mapObje
"Ljava/lang/String;" // address
"DD" // lat, lon
"Ljava/lang/String;" // appId
"Lapp/organicmaps/routing/RoutePointInfo;" // routePointInfo
"Lapp/organicmaps/sdk/routing/RoutePointInfo;" // routePointInfo
"I" // openingMode
"Lapp/organicmaps/sdk/search/Popularity;" // popularity
"Ljava/lang/String;" // description
@ -104,7 +106,7 @@ jobject CreateBookmark(JNIEnv *env, const place_page::Info &info,
jni::GetConstructorID(env, g_bookmarkClazz,
"(Lapp/organicmaps/bookmarks/data/FeatureId;JJLjava/lang/String;"
"Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;"
"Lapp/organicmaps/routing/RoutePointInfo;"
"Lapp/organicmaps/sdk/routing/RoutePointInfo;"
"ILapp/organicmaps/sdk/search/Popularity;Ljava/lang/String;"
"[Ljava/lang/String;)V");
static jmethodID const featureCtorId =
@ -213,14 +215,6 @@ jobject CreateMapObject(JNIEnv * env, place_page::Info const & info)
routingPointInfo.get(), popularity, jrawTypes.get());
}
jobject CreateRoutePointInfo(JNIEnv * env, place_page::Info const & info)
{
static jclass const clazz = jni::GetGlobalClassRef(env, "app/organicmaps/routing/RoutePointInfo");
static jmethodID const ctorId = jni::GetConstructorID(env, clazz, "(II)V");
int const markType = static_cast<int>(info.GetRouteMarkType());
return env->NewObject(clazz, ctorId, markType, info.GetIntermediateIndex());
}
jobject CreateFeatureId(JNIEnv * env, FeatureID const & fid)
{
static jmethodID const featureCtorId =

View file

@ -40,8 +40,6 @@ jobjectArray ToRatingArray(JNIEnv * env, std::vector<std::string> const & rating
jobject CreateLocalAdInfo(JNIEnv * env, place_page::Info const & info);
jobject CreateRoutePointInfo(JNIEnv * env, place_page::Info const & info);
jobject CreateFeatureId(JNIEnv * env, FeatureID const & fid);
jobjectArray ToFeatureIdArray(JNIEnv * env, std::vector<FeatureID> const & ids);
} // namespace usermark_helper

View file

@ -0,0 +1,26 @@
#include "app/organicmaps/core/jni_helper.hpp"
#include "app/organicmaps/Framework.hpp"
#include "indexer/map_style.hpp"
extern "C"
{
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_ChoosePositionMode_nativeSet(JNIEnv *, jclass, jint mode,
jboolean isBusiness,
jboolean applyPosition)
{
// TODO(AB): Move this code into the Framework to share with iOS and other platforms.
auto const f = frm();
if (applyPosition && f->HasPlacePageInfo())
g_framework->SetChoosePositionMode(static_cast<android::ChoosePositionMode>(mode), isBusiness,
&f->GetCurrentPlacePageInfo().GetMercator());
else
g_framework->SetChoosePositionMode(static_cast<android::ChoosePositionMode>(mode), isBusiness, nullptr);
}
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_ChoosePositionMode_nativeGet(JNIEnv *, jclass)
{
return static_cast<jint>(g_framework->GetChoosePositionMode());
}
}

View file

@ -0,0 +1,27 @@
#include "app/organicmaps/core/jni_helper.hpp"
#include "app/organicmaps/Framework.hpp"
#include "indexer/map_style.hpp"
extern "C"
{
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_MapStyle_nativeSet(JNIEnv *, jclass, jint mapStyle)
{
auto const val = static_cast<MapStyle>(mapStyle);
if (val != g_framework->GetMapStyle())
g_framework->SetMapStyle(val);
}
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_MapStyle_nativeGet(JNIEnv *, jclass)
{
return g_framework->GetMapStyle();
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_MapStyle_nativeMark(JNIEnv *, jclass, jint mapStyle)
{
auto const val = static_cast<MapStyle>(mapStyle);
if (val != g_framework->GetMapStyle())
g_framework->MarkMapStyle(val);
}
}

View file

@ -0,0 +1,56 @@
#include "app/organicmaps/Framework.hpp"
#include "app/organicmaps/platform/AndroidPlatform.hpp"
#include "app/organicmaps/core/jni_helper.hpp"
extern "C"
{
// static void nativeSetSettingsDir(String settingsPath);
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_OrganicMaps_nativeSetSettingsDir(JNIEnv * env, jclass clazz,
jstring settingsPath)
{
android::Platform::Instance().SetSettingsDir(jni::ToNativeString(env, settingsPath));
}
// static void nativeInitPlatform(Context context, String apkPath, String storagePath, String privatePath, String
// tmpPath, String flavorName, String buildType, boolean isTablet);
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_OrganicMaps_nativeInitPlatform(
JNIEnv * env, jclass clazz, jobject context, jstring apkPath, jstring writablePath, jstring privatePath,
jstring tmpPath, jstring flavorName, jstring buildType, jboolean isTablet)
{
android::Platform::Instance().Initialize(env, context, apkPath, writablePath, privatePath, tmpPath, flavorName,
buildType, isTablet);
}
// static void nativeInitFramework(@NonNull Runnable onComplete);
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_OrganicMaps_nativeInitFramework(JNIEnv * env, jclass clazz,
jobject onComplete)
{
if (!g_framework)
{
g_framework = std::make_unique<android::Framework>(
[onComplete = jni::make_global_ref(onComplete)]()
{
JNIEnv * env = jni::GetEnv();
jmethodID const methodId = jni::GetMethodID(env, *onComplete, "run", "()V");
env->CallVoidMethod(*onComplete, methodId);
});
}
}
// static void nativeAddLocalization(String name, String value);
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_OrganicMaps_nativeAddLocalization(JNIEnv * env, jclass clazz,
jstring name, jstring value)
{
g_framework->AddString(jni::ToNativeString(env, name), jni::ToNativeString(env, value));
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_OrganicMaps_nativeOnTransit(JNIEnv *, jclass, jboolean foreground)
{
if (static_cast<bool>(foreground))
g_framework->NativeFramework()->EnterForeground();
else
g_framework->NativeFramework()->EnterBackground();
}
}

View file

@ -0,0 +1,41 @@
#include "app/organicmaps/core/jni_helper.hpp"
#include "app/organicmaps/Framework.hpp"
#include "indexer/map_style.hpp"
extern "C"
{
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Router_nativeSet(JNIEnv *, jclass, jint routerType)
{
using Type = routing::RouterType;
Type type;
switch (routerType)
{
case 0: type = Type::Vehicle; break;
case 1: type = Type::Pedestrian; break;
case 2: type = Type::Bicycle; break;
case 3: type = Type::Transit; break;
case 4: type = Type::Ruler; break;
default: assert(false); break;
}
frm()->GetRoutingManager().SetRouter(type);
}
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_Router_nativeGet(JNIEnv *, jclass)
{
return static_cast<jint>(frm()->GetRoutingManager().GetRouter());
}
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_Router_nativeGetLastUsed(JNIEnv *, jclass)
{
return static_cast<jint>(frm()->GetRoutingManager().GetLastUsedRouter());
}
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_Router_nativeGetBest(JNIEnv *, jclass, jdouble srcLat, jdouble srcLon,
jdouble dstLat, jdouble dstLon)
{
return static_cast<jint>(frm()->GetRoutingManager().GetBestRouter(mercator::FromLatLon(srcLat, srcLon),
mercator::FromLatLon(dstLat, dstLon)));
}
}

View file

@ -0,0 +1,21 @@
#pragma once
#include "app/organicmaps/core/jni_helper.hpp"
#include "geometry/point2d.hpp"
#include <vector>
jobjectArray CreateJunctionInfoArray(JNIEnv * env, std::vector<m2::PointD> const & junctionPoints)
{
static jclass const junctionClazz = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/JunctionInfo");
// Java signature : JunctionInfo(double lat, double lon)
static jmethodID const junctionConstructor = jni::GetConstructorID(env, junctionClazz, "(DD)V");
return jni::ToJavaArray(env, junctionClazz, junctionPoints,
[](JNIEnv * env, m2::PointD const & point)
{
return env->NewObject(junctionClazz, junctionConstructor, mercator::YToLat(point.y),
mercator::XToLon(point.x));
});
}

View file

@ -0,0 +1,29 @@
#pragma once
#include "app/organicmaps/core/jni_helper.hpp"
#include "geometry/point2d.hpp"
#include <vector>
jobjectArray CreateRouteMarkDataArray(JNIEnv * env, std::vector<RouteMarkData> const & points)
{
static jclass const pointClazz = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/RouteMarkData");
// Java signature : RouteMarkData(String title, String subtitle, int pointType,
// int intermediateIndex, boolean isVisible, boolean isMyPosition,
// boolean isPassed, double lat, double lon)
static jmethodID const pointConstructor =
jni::GetConstructorID(env, pointClazz, "(Ljava/lang/String;Ljava/lang/String;IIZZZDD)V");
return jni::ToJavaArray(env, pointClazz, points,
[&](JNIEnv * jEnv, RouteMarkData const & data)
{
jni::TScopedLocalRef const title(env, jni::ToJavaString(env, data.m_title));
jni::TScopedLocalRef const subtitle(env, jni::ToJavaString(env, data.m_subTitle));
return env->NewObject(
pointClazz, pointConstructor, title.get(), subtitle.get(),
static_cast<jint>(data.m_pointType), static_cast<jint>(data.m_intermediateIndex),
static_cast<jboolean>(data.m_isVisible), static_cast<jboolean>(data.m_isMyPosition),
static_cast<jboolean>(data.m_isPassed), mercator::YToLat(data.m_position.y),
mercator::XToLon(data.m_position.x));
});
}

View file

@ -0,0 +1,12 @@
#pragma once
#include "app/organicmaps/sdk/routing/RouteMarkType.hpp"
#include "map/routing_mark.hpp"
RouteMarkType GetRouteMarkType(JNIEnv * env, jobject markType)
{
static jmethodID const ordinal = jni::GetMethodID(env, markType, "ordinal", "()I");
return static_cast<RouteMarkType>(env->CallIntMethod(markType, ordinal));
}

View file

@ -0,0 +1,13 @@
#pragma once
#include "app/organicmaps/core/jni_helper.hpp"
#include "map/place_page_info.hpp"
jobject CreateRoutePointInfo(JNIEnv * env, place_page::Info const & info)
{
static jclass const clazz = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/RoutePointInfo");
static jmethodID const ctorId = jni::GetConstructorID(env, clazz, "(II)V");
int const markType = static_cast<int>(info.GetRouteMarkType());
return env->NewObject(clazz, ctorId, markType, info.GetIntermediateIndex());
}

View file

@ -0,0 +1,38 @@
#pragma once
#include "app/organicmaps/core/jni_helper.hpp"
jobject GetRebuildAfterPointsLoading(JNIEnv * env)
{
static jobject rebuildAfterPointsLoading = nullptr;
if (rebuildAfterPointsLoading)
return rebuildAfterPointsLoading;
// Find the RouteRecommendationType class
jclass routeRecommendationTypeClass = env->FindClass("app/organicmaps/sdk/routing/RouteRecommendationType");
ASSERT(routeRecommendationTypeClass, ());
// Get the values() method of RouteRecommendationType
jmethodID valuesMethod = env->GetStaticMethodID(routeRecommendationTypeClass, "values",
"()[Lapp/organicmaps/sdk/routing/RouteRecommendationType;");
ASSERT(valuesMethod, ());
// Call values() to get all enum constants
jobjectArray enumConstants = (jobjectArray)env->CallStaticObjectMethod(routeRecommendationTypeClass, valuesMethod);
ASSERT(enumConstants, ());
// Retrieve the first (and only) constant, RebuildAfterPointsLoading
rebuildAfterPointsLoading = env->NewGlobalRef(env->GetObjectArrayElement(enumConstants, 0));
ASSERT(rebuildAfterPointsLoading, ());
return rebuildAfterPointsLoading;
}
jobject GetRouteRecommendationType(JNIEnv * env, RoutingManager::Recommendation recommendation)
{
switch (recommendation)
{
case RoutingManager::Recommendation::RebuildAfterPointsLoading: return GetRebuildAfterPointsLoading(env);
default: ASSERT_FAIL("Unknown recommendation type");
}
}

View file

@ -0,0 +1,34 @@
#pragma once
#include "app/organicmaps/core/jni_helper.hpp"
#include "app/organicmaps/sdk/routing/SingleLaneInfo.hpp"
#include "map/routing_manager.hpp"
jobject CreateRoutingInfo(JNIEnv * env, routing::FollowingInfo const & info, RoutingManager & rm)
{
static jclass const klass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/RoutingInfo");
// Java signature : RoutingInfo(Distance distToTarget, Distance distToTurn,
// String currentStreet, String nextStreet, String nextNextStreet,
// double completionPercent, int vehicleTurnOrdinal, int
// vehicleNextTurnOrdinal, int pedestrianTurnOrdinal, int exitNum,
// int totalTime, SingleLaneInfo[] lanes)
static jmethodID const ctorRouteInfoID =
jni::GetConstructorID(env, klass,
"(Lapp/organicmaps/util/Distance;Lapp/organicmaps/util/Distance;"
"Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;DIIIII"
"[Lapp/organicmaps/sdk/routing/SingleLaneInfo;DZZ)V");
jobjectArray jLanes = CreateLanesInfo(env, info.m_lanes);
auto const isSpeedCamLimitExceeded = rm.IsSpeedCamLimitExceeded();
auto const shouldPlaySignal = rm.GetSpeedCamManager().ShouldPlayBeepSignal();
jobject const result = env->NewObject(
klass, ctorRouteInfoID, ToJavaDistance(env, info.m_distToTarget), ToJavaDistance(env, info.m_distToTurn),
jni::ToJavaString(env, info.m_currentStreetName), jni::ToJavaString(env, info.m_nextStreetName),
jni::ToJavaString(env, info.m_nextNextStreetName), info.m_completionPercent, info.m_turn, info.m_nextTurn,
info.m_pedestrianTurn, info.m_exitNum, info.m_time, jLanes, info.m_speedLimitMps,
static_cast<jboolean>(isSpeedCamLimitExceeded), static_cast<jboolean>(shouldPlaySignal));
ASSERT(result, (jni::DescribeException()));
return result;
}

View file

@ -5,16 +5,15 @@
routing::RoutingOptions::Road makeValue(jint option)
{
uint8_t const road = static_cast<uint8_t>(1u << static_cast<int>(option));
auto const road = static_cast<uint8_t>(1u << static_cast<int>(option));
CHECK_LESS(road, static_cast<uint8_t>(routing::RoutingOptions::Road::Max), ());
return static_cast<routing::RoutingOptions::Road>(road);
}
extern "C"
{
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_routing_RoutingOptions_nativeHasOption(JNIEnv * env, jclass clazz, jint option)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_routing_RoutingOptions_nativeHasOption(JNIEnv *, jclass,
jint option)
{
CHECK(g_framework, ("Framework isn't created yet!"));
routing::RoutingOptions routingOptions = routing::RoutingOptions::LoadCarOptionsFromSettings();
@ -22,8 +21,7 @@ Java_app_organicmaps_routing_RoutingOptions_nativeHasOption(JNIEnv * env, jclass
return static_cast<jboolean>(routingOptions.Has(road));
}
JNIEXPORT void JNICALL
Java_app_organicmaps_routing_RoutingOptions_nativeAddOption(JNIEnv * env, jclass clazz, jint option)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_routing_RoutingOptions_nativeAddOption(JNIEnv *, jclass, jint option)
{
CHECK(g_framework, ("Framework isn't created yet!"));
routing::RoutingOptions routingOptions = routing::RoutingOptions::LoadCarOptionsFromSettings();
@ -32,9 +30,7 @@ Java_app_organicmaps_routing_RoutingOptions_nativeAddOption(JNIEnv * env, jclass
routing::RoutingOptions::SaveCarOptionsToSettings(routingOptions);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_routing_RoutingOptions_nativeRemoveOption(JNIEnv * env, jclass clazz, jint option)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_routing_RoutingOptions_nativeRemoveOption(JNIEnv *, jclass, jint option)
{
CHECK(g_framework, ("Framework isn't created yet!"));
routing::RoutingOptions routingOptions = routing::RoutingOptions::LoadCarOptionsFromSettings();

View file

@ -0,0 +1,34 @@
#pragma once
#include "app/organicmaps/core/jni_helper.hpp"
#include "routing/following_info.hpp"
#include <vector>
jobjectArray CreateLanesInfo(JNIEnv * env, std::vector<routing::FollowingInfo::SingleLaneInfoClient> const & lanes)
{
if (lanes.empty())
return nullptr;
static jclass const laneClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/SingleLaneInfo");
auto const lanesSize = static_cast<jsize>(lanes.size());
jobjectArray jLanes = env->NewObjectArray(lanesSize, laneClass, nullptr);
ASSERT(jLanes, (jni::DescribeException()));
static jmethodID const ctorSingleLaneInfoID = jni::GetConstructorID(env, laneClass, "([BZ)V");
for (jsize j = 0; j < lanesSize; ++j)
{
auto const laneSize = static_cast<jsize>(lanes[j].m_lane.size());
jni::TScopedLocalByteArrayRef singleLane(env, env->NewByteArray(laneSize));
ASSERT(singleLane.get(), (jni::DescribeException()));
env->SetByteArrayRegion(singleLane.get(), 0, laneSize, lanes[j].m_lane.data());
jni::TScopedLocalRef singleLaneInfo(
env, env->NewObject(laneClass, ctorSingleLaneInfoID, singleLane.get(), lanes[j].m_isRecommended));
ASSERT(singleLaneInfo.get(), (jni::DescribeException()));
env->SetObjectArrayElement(jLanes, j, singleLaneInfo.get());
}
return jLanes;
}

View file

@ -0,0 +1,32 @@
#pragma once
#include "app/organicmaps/core/jni_helper.hpp"
#include "app/organicmaps/sdk/routing/TransitStepInfo.hpp"
#include "map/transit/transit_display.hpp"
jobject CreateTransitRouteInfo(JNIEnv * env, TransitRouteInfo const & routeInfo)
{
jobjectArray steps = CreateTransitStepInfoArray(env, routeInfo.m_steps);
static jclass const transitRouteInfoClass =
jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/TransitRouteInfo");
// Java signature : TransitRouteInfo(@NonNull String totalDistance, @NonNull String totalDistanceUnits,
// int totalTimeInSec, @NonNull String totalPedestrianDistance, @NonNull String
// totalPedestrianDistanceUnits, int totalPedestrianTimeInSec, @NonNull
// TransitStepInfo[] steps)
static jmethodID const transitRouteInfoConstructor =
jni::GetConstructorID(env, transitRouteInfoClass,
"(Ljava/lang/String;Ljava/lang/String;I"
"Ljava/lang/String;Ljava/lang/String;I"
"[Lapp/organicmaps/sdk/routing/TransitStepInfo;)V");
jni::TScopedLocalRef const distance(env, jni::ToJavaString(env, routeInfo.m_totalDistanceStr));
jni::TScopedLocalRef const distanceUnits(env, jni::ToJavaString(env, routeInfo.m_totalDistanceUnitsSuffix));
jni::TScopedLocalRef const distancePedestrian(env, jni::ToJavaString(env, routeInfo.m_totalPedestrianDistanceStr));
jni::TScopedLocalRef const distancePedestrianUnits(env,
jni::ToJavaString(env, routeInfo.m_totalPedestrianUnitsSuffix));
return env->NewObject(transitRouteInfoClass, transitRouteInfoConstructor, distance.get(), distanceUnits.get(),
static_cast<jint>(routeInfo.m_totalTimeInSec), distancePedestrian.get(),
distancePedestrianUnits.get(), static_cast<jint>(routeInfo.m_totalPedestrianTimeInSec), steps);
}

View file

@ -0,0 +1,28 @@
#pragma once
#include "app/organicmaps/core/jni_helper.hpp"
#include "map/transit/transit_display.hpp"
#include <vector>
jobjectArray CreateTransitStepInfoArray(JNIEnv * env, std::vector<TransitStepInfo> const & steps)
{
static jclass const transitStepClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/routing/TransitStepInfo");
// Java signature : TransitStepInfo(int type, @Nullable String distance, @Nullable String distanceUnits,
// int timeInSec, @Nullable String number, int color, int intermediateIndex)
static jmethodID const transitStepConstructor =
jni::GetConstructorID(env, transitStepClass, "(ILjava/lang/String;Ljava/lang/String;ILjava/lang/String;II)V");
return jni::ToJavaArray(
env, transitStepClass, steps,
[&](JNIEnv * jEnv, TransitStepInfo const & stepInfo)
{
jni::TScopedLocalRef const distance(env, jni::ToJavaString(env, stepInfo.m_distanceStr));
jni::TScopedLocalRef const distanceUnits(env, jni::ToJavaString(env, stepInfo.m_distanceUnitsSuffix));
jni::TScopedLocalRef const number(env, jni::ToJavaString(env, stepInfo.m_number));
return env->NewObject(transitStepClass, transitStepConstructor, static_cast<jint>(stepInfo.m_type),
distance.get(), distanceUnits.get(), static_cast<jint>(stepInfo.m_timeInSec), number.get(),
static_cast<jint>(stepInfo.m_colorARGB), static_cast<jint>(stepInfo.m_intermediateIndex));
});
}

View file

@ -2,9 +2,7 @@ package app.organicmaps;
import android.graphics.Bitmap;
import androidx.annotation.IntDef;
import androidx.annotation.Keep;
import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Size;
@ -15,19 +13,20 @@ import app.organicmaps.api.RequestType;
import app.organicmaps.bookmarks.data.DistanceAndAzimut;
import app.organicmaps.bookmarks.data.FeatureId;
import app.organicmaps.bookmarks.data.MapObject;
import app.organicmaps.products.Product;
import app.organicmaps.products.ProductsConfig;
import app.organicmaps.routing.JunctionInfo;
import app.organicmaps.routing.RouteMarkData;
import app.organicmaps.routing.RoutePointInfo;
import app.organicmaps.routing.RoutingInfo;
import app.organicmaps.routing.TransitRouteInfo;
import app.organicmaps.sdk.routing.JunctionInfo;
import app.organicmaps.sdk.routing.RouteMarkData;
import app.organicmaps.sdk.routing.RouteMarkType;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.routing.TransitRouteInfo;
import app.organicmaps.sdk.PlacePageActivationListener;
import app.organicmaps.sdk.routing.RoutingListener;
import app.organicmaps.sdk.routing.RoutingLoadPointsListener;
import app.organicmaps.sdk.routing.RoutingProgressListener;
import app.organicmaps.sdk.routing.RoutingRecommendationListener;
import app.organicmaps.settings.SettingsPrefsFragment;
import app.organicmaps.widget.placepage.PlacePageData;
import app.organicmaps.util.Constants;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
@ -39,87 +38,6 @@ import java.util.Locale;
*/
public class Framework
{
@Retention(RetentionPolicy.SOURCE)
@IntDef({MAP_STYLE_CLEAR, MAP_STYLE_DARK, MAP_STYLE_VEHICLE_CLEAR, MAP_STYLE_VEHICLE_DARK, MAP_STYLE_OUTDOORS_CLEAR, MAP_STYLE_OUTDOORS_DARK})
public @interface MapStyle {}
public static final int MAP_STYLE_CLEAR = 0;
public static final int MAP_STYLE_DARK = 1;
public static final int MAP_STYLE_VEHICLE_CLEAR = 3;
public static final int MAP_STYLE_VEHICLE_DARK = 4;
public static final int MAP_STYLE_OUTDOORS_CLEAR = 5;
public static final int MAP_STYLE_OUTDOORS_DARK = 6;
@Retention(RetentionPolicy.SOURCE)
@IntDef({ ROUTER_TYPE_VEHICLE, ROUTER_TYPE_PEDESTRIAN, ROUTER_TYPE_BICYCLE, ROUTER_TYPE_TRANSIT, ROUTER_TYPE_RULER })
public @interface RouterType {}
public static final int ROUTER_TYPE_VEHICLE = 0;
public static final int ROUTER_TYPE_PEDESTRIAN = 1;
public static final int ROUTER_TYPE_BICYCLE = 2;
public static final int ROUTER_TYPE_TRANSIT = 3;
public static final int ROUTER_TYPE_RULER = 4;
@Retention(RetentionPolicy.SOURCE)
@IntDef({ROUTE_REBUILD_AFTER_POINTS_LOADING})
public @interface RouteRecommendationType {}
public static final int ROUTE_REBUILD_AFTER_POINTS_LOADING = 0;
public interface PlacePageActivationListener
{
// Called from JNI.
@Keep
@SuppressWarnings("unused")
void onPlacePageActivated(@NonNull PlacePageData data);
// Called from JNI
@Keep
@SuppressWarnings("unused")
void onPlacePageDeactivated();
// Called from JNI
@Keep
@SuppressWarnings("unused")
void onSwitchFullScreenMode();
}
public interface RoutingListener
{
// Called from JNI
@Keep
@SuppressWarnings("unused")
@MainThread
void onRoutingEvent(int resultCode, String[] missingMaps);
}
public interface RoutingProgressListener
{
// Called from JNI.
@Keep
@SuppressWarnings("unused")
@MainThread
void onRouteBuildingProgress(float progress);
}
public interface RoutingRecommendationListener
{
// Called from JNI.
@Keep
@SuppressWarnings("unused")
void onRecommend(@RouteRecommendationType int recommendation);
}
public interface RoutingLoadPointsListener
{
// Called from JNI.
@Keep
@SuppressWarnings("unused")
void onRoutePointsLoaded(boolean success);
}
// Used by JNI.
@Keep
@SuppressWarnings("unused")
@ -301,38 +219,16 @@ public class Framework
private static native void nativeSetSpeedCamManagerMode(int mode);
public static native void nativeSetRoutingListener(RoutingListener listener);
public static native void nativeSetRoutingListener(@NonNull RoutingListener listener);
public static native void nativeSetRouteProgressListener(RoutingProgressListener listener);
public static native void nativeSetRouteProgressListener(@NonNull RoutingProgressListener listener);
public static native void nativeSetRoutingRecommendationListener(RoutingRecommendationListener listener);
public static native void nativeSetRoutingRecommendationListener(@NonNull RoutingRecommendationListener listener);
public static native void nativeSetRoutingLoadPointsListener(
@Nullable RoutingLoadPointsListener listener);
public static native void nativeSetRoutingLoadPointsListener(@NonNull RoutingLoadPointsListener listener);
public static native void nativeShowCountry(String countryId, boolean zoomToDownloadButton);
public static native void nativeSetMapStyle(int mapStyle);
@MapStyle
public static native int nativeGetMapStyle();
/**
* This method allows to set new map style without immediate applying. It can be used before
* engine recreation instead of nativeSetMapStyle to avoid huge flow of OpenGL invocations.
* @param mapStyle style index
*/
public static native void nativeMarkMapStyle(int mapStyle);
public static native void nativeSetRouter(@RouterType int routerType);
@RouterType
public static native int nativeGetRouter();
@RouterType
public static native int nativeGetLastUsedRouter();
@RouterType
public static native int nativeGetBestRouter(double srcLat, double srcLon,
double dstLat, double dstLon);
public static void addRoutePoint(RouteMarkData point)
{
Framework.nativeAddRoutePoint(point.mTitle, point.mSubtitle, point.mPointType,
@ -340,15 +236,13 @@ public class Framework
point.mLat, point.mLon);
}
public static native void nativeAddRoutePoint(String title, String subtitle,
@RoutePointInfo.RouteMarkType int markType,
public static native void nativeAddRoutePoint(String title, String subtitle, @NonNull RouteMarkType markType,
int intermediateIndex, boolean isMyPosition,
double lat, double lon);
public static native void nativeRemoveRoutePoints();
public static native void nativeRemoveRoutePoint(@RoutePointInfo.RouteMarkType int markType,
int intermediateIndex);
public static native void nativeRemoveRoutePoint(@NonNull RouteMarkType markType, int intermediateIndex);
public static native void nativeRemoveIntermediateRoutePoints();
@ -404,23 +298,6 @@ public class Framework
public static native void nativeZoomToPoint(double lat, double lon, int zoom, boolean animate);
@Retention(RetentionPolicy.SOURCE)
@IntDef({ChoosePositionMode.NONE, ChoosePositionMode.EDITOR, ChoosePositionMode.API})
public @interface ChoosePositionMode
{
// Keep in sync with `enum ChoosePositionMode` in Framework.hpp.
public static final int NONE = 0;
public static final int EDITOR = 1;
public static final int API = 2;
}
/**
* @param mode - see ChoosePositionMode values.
* @param isBusiness selection area will be bounded by building borders, if its true (eg. true for businesses in buildings).
* @param applyPosition if true, map'll be animated to currently selected object.
*/
public static native void nativeSetChoosePositionMode(@ChoosePositionMode int mode, boolean isBusiness,
boolean applyPosition);
public static native @ChoosePositionMode int nativeGetChoosePositionMode();
public static native boolean nativeIsDownloadedMapAtScreenCenter();
public static native String nativeGetActiveObjectFormattedCuisine();
@ -446,7 +323,7 @@ public class Framework
public static native void nativeMakeCrash();
public static native void nativeSetPowerManagerFacility(int facilityType, boolean state);
public static native void nativeSetPowerManagerFacility(int facilityType, boolean state);
public static native int nativeGetPowerManagerScheme();
public static native void nativeSetPowerManagerScheme(int schemeType);
public static native void nativeSetViewportCenter(double lat, double lon, int zoom);

View file

@ -40,7 +40,6 @@ import androidx.fragment.app.FragmentFactory;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.ViewModelProvider;
import app.organicmaps.Framework.PlacePageActivationListener;
import app.organicmaps.api.Const;
import app.organicmaps.base.BaseMwmFragmentActivity;
import app.organicmaps.base.OnBackPressListener;
@ -80,13 +79,17 @@ import app.organicmaps.maplayer.isolines.IsolinesState;
import app.organicmaps.routing.ManageRouteBottomSheet;
import app.organicmaps.routing.NavigationController;
import app.organicmaps.routing.NavigationService;
import app.organicmaps.routing.RoutePointInfo;
import app.organicmaps.sdk.routing.RouteMarkType;
import app.organicmaps.sdk.routing.RoutePointInfo;
import app.organicmaps.routing.RoutingBottomMenuListener;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.routing.RoutingErrorDialogFragment;
import app.organicmaps.routing.RoutingOptions;
import app.organicmaps.sdk.routing.RoutingOptions;
import app.organicmaps.routing.RoutingPlanFragment;
import app.organicmaps.routing.RoutingPlanInplaceController;
import app.organicmaps.sdk.ChoosePositionMode;
import app.organicmaps.sdk.PlacePageActivationListener;
import app.organicmaps.sdk.Router;
import app.organicmaps.search.FloatingSearchToolbarController;
import app.organicmaps.search.SearchActivity;
import app.organicmaps.sdk.search.SearchEngine;
@ -584,7 +587,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
UiUtils.setLightStatusBar(this, !(
ThemeUtils.isNightTheme(this)
|| RoutingController.get().isPlanning()
|| Framework.nativeGetChoosePositionMode() != Framework.ChoosePositionMode.NONE
|| ChoosePositionMode.get() != ChoosePositionMode.None
));
}
@ -645,9 +648,9 @@ public class MwmActivity extends BaseMwmFragmentActivity
mPointChooser.findViewById(R.id.done).setOnClickListener(
v ->
{
switch (Framework.nativeGetChoosePositionMode())
switch (ChoosePositionMode.get())
{
case Framework.ChoosePositionMode.API:
case Api:
final Intent apiResult = new Intent();
final double[] center = Framework.nativeGetScreenRectCenter();
apiResult.putExtra(Const.EXTRA_POINT_LAT, center[0]);
@ -656,7 +659,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
setResult(Activity.RESULT_OK, apiResult);
finish();
break;
case Framework.ChoosePositionMode.EDITOR:
case Editor:
if (Framework.nativeIsDownloadedMapAtScreenCenter())
startActivity(new Intent(MwmActivity.this, FeatureCategoryActivity.class));
else
@ -669,7 +672,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
.show();
}
break;
case Framework.ChoosePositionMode.NONE:
case None:
throw new IllegalStateException("Unexpected Framework.nativeGetChoosePositionMode()");
}
closePositionChooser();
@ -715,7 +718,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
public void showPositionChooserForAPI(@Nullable String appName)
{
showPositionChooser(Framework.ChoosePositionMode.API, false, false);
showPositionChooser(ChoosePositionMode.Api, false, false);
if (!TextUtils.isEmpty(appName))
{
setTitle(appName);
@ -725,26 +728,26 @@ public class MwmActivity extends BaseMwmFragmentActivity
public void showPositionChooserForEditor(boolean isBusiness, boolean applyPosition)
{
showPositionChooser(Framework.ChoosePositionMode.EDITOR, isBusiness, applyPosition);
showPositionChooser(ChoosePositionMode.Editor, isBusiness, applyPosition);
}
private void showPositionChooser(@Framework.ChoosePositionMode int mode, boolean isBusiness, boolean applyPosition)
private void showPositionChooser(ChoosePositionMode mode, boolean isBusiness, boolean applyPosition)
{
closeFloatingToolbarsAndPanels(false);
UiUtils.show(mPointChooser);
mMapButtonsViewModel.setButtonsHidden(true);
Framework.nativeSetChoosePositionMode(mode, isBusiness, applyPosition);
ChoosePositionMode.set(mode, isBusiness, applyPosition);
refreshLightStatusBar();
}
private void hidePositionChooser()
{
UiUtils.hide(mPointChooser);
@Framework.ChoosePositionMode int mode = Framework.nativeGetChoosePositionMode();
Framework.nativeSetChoosePositionMode(Framework.ChoosePositionMode.NONE, false, false);
ChoosePositionMode mode = ChoosePositionMode.get();
ChoosePositionMode.set(ChoosePositionMode.None, false, false);
mMapButtonsViewModel.setButtonsHidden(false);
refreshLightStatusBar();
if (mode == Framework.ChoosePositionMode.API)
if (mode == ChoosePositionMode.Api)
finish();
}
@ -1100,7 +1103,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
ThemeSwitcher.INSTANCE.restart(isMapRendererActive());
refreshSearchToolbar();
setFullscreen(isFullscreen());
if (Framework.nativeGetChoosePositionMode() != Framework.ChoosePositionMode.NONE)
if (ChoosePositionMode.get() != ChoosePositionMode.None)
{
UiUtils.show(mPointChooser);
mMapButtonsViewModel.setButtonsHidden(true);
@ -1314,7 +1317,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
{
// Buttons are hidden in position chooser mode but we are not in fullscreen
return Boolean.TRUE.equals(mMapButtonsViewModel.getButtonsHidden().getValue()) &&
Framework.nativeGetChoosePositionMode() == Framework.ChoosePositionMode.NONE;
ChoosePositionMode.get() == ChoosePositionMode.None;
}
@Override
@ -1578,7 +1581,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
}
@Override
public void updateBuildProgress(int progress, @Framework.RouterType int router)
public void updateBuildProgress(int progress, Router router)
{
if (mIsTabletLayout)
{
@ -2133,7 +2136,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
}
@Override
public void onSearchRoutePoint(@RoutePointInfo.RouteMarkType int pointType)
public void onSearchRoutePoint(@NonNull RouteMarkType pointType)
{
RoutingController.get().waitForPoiPick(pointType);
closeSearchToolbar(true, true);

View file

@ -20,10 +20,9 @@ import java.io.IOException;
import java.lang.ref.WeakReference;
import app.organicmaps.background.OsmUploadWork;
import app.organicmaps.bookmarks.data.BookmarkManager;
import app.organicmaps.display.DisplayManager;
import app.organicmaps.downloader.Android7RootCertificateWorkaround;
import app.organicmaps.downloader.DownloaderNotifier;
import app.organicmaps.display.DisplayManager;
import app.organicmaps.location.LocationHelper;
import app.organicmaps.location.LocationState;
import app.organicmaps.location.SensorHelper;
@ -31,18 +30,11 @@ import app.organicmaps.location.TrackRecorder;
import app.organicmaps.location.TrackRecordingService;
import app.organicmaps.maplayer.isolines.IsolinesManager;
import app.organicmaps.maplayer.subway.SubwayManager;
import app.organicmaps.maplayer.traffic.TrafficManager;
import app.organicmaps.routing.NavigationService;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.search.SearchEngine;
import app.organicmaps.settings.StoragePathManager;
import app.organicmaps.sound.TtsPlayer;
import app.organicmaps.sdk.OrganicMaps;
import app.organicmaps.util.Config;
import app.organicmaps.util.ConnectionState;
import app.organicmaps.util.SharedPropertiesUtils;
import app.organicmaps.util.StorageUtils;
import app.organicmaps.util.ThemeSwitcher;
import app.organicmaps.util.UiUtils;
import app.organicmaps.util.Utils;
import app.organicmaps.util.log.Logger;
import app.organicmaps.util.log.LogsManager;
@ -52,6 +44,10 @@ public class MwmApplication extends Application implements Application.ActivityL
@NonNull
private static final String TAG = MwmApplication.class.getSimpleName();
@SuppressWarnings("NotNullFieldNotInitialized")
@NonNull
private OrganicMaps mOrganicMaps;
@SuppressWarnings("NotNullFieldNotInitialized")
@NonNull
private SubwayManager mSubwayManager;
@ -72,9 +68,6 @@ public class MwmApplication extends Application implements Application.ActivityL
@NonNull
private DisplayManager mDisplayManager;
private volatile boolean mFrameworkInitialized;
private volatile boolean mPlatformInitialized;
@Nullable
private WeakReference<Activity> mTopActivity;
@ -115,6 +108,12 @@ public class MwmApplication extends Application implements Application.ActivityL
return mDisplayManager;
}
@NonNull
public OrganicMaps getOrganicMaps()
{
return mOrganicMaps;
}
@NonNull
public static MwmApplication from(@NonNull Context context)
{
@ -138,20 +137,12 @@ public class MwmApplication extends Application implements Application.ActivityL
sInstance = this;
mOrganicMaps = new OrganicMaps(getApplicationContext());
LogsManager.INSTANCE.initFileLogging(this);
Android7RootCertificateWorkaround.initializeIfNeeded(this);
// Set configuration directory as early as possible.
// Other methods may explicitly use Config, which requires settingsDir to be set.
final String settingsPath = StorageUtils.getSettingsPath(this);
if (!StorageUtils.createDirectory(settingsPath))
throw new AssertionError("Can't create settingsDir " + settingsPath);
Logger.d(TAG, "Settings path = " + settingsPath);
nativeSetSettingsDir(settingsPath);
Config.init(this);
ConnectionState.INSTANCE.initialize(this);
DownloaderNotifier.createNotificationChannel(this);
@ -166,117 +157,16 @@ public class MwmApplication extends Application implements Application.ActivityL
mDisplayManager = new DisplayManager();
}
/**
* Initialize native core of application: platform and framework.
*
* @throws IOException - if failed to create directories. Caller must handle
* the exception and do nothing with native code if initialization is failed.
*/
public boolean init(@NonNull Runnable onComplete) throws IOException
public boolean initOrganicMaps(@NonNull Runnable onComplete) throws IOException
{
initNativePlatform();
return initNativeFramework(onComplete);
return mOrganicMaps.init(() -> {
ProcessLifecycleOwner.get().getLifecycle().addObserver(mProcessLifecycleObserver);
onComplete.run();
});
}
private void initNativePlatform() throws IOException
private final LifecycleObserver mProcessLifecycleObserver = new DefaultLifecycleObserver()
{
if (mPlatformInitialized)
return;
final String apkPath = StorageUtils.getApkPath(this);
Logger.d(TAG, "Apk path = " + apkPath);
// Note: StoragePathManager uses Config, which requires SettingsDir to be set.
final String writablePath = StoragePathManager.findMapsStorage(this);
Logger.d(TAG, "Writable path = " + writablePath);
final String privatePath = StorageUtils.getPrivatePath(this);
Logger.d(TAG, "Private path = " + privatePath);
final String tempPath = StorageUtils.getTempPath(this);
Logger.d(TAG, "Temp path = " + tempPath);
// If platform directories are not created it means that native part of app will not be able
// to work at all. So, we just ignore native part initialization in this case, e.g. when the
// external storage is damaged or not available (read-only).
createPlatformDirectories(writablePath, privatePath, tempPath);
nativeInitPlatform(getApplicationContext(),
apkPath,
writablePath,
privatePath,
tempPath,
app.organicmaps.BuildConfig.FLAVOR,
app.organicmaps.BuildConfig.BUILD_TYPE, UiUtils.isTablet(this));
Config.setStoragePath(writablePath);
Config.setStatisticsEnabled(SharedPropertiesUtils.isStatisticsEnabled(this));
mPlatformInitialized = true;
Logger.i(TAG, "Platform initialized");
}
private void createPlatformDirectories(@NonNull String writablePath,
@NonNull String privatePath,
@NonNull String tempPath) throws IOException
{
SharedPropertiesUtils.emulateBadExternalStorage(this);
StorageUtils.requireDirectory(writablePath);
StorageUtils.requireDirectory(privatePath);
StorageUtils.requireDirectory(tempPath);
}
private boolean initNativeFramework(@NonNull Runnable onComplete)
{
if (mFrameworkInitialized)
return false;
nativeInitFramework(onComplete);
initNativeStrings();
ThemeSwitcher.INSTANCE.initialize(this);
SearchEngine.INSTANCE.initialize();
BookmarkManager.loadBookmarks();
TtsPlayer.INSTANCE.initialize(this);
ThemeSwitcher.INSTANCE.restart(false);
RoutingController.get().initialize(this);
TrafficManager.INSTANCE.initialize();
SubwayManager.from(this).initialize();
IsolinesManager.from(this).initialize();
ProcessLifecycleOwner.get().getLifecycle().addObserver(mProcessLifecycleObserver);
Logger.i(TAG, "Framework initialized");
mFrameworkInitialized = true;
return true;
}
private void initNativeStrings()
{
nativeAddLocalization("core_entrance", getString(R.string.core_entrance));
nativeAddLocalization("core_exit", getString(R.string.core_exit));
nativeAddLocalization("core_my_places", getString(R.string.core_my_places));
nativeAddLocalization("core_my_position", getString(R.string.core_my_position));
nativeAddLocalization("core_placepage_unknown_place", getString(R.string.core_placepage_unknown_place));
nativeAddLocalization("postal_code", getString(R.string.postal_code));
nativeAddLocalization("wifi", getString(R.string.category_wifi));
}
public boolean arePlatformAndCoreInitialized()
{
return mFrameworkInitialized && mPlatformInitialized;
}
static
{
System.loadLibrary("organicmaps");
}
private static native void nativeSetSettingsDir(String settingsPath);
private static native void nativeInitPlatform(Context context, String apkPath, String writablePath,
String privatePath, String tmpPath, String flavorName,
String buildType, boolean isTablet);
private static native void nativeInitFramework(@NonNull Runnable onComplete);
private static native void nativeAddLocalization(String name, String value);
private static native void nativeOnTransit(boolean foreground);
private final LifecycleObserver mProcessLifecycleObserver = new DefaultLifecycleObserver() {
@Override
public void onStart(@NonNull LifecycleOwner owner)
{
@ -334,8 +224,6 @@ public class MwmApplication extends Application implements Application.ActivityL
{
Logger.d(TAG);
nativeOnTransit(true);
mLocationHelper.resumeLocationInForeground();
}
@ -343,8 +231,6 @@ public class MwmApplication extends Application implements Application.ActivityL
{
Logger.d(TAG);
nativeOnTransit(false);
OsmUploadWork.startActionUploadOsmChanges(this);
if (!mDisplayManager.isDeviceDisplayUsed())

View file

@ -2,7 +2,6 @@ package app.organicmaps;
import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static app.organicmaps.api.Const.EXTRA_PICK_POINT;
import android.content.ComponentName;
import android.content.Context;
@ -146,7 +145,7 @@ public class SplashActivity extends AppCompatActivity
boolean asyncContinue = false;
try
{
asyncContinue = app.init(this::processNavigation);
asyncContinue = app.initOrganicMaps(this::processNavigation);
} catch (IOException error)
{
showFatalErrorDialog(R.string.dialog_error_storage_title, R.string.dialog_error_storage_message, error);

View file

@ -2,7 +2,7 @@ package app.organicmaps.api;
import androidx.annotation.Keep;
import app.organicmaps.Framework;
import app.organicmaps.sdk.Router;
/**
* Represents Framework::ParsedRoutingData from core.
@ -13,11 +13,10 @@ import app.organicmaps.Framework;
public class ParsedRoutingData
{
public final RoutePoint[] mPoints;
@Framework.RouterType
public final int mRouterType;
public final Router mRouterType;
public ParsedRoutingData(RoutePoint[] points, int routerType) {
this.mPoints = points;
this.mRouterType = routerType;
this.mRouterType = Router.valueOf(routerType);
}
}

View file

@ -47,7 +47,7 @@ public class OsmUploadWork extends Worker
public Result doWork()
{
final MwmApplication app = MwmApplication.from(mContext);
if (!app.arePlatformAndCoreInitialized())
if (!app.getOrganicMaps().arePlatformAndCoreInitialized())
{
Logger.w(TAG, "Application is not initialized, ignoring " + mWorkerParameters);
return Result.failure();

View file

@ -69,7 +69,7 @@ public abstract class BaseMwmFragmentActivity extends AppCompatActivity
setTheme(getThemeResourceId(mThemeName));
EdgeToEdge.enable(this, SystemBarStyle.dark(Color.TRANSPARENT));
RtlUtils.manageRtl(this);
if (!MwmApplication.from(this).arePlatformAndCoreInitialized())
if (!MwmApplication.from(this).getOrganicMaps().arePlatformAndCoreInitialized())
{
final Intent intent = Objects.requireNonNull(getIntent());
intent.setComponent(new ComponentName(this, SplashActivity.class));

View file

@ -10,7 +10,7 @@ import androidx.annotation.Nullable;
import androidx.core.os.ParcelCompat;
import app.organicmaps.Framework;
import app.organicmaps.routing.RoutePointInfo;
import app.organicmaps.sdk.routing.RoutePointInfo;
import app.organicmaps.sdk.search.Popularity;
import app.organicmaps.util.Constants;

View file

@ -11,7 +11,7 @@ import androidx.annotation.Nullable;
import androidx.core.os.ParcelCompat;
import app.organicmaps.Framework;
import app.organicmaps.routing.RoutePointInfo;
import app.organicmaps.sdk.routing.RoutePointInfo;
import app.organicmaps.sdk.search.Popularity;
import app.organicmaps.util.Utils;
import app.organicmaps.widget.placepage.PlacePageData;

View file

@ -35,6 +35,7 @@ import app.organicmaps.display.DisplayManager;
import app.organicmaps.display.DisplayType;
import app.organicmaps.location.LocationState;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.PlacePageActivationListener;
import app.organicmaps.util.Config;
import app.organicmaps.util.LocationUtils;
import app.organicmaps.util.log.Logger;
@ -45,7 +46,7 @@ import java.util.ArrayList;
import java.util.List;
public final class CarAppSession extends Session implements DefaultLifecycleObserver,
LocationState.ModeChangeListener, DisplayChangedListener, Framework.PlacePageActivationListener
LocationState.ModeChangeListener, DisplayChangedListener, PlacePageActivationListener
{
private static final String TAG = CarAppSession.class.getSimpleName();
@ -163,7 +164,7 @@ public final class CarAppSession extends Session implements DefaultLifecycleObse
mInitFailed = false;
try
{
MwmApplication.from(getCarContext()).init(() -> {
MwmApplication.from(getCarContext()).initOrganicMaps(() -> {
Config.setFirstStartDialogSeen(getCarContext());
if (DownloaderHelpers.isWorldMapsDownloadNeeded())
mScreenManager.push(new DownloadMapsScreenBuilder(getCarContext()).setDownloaderType(DownloadMapsScreenBuilder.DownloaderType.FirstLaunch).build());

View file

@ -30,10 +30,10 @@ import app.organicmaps.car.util.ThemeUtils;
import app.organicmaps.car.util.UiHelpers;
import app.organicmaps.location.LocationHelper;
import app.organicmaps.location.LocationListener;
import app.organicmaps.routing.JunctionInfo;
import app.organicmaps.sdk.routing.JunctionInfo;
import app.organicmaps.routing.NavigationService;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.routing.RoutingInfo;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sound.TtsPlayer;
import app.organicmaps.util.LocationUtils;
import app.organicmaps.util.log.Logger;

View file

@ -41,14 +41,15 @@ import app.organicmaps.car.util.UiHelpers;
import app.organicmaps.location.LocationHelper;
import app.organicmaps.routing.ResultCodesHelper;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.routing.RoutingInfo;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.Router;
import app.organicmaps.util.Config;
import java.util.Objects;
public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback.Callback, RoutingController.Container
{
private static final int ROUTER_TYPE = Framework.ROUTER_TYPE_VEHICLE;
private static final Router ROUTER = Router.Vehicle;
@Nullable
private MapObject mMapObject;
@ -83,7 +84,7 @@ public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback.
public void onCreate(@NonNull LifecycleOwner owner)
{
mRoutingController.restore();
if (mRoutingController.isNavigating() && mRoutingController.getLastRouterType() == ROUTER_TYPE)
if (mRoutingController.isNavigating() && mRoutingController.getLastRouterType() == ROUTER)
{
showNavigation(true);
return;
@ -95,11 +96,11 @@ public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback.
else
{
final boolean hasIncorrectEndPoint = mRoutingController.isPlanning() && (!MapObject.same(mMapObject, mRoutingController.getEndPoint()));
final boolean hasIncorrectRouterType = mRoutingController.getLastRouterType() != ROUTER_TYPE;
final boolean hasIncorrectRouterType = mRoutingController.getLastRouterType() != ROUTER;
final boolean isNotPlanningMode = !mRoutingController.isPlanning();
if (hasIncorrectRouterType)
{
mRoutingController.setRouterType(ROUTER_TYPE);
mRoutingController.setRouterType(ROUTER);
mRoutingController.rebuildLastRoute();
}
else if (hasIncorrectEndPoint || isNotPlanningMode)

View file

@ -18,7 +18,7 @@ import app.organicmaps.car.SurfaceRenderer;
import app.organicmaps.car.screens.base.BaseMapScreen;
import app.organicmaps.car.util.Toggle;
import app.organicmaps.car.util.UiHelpers;
import app.organicmaps.routing.RoutingOptions;
import app.organicmaps.sdk.routing.RoutingOptions;
import app.organicmaps.settings.RoadType;
import java.util.HashMap;

View file

@ -8,8 +8,8 @@ import androidx.car.app.navigation.model.LaneDirection;
import androidx.car.app.navigation.model.Maneuver;
import androidx.core.graphics.drawable.IconCompat;
import app.organicmaps.routing.RoutingInfo;
import app.organicmaps.routing.SingleLaneInfo;
import app.organicmaps.sdk.routing.CarDirection;
import app.organicmaps.sdk.routing.LaneWay;
public final class RoutingHelpers
{
@ -30,7 +30,7 @@ public final class RoutingHelpers
}
@NonNull
public static LaneDirection createLaneDirection(@NonNull SingleLaneInfo.LaneWay laneWay, boolean isRecommended)
public static LaneDirection createLaneDirection(@NonNull LaneWay laneWay, boolean isRecommended)
{
int shape = LaneDirection.SHAPE_UNKNOWN;
switch (laneWay)
@ -67,7 +67,7 @@ public final class RoutingHelpers
}
@NonNull
public static Maneuver createManeuver(@NonNull final CarContext context, @NonNull RoutingInfo.CarDirection carDirection, int roundaboutExitNum)
public static Maneuver createManeuver(@NonNull final CarContext context, @NonNull CarDirection carDirection, int roundaboutExitNum)
{
int maneuverType = switch (carDirection)
{

View file

@ -15,8 +15,9 @@ import androidx.car.app.navigation.model.Trip;
import androidx.core.graphics.drawable.IconCompat;
import app.organicmaps.bookmarks.data.MapObject;
import app.organicmaps.routing.RoutingInfo;
import app.organicmaps.routing.SingleLaneInfo;
import app.organicmaps.sdk.routing.LaneWay;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.routing.SingleLaneInfo;
import app.organicmaps.util.Graphics;
import app.organicmaps.widget.LanesDrawable;
@ -71,7 +72,7 @@ public final class RoutingUtils
for (final SingleLaneInfo laneInfo : info.lanes)
{
final Lane.Builder laneBuilder = new Lane.Builder();
for (final SingleLaneInfo.LaneWay laneWay : laneInfo.mLane)
for (final LaneWay laneWay : laneInfo.mLane)
laneBuilder.addDirection(RoutingHelpers.createLaneDirection(laneWay, laneInfo.mIsActive));
builder.addLane(laneBuilder.build());
}

View file

@ -12,6 +12,7 @@ import androidx.car.app.CarContext;
import app.organicmaps.Framework;
import app.organicmaps.R;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.MapStyle;
public final class ThemeUtils
{
@ -60,15 +61,14 @@ public final class ThemeUtils
{
final ThemeMode newThemeMode = oldThemeMode == ThemeMode.AUTO ? (context.isDarkMode() ? ThemeMode.NIGHT : ThemeMode.LIGHT) : oldThemeMode;
@Framework.MapStyle
int newMapStyle;
MapStyle newMapStyle;
if (newThemeMode == ThemeMode.NIGHT)
newMapStyle = RoutingController.get().isVehicleNavigation() ? Framework.MAP_STYLE_VEHICLE_DARK : Framework.MAP_STYLE_DARK;
newMapStyle = RoutingController.get().isVehicleNavigation() ? MapStyle.VehicleDark : MapStyle.Dark;
else
newMapStyle = RoutingController.get().isVehicleNavigation() ? Framework.MAP_STYLE_VEHICLE_CLEAR : Framework.MAP_STYLE_CLEAR;
newMapStyle = RoutingController.get().isVehicleNavigation() ? MapStyle.VehicleClear : MapStyle.Clear;
if (Framework.nativeGetMapStyle() != newMapStyle)
Framework.nativeSetMapStyle(newMapStyle);
if (MapStyle.get() != newMapStyle)
MapStyle.set(newMapStyle);
}
public static boolean isNightMode(@NonNull CarContext context)

View file

@ -25,7 +25,7 @@ import app.organicmaps.Map;
import app.organicmaps.MwmApplication;
import app.organicmaps.bookmarks.data.FeatureId;
import app.organicmaps.bookmarks.data.MapObject;
import app.organicmaps.routing.JunctionInfo;
import app.organicmaps.sdk.routing.JunctionInfo;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.util.Config;
import app.organicmaps.util.LocationUtils;

View file

@ -5,7 +5,7 @@ import android.location.Location;
import androidx.annotation.NonNull;
import app.organicmaps.routing.JunctionInfo;
import app.organicmaps.sdk.routing.JunctionInfo;
import app.organicmaps.util.LocationUtils;
import app.organicmaps.util.concurrency.UiThread;
import app.organicmaps.util.log.Logger;

View file

@ -135,7 +135,7 @@ public class TrackRecordingService extends Service implements LocationListener
@Override
public int onStartCommand(@NonNull Intent intent, int flags, int startId)
{
if (!MwmApplication.from(this).arePlatformAndCoreInitialized())
if (!MwmApplication.from(this).getOrganicMaps().arePlatformAndCoreInitialized())
{
Logger.w(TAG, "Application is not initialized");
stopSelf();

View file

@ -17,6 +17,9 @@ import androidx.recyclerview.widget.RecyclerView;
import app.organicmaps.R;
import app.organicmaps.bookmarks.data.MapObject;
import app.organicmaps.sdk.routing.RouteMarkData;
import app.organicmaps.sdk.routing.RouteMarkType;
import app.organicmaps.sdk.routing.RoutePointInfo;
import app.organicmaps.util.StringUtils;
import app.organicmaps.util.UiUtils;
@ -65,21 +68,21 @@ public class ManageRouteAdapter extends RecyclerView.Adapter<ManageRouteAdapter.
switch (mRoutePoints.get(position).mPointType)
{
case RoutePointInfo.ROUTE_MARK_START: // Starting point.
case Start: // Starting point.
if (mRoutePoints.get(position).mIsMyPosition)
iconId = R.drawable.ic_location_arrow_blue;
else
iconId = R.drawable.route_point_start;
break;
case RoutePointInfo.ROUTE_MARK_INTERMEDIATE: // Intermediate stop.
case Intermediate: // Intermediate stop.
TypedArray iconArray = mContext.getResources().obtainTypedArray(R.array.route_stop_icons);
iconId = iconArray.getResourceId(mRoutePoints.get(position).mIntermediateIndex,
R.drawable.route_point_20);
iconArray.recycle();
break;
case RoutePointInfo.ROUTE_MARK_FINISH: // Destination point.
case Finish: // Destination point.
iconId = R.drawable.route_point_finish;
break;
@ -99,7 +102,7 @@ public class ManageRouteAdapter extends RecyclerView.Adapter<ManageRouteAdapter.
// My position point.
title = mContext.getString(R.string.core_my_position);
if (mRoutePoints.get(position).mPointType != RoutePointInfo.ROUTE_MARK_START)
if (mRoutePoints.get(position).mPointType != RouteMarkType.Start)
subtitle = mRoutePoints.get(position).mTitle;
else
{
@ -180,7 +183,7 @@ public class ManageRouteAdapter extends RecyclerView.Adapter<ManageRouteAdapter.
myLocation.getLon());
// Replace route point in first position with 'My Position".
mRoutePoints.set(0, new RouteMarkData(latLonString, "", RoutePointInfo.ROUTE_MARK_START,
mRoutePoints.set(0, new RouteMarkData(latLonString, "", RouteMarkType.Start,
0, true, true, false, myLocation.getLat(),
myLocation.getLon()));
@ -217,15 +220,15 @@ public class ManageRouteAdapter extends RecyclerView.Adapter<ManageRouteAdapter.
assert(mRoutePoints.size() >= 2);
// Set starting point.
mRoutePoints.get(0).mPointType = RoutePointInfo.ROUTE_MARK_START;
mRoutePoints.get(0).mPointType = RouteMarkType.Start;
// Set finish point.
mRoutePoints.get(mRoutePoints.size() - 1).mPointType = RoutePointInfo.ROUTE_MARK_FINISH;
mRoutePoints.get(mRoutePoints.size() - 1).mPointType = RouteMarkType.Finish;
// Set intermediate point(s).
for (int pos = 1; pos < mRoutePoints.size() - 1; pos++)
{
mRoutePoints.get(pos).mPointType = RoutePointInfo.ROUTE_MARK_INTERMEDIATE;
mRoutePoints.get(pos).mPointType = RouteMarkType.Intermediate;
mRoutePoints.get(pos).mIntermediateIndex = pos - 1;
}
}

View file

@ -20,6 +20,7 @@ import app.organicmaps.Framework;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
import app.organicmaps.bookmarks.data.MapObject;
import app.organicmaps.sdk.routing.RouteMarkData;
import app.organicmaps.util.UiUtils;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.bottomsheet.BottomSheetDialog;

View file

@ -18,6 +18,9 @@ import app.organicmaps.R;
import app.organicmaps.location.LocationHelper;
import app.organicmaps.maplayer.MapButtonsViewModel;
import app.organicmaps.maplayer.traffic.TrafficManager;
import app.organicmaps.sdk.Router;
import app.organicmaps.sdk.routing.CarDirection;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.util.StringUtils;
import app.organicmaps.util.UiUtils;
import app.organicmaps.util.Utils;
@ -112,7 +115,7 @@ public class NavigationController implements TrafficManager.TrafficCallback,
mNextTurnDistance.setText(Utils.formatDistance(mFrame.getContext(), info.distToTurn));
info.carDirection.setTurnDrawable(mNextTurnImage);
if (RoutingInfo.CarDirection.isRoundAbout(info.carDirection))
if (CarDirection.isRoundAbout(info.carDirection))
UiUtils.setTextAndShow(mCircleExit, String.valueOf(info.exitNum));
else
UiUtils.hide(mCircleExit);
@ -146,7 +149,7 @@ public class NavigationController implements TrafficManager.TrafficCallback,
if (info == null)
return;
if (Framework.nativeGetRouter() == Framework.ROUTER_TYPE_PEDESTRIAN)
if (Router.get() == Router.Pedestrian)
updatePedestrian(info);
else
updateVehicle(info);

View file

@ -33,6 +33,7 @@ import app.organicmaps.Framework;
import app.organicmaps.MwmActivity;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sound.MediaPlayerWrapper;
import app.organicmaps.location.LocationHelper;
import app.organicmaps.location.LocationListener;
@ -201,7 +202,7 @@ public class NavigationService extends Service implements LocationListener
return START_NOT_STICKY;
}
if (!MwmApplication.from(this).arePlatformAndCoreInitialized())
if (!MwmApplication.from(this).getOrganicMaps().arePlatformAndCoreInitialized())
{
// The system restarts the service if the app's process has crashed or been stopped. It would be nice to
// automatically restore the last route and resume navigation. Unfortunately, the current implementation of

View file

@ -32,6 +32,12 @@ import app.organicmaps.Framework;
import app.organicmaps.R;
import app.organicmaps.bookmarks.data.DistanceAndAzimut;
import app.organicmaps.location.LocationHelper;
import app.organicmaps.sdk.routing.RouteMarkData;
import app.organicmaps.sdk.routing.RouteMarkType;
import app.organicmaps.sdk.routing.RoutePointInfo;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.routing.TransitRouteInfo;
import app.organicmaps.sdk.routing.TransitStepInfo;
import app.organicmaps.util.Distance;
import app.organicmaps.util.Graphics;
import app.organicmaps.util.ThemeUtils;
@ -251,7 +257,7 @@ final class RoutingBottomMenuController implements View.OnClickListener
UiUtils.hide(mError, mTransitFrame);
UiUtils.show(mActionFrame);
mActionMessage.setText(R.string.routing_add_start_point);
mActionMessage.setTag(RoutePointInfo.ROUTE_MARK_START);
mActionMessage.setTag(RouteMarkType.Start);
if (LocationHelper.from(mContext).getMyPosition() != null)
{
UiUtils.show(mActionButton);
@ -271,7 +277,7 @@ final class RoutingBottomMenuController implements View.OnClickListener
UiUtils.hide(mError, mTransitFrame);
UiUtils.show(mActionFrame);
mActionMessage.setText(R.string.routing_add_finish_point);
mActionMessage.setTag(RoutePointInfo.ROUTE_MARK_FINISH);
mActionMessage.setTag(RouteMarkType.Finish);
UiUtils.hide(mActionButton);
}
@ -483,8 +489,7 @@ final class RoutingBottomMenuController implements View.OnClickListener
mListener.onUseMyPositionAsStart();
else if (id == R.id.btn__search_point && mListener != null)
{
@RoutePointInfo.RouteMarkType
int pointType = (Integer) mActionMessage.getTag();
final RouteMarkType pointType = (RouteMarkType) mActionMessage.getTag();
mListener.onSearchRoutePoint(pointType);
}
else if (id == R.id.btn__manage_route && mListener != null)

View file

@ -1,9 +1,13 @@
package app.organicmaps.routing;
import androidx.annotation.NonNull;
import app.organicmaps.sdk.routing.RouteMarkType;
public interface RoutingBottomMenuListener
{
void onUseMyPositionAsStart();
void onSearchRoutePoint(@RoutePointInfo.RouteMarkType int type);
void onSearchRoutePoint(@NonNull RouteMarkType type);
void onRoutingStart();
void onManageRouteOpen();
}

View file

@ -16,6 +16,17 @@ import app.organicmaps.R;
import app.organicmaps.bookmarks.data.FeatureId;
import app.organicmaps.bookmarks.data.MapObject;
import app.organicmaps.location.LocationHelper;
import app.organicmaps.sdk.Router;
import app.organicmaps.sdk.routing.RouteMarkData;
import app.organicmaps.sdk.routing.RouteMarkType;
import app.organicmaps.sdk.routing.RoutePointInfo;
import app.organicmaps.sdk.routing.RouteRecommendationType;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.routing.RoutingListener;
import app.organicmaps.sdk.routing.RoutingLoadPointsListener;
import app.organicmaps.sdk.routing.RoutingOptions;
import app.organicmaps.sdk.routing.RoutingProgressListener;
import app.organicmaps.sdk.routing.TransitRouteInfo;
import app.organicmaps.widget.placepage.CoordinatesFormat;
import app.organicmaps.util.StringUtils;
import app.organicmaps.util.Utils;
@ -67,11 +78,10 @@ public class RoutingController
/**
* @param progress progress to be displayed.
* */
default void updateBuildProgress(@IntRange(from = 0, to = 100) int progress, @Framework.RouterType int router) {}
default void updateBuildProgress(@IntRange(from = 0, to = 100) int progress, Router router) {}
default void onStartRouteBuilding() {}
}
private static final int NO_WAITING_POI_PICK = -1;
private static final RoutingController sInstance = new RoutingController();
@Nullable
@ -79,11 +89,10 @@ public class RoutingController
private BuildState mBuildState = BuildState.NONE;
private State mState = State.NONE;
//@RoutePointInfo.RouteMarkType
private int mWaitingPoiPickType = NO_WAITING_POI_PICK;
@Nullable
private RouteMarkType mWaitingPoiPickType = null;
private int mLastBuildProgress;
@Framework.RouterType
private int mLastRouterType;
private Router mLastRouterType;
private boolean mHasContainerSavedState;
private boolean mContainsCachedResult;
@ -98,7 +107,7 @@ public class RoutingController
private int mRemovingIntermediatePointsTransactionId;
@SuppressWarnings("FieldCanBeLocal")
private final Framework.RoutingListener mRoutingListener = new Framework.RoutingListener()
private final RoutingListener mRoutingListener = new RoutingListener()
{
@MainThread
@Override
@ -124,10 +133,11 @@ public class RoutingController
processRoutingEvent();
}
};
private void onBuiltRoute()
{
mCachedRoutingInfo = Framework.nativeGetRouteFollowingInfo();
if (mLastRouterType == Framework.ROUTER_TYPE_TRANSIT)
if (mLastRouterType == Router.Transit)
mCachedTransitRouteInfo = Framework.nativeGetTransitRouteInfo();
setBuildState(BuildState.BUILT);
mLastBuildProgress = 100;
@ -135,23 +145,15 @@ public class RoutingController
mContainer.onBuiltRoute();
}
private final Framework.RoutingProgressListener mRoutingProgressListener = new Framework.RoutingProgressListener()
{
@MainThread
@Override
public void onRouteBuildingProgress(float progress)
{
mLastBuildProgress = (int) progress;
updateProgress();
}
private final RoutingProgressListener mRoutingProgressListener = progress -> {
mLastBuildProgress = (int) progress;
updateProgress();
};
@SuppressWarnings("FieldCanBeLocal")
private final Framework.RoutingLoadPointsListener mRoutingLoadPointsListener =
success -> {
if (success)
prepare(getStartPoint(), getEndPoint());
};
private final RoutingLoadPointsListener mRoutingLoadPointsListener = success -> {
if (success)
prepare(getStartPoint(), getEndPoint());
};
public static RoutingController get()
{
@ -254,14 +256,14 @@ public class RoutingController
public void initialize(@NonNull Context context)
{
mLastRouterType = Framework.nativeGetLastUsedRouter();
mLastRouterType = Router.getLastUsed();
mInvalidRoutePointsTransactionId = Framework.nativeInvalidRoutePointsTransactionId();
mRemovingIntermediatePointsTransactionId = mInvalidRoutePointsTransactionId;
Framework.nativeSetRoutingListener(mRoutingListener);
Framework.nativeSetRouteProgressListener(mRoutingProgressListener);
Framework.nativeSetRoutingRecommendationListener(recommendation -> UiThread.run(() -> {
if (recommendation == Framework.ROUTE_REBUILD_AFTER_POINTS_LOADING)
if (recommendation == RouteRecommendationType.RebuildAfterPointsLoading)
setStartPoint(LocationHelper.from(context).getMyPosition());
}));
Framework.nativeSetRoutingLoadPointsListener(mRoutingLoadPointsListener);
@ -346,18 +348,18 @@ public class RoutingController
private void initLastRouteType(@Nullable MapObject startPoint, @Nullable MapObject endPoint)
{
if (startPoint != null && endPoint != null)
mLastRouterType = Framework.nativeGetBestRouter(startPoint.getLat(), startPoint.getLon(),
endPoint.getLat(), endPoint.getLon());
mLastRouterType = Router.getBest(startPoint.getLat(), startPoint.getLon(),
endPoint.getLat(), endPoint.getLon());
}
public void prepare(final @Nullable MapObject startPoint, final @Nullable MapObject endPoint,
@Framework.RouterType int routerType)
Router routerType)
{
cancel();
setState(State.PREPARE);
mLastRouterType = routerType;
Framework.nativeSetRouter(mLastRouterType);
Router.set(mLastRouterType);
if (startPoint != null || endPoint != null)
setPointsInternal(startPoint, endPoint);
@ -383,7 +385,7 @@ public class RoutingController
public void addStop(@NonNull MapObject mapObject)
{
addRoutePoint(RoutePointInfo.ROUTE_MARK_INTERMEDIATE, mapObject);
addRoutePoint(RouteMarkType.Intermediate, mapObject);
build();
if (mContainer != null)
mContainer.onAddedStop();
@ -462,8 +464,7 @@ public class RoutingController
{
Logger.d(TAG, "cancelInternal");
//noinspection WrongConstant
mWaitingPoiPickType = NO_WAITING_POI_PICK;
mWaitingPoiPickType = null;
setBuildState(BuildState.NONE);
setState(State.NONE);
@ -554,17 +555,17 @@ public class RoutingController
public boolean isTransitType()
{
return mLastRouterType == Framework.ROUTER_TYPE_TRANSIT;
return mLastRouterType == Router.Transit;
}
public boolean isVehicleRouterType()
{
return mLastRouterType == Framework.ROUTER_TYPE_VEHICLE;
return mLastRouterType == Router.Vehicle;
}
boolean isRulerRouterType()
{
return mLastRouterType == Framework.ROUTER_TYPE_RULER;
return mLastRouterType == Router.Ruler;
}
public boolean isNavigating()
@ -592,13 +593,13 @@ public class RoutingController
return mBuildState == BuildState.BUILT;
}
public void waitForPoiPick(@RoutePointInfo.RouteMarkType int pointType){
public void waitForPoiPick(@NonNull RouteMarkType pointType){
mWaitingPoiPickType = pointType;
}
public boolean isWaitingPoiPick()
{
return mWaitingPoiPickType != NO_WAITING_POI_PICK;
return mWaitingPoiPickType != null;
}
public BuildState getBuildState()
@ -609,17 +610,17 @@ public class RoutingController
@Nullable
public MapObject getStartPoint()
{
return getStartOrEndPointByType(RoutePointInfo.ROUTE_MARK_START);
return getStartOrEndPointByType(RouteMarkType.Start);
}
@Nullable
public MapObject getEndPoint()
{
return getStartOrEndPointByType(RoutePointInfo.ROUTE_MARK_FINISH);
return getStartOrEndPointByType(RouteMarkType.Finish);
}
@Nullable
private MapObject getStartOrEndPointByType(@RoutePointInfo.RouteMarkType int type)
private MapObject getStartOrEndPointByType(@NonNull RouteMarkType type)
{
RouteMarkData[] points = Framework.nativeGetRoutePoints();
int size = points.length;
@ -633,9 +634,9 @@ public class RoutingController
return point.mPointType == type ? toMapObject(point) : null;
}
if (type == RoutePointInfo.ROUTE_MARK_START)
if (type == RouteMarkType.Start)
return toMapObject(points[0]);
if (type == RoutePointInfo.ROUTE_MARK_FINISH)
if (type == RouteMarkType.Finish)
return toMapObject(points[size - 1]);
return null;
@ -663,10 +664,10 @@ public class RoutingController
applyRemovingIntermediatePointsTransaction();
if (hasStart)
addRoutePoint(RoutePointInfo.ROUTE_MARK_START , startPoint);
addRoutePoint(RouteMarkType.Start, startPoint);
if (hasEnd)
addRoutePoint(RoutePointInfo.ROUTE_MARK_FINISH , endPoint);
addRoutePoint(RouteMarkType.Finish, endPoint);
if (hasOnePointAtLeast && mContainer != null)
mContainer.updateMenu();
@ -701,7 +702,7 @@ public class RoutingController
if (point != null)
{
applyRemovingIntermediatePointsTransaction();
addRoutePoint(RoutePointInfo.ROUTE_MARK_START, point);
addRoutePoint(RouteMarkType.Start, point);
startPoint = getStartPoint();
}
@ -750,7 +751,7 @@ public class RoutingController
{
applyRemovingIntermediatePointsTransaction();
addRoutePoint(RoutePointInfo.ROUTE_MARK_FINISH, point);
addRoutePoint(RouteMarkType.Finish, point);
endPoint = getEndPoint();
}
@ -771,7 +772,7 @@ public class RoutingController
return true;
}
private static void addRoutePoint(@RoutePointInfo.RouteMarkType int type, @NonNull MapObject point)
private static void addRoutePoint(@NonNull RouteMarkType type, @NonNull MapObject point)
{
Pair<String, String> description = getDescriptionForPoint(point);
Framework.nativeAddRoutePoint(description.first /* title */, description.second /* subtitle */,
@ -823,7 +824,7 @@ public class RoutingController
mContainer.updateMenu();
}
public void setRouterType(@Framework.RouterType int router)
public void setRouterType(Router router)
{
Logger.d(TAG, "setRouterType: " + mLastRouterType + " -> " + router);
@ -833,7 +834,7 @@ public class RoutingController
return;
mLastRouterType = router;
Framework.nativeSetRouter(router);
Router.set(router);
cancelRemovingIntermediatePointsTransaction();
@ -841,8 +842,7 @@ public class RoutingController
build();
}
@Framework.RouterType
public int getLastRouterType()
public Router getLastRouterType()
{
return mLastRouterType;
}
@ -870,15 +870,12 @@ public class RoutingController
if (!isWaitingPoiPick())
return;
if (mWaitingPoiPickType != RoutePointInfo.ROUTE_MARK_FINISH
&& mWaitingPoiPickType != RoutePointInfo.ROUTE_MARK_START)
{
if (mWaitingPoiPickType != RouteMarkType.Start && mWaitingPoiPickType != RouteMarkType.Finish)
throw new AssertionError("Only start and finish points can be added through search!");
}
if (point != null)
{
if (mWaitingPoiPickType == RoutePointInfo.ROUTE_MARK_FINISH)
if (mWaitingPoiPickType == RouteMarkType.Finish)
setEndPoint(point);
else
setStartPoint(point);
@ -890,8 +887,7 @@ public class RoutingController
showRoutePlan();
}
//noinspection WrongConstant
mWaitingPoiPickType = NO_WAITING_POI_PICK;
mWaitingPoiPickType = null;
}
public static CharSequence formatRoutingTime(Context context, int seconds, @DimenRes int unitsSize)
{

View file

@ -1,175 +0,0 @@
package app.organicmaps.routing;
import android.widget.ImageView;
import androidx.annotation.DrawableRes;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import app.organicmaps.R;
import app.organicmaps.util.Distance;
// Called from JNI.
@Keep
@SuppressWarnings("unused")
public class RoutingInfo
{
// Target (end point of route).
public final Distance distToTarget;
// Next turn.
public final Distance distToTurn;
public final int totalTimeInSeconds;
// Current street name.
public final String currentStreet;
// The next street name.
public final String nextStreet;
// The next next street name.
public final String nextNextStreet;
public final double completionPercent;
// For vehicle routing.
public final CarDirection carDirection;
public final CarDirection nextCarDirection;
public final int exitNum;
public final SingleLaneInfo[] lanes;
// For pedestrian routing.
public final PedestrianTurnDirection pedestrianTurnDirection;
// Current speed limit in meters per second.
// If no info about speed limit then speedLimitMps < 0.
public final double speedLimitMps;
private final boolean speedCamLimitExceeded;
private final boolean shouldPlayWarningSignal;
/**
* IMPORTANT : Order of enum values MUST BE the same as native CarDirection enum.
*/
public enum CarDirection
{
NO_TURN(R.drawable.ic_turn_straight, 0),
GO_STRAIGHT(R.drawable.ic_turn_straight, 0),
TURN_RIGHT(R.drawable.ic_turn_right, R.drawable.ic_then_right),
TURN_SHARP_RIGHT(R.drawable.ic_turn_right_sharp, R.drawable.ic_then_right_sharp),
TURN_SLIGHT_RIGHT(R.drawable.ic_turn_right_slight, R.drawable.ic_then_right_slight),
TURN_LEFT(R.drawable.ic_turn_left, R.drawable.ic_then_left),
TURN_SHARP_LEFT(R.drawable.ic_turn_left_sharp, R.drawable.ic_then_left_sharp),
TURN_SLIGHT_LEFT(R.drawable.ic_turn_left_slight, R.drawable.ic_then_left_slight),
U_TURN_LEFT(R.drawable.ic_turn_uleft, R.drawable.ic_then_uleft),
U_TURN_RIGHT(R.drawable.ic_turn_uright, R.drawable.ic_then_uright),
ENTER_ROUND_ABOUT(R.drawable.ic_turn_round, R.drawable.ic_then_round),
LEAVE_ROUND_ABOUT(R.drawable.ic_turn_round, R.drawable.ic_then_round),
STAY_ON_ROUND_ABOUT(R.drawable.ic_turn_round, R.drawable.ic_then_round),
START_AT_THE_END_OF_STREET(0, 0),
REACHED_YOUR_DESTINATION(R.drawable.ic_turn_finish, R.drawable.ic_then_finish),
EXIT_HIGHWAY_TO_LEFT(R.drawable.ic_exit_highway_to_left, R.drawable.ic_then_exit_highway_to_left),
EXIT_HIGHWAY_TO_RIGHT(R.drawable.ic_exit_highway_to_right, R.drawable.ic_then_exit_highway_to_right);
private final int mTurnRes;
private final int mNextTurnRes;
CarDirection(@DrawableRes int mainResId, @DrawableRes int nextResId)
{
mTurnRes = mainResId;
mNextTurnRes = nextResId;
}
public int getTurnRes()
{
return mTurnRes;
}
public void setTurnDrawable(@NonNull ImageView imageView)
{
imageView.setImageResource(mTurnRes);
imageView.setRotation(0.0f);
}
public void setNextTurnDrawable(@NonNull ImageView imageView)
{
imageView.setImageResource(mNextTurnRes);
}
public boolean containsNextTurn()
{
return mNextTurnRes != 0;
}
public static boolean isRoundAbout(CarDirection turn)
{
return turn == ENTER_ROUND_ABOUT || turn == LEAVE_ROUND_ABOUT || turn == STAY_ON_ROUND_ABOUT;
}
}
enum PedestrianTurnDirection
{
NO_TURN(R.drawable.ic_turn_straight, 0),
GO_STRAIGHT(R.drawable.ic_turn_straight, 0),
TURN_RIGHT(R.drawable.ic_turn_right, R.drawable.ic_then_right),
TURN_LEFT(R.drawable.ic_turn_left, R.drawable.ic_then_left),
REACHED_YOUR_DESTINATION(R.drawable.ic_turn_finish, R.drawable.ic_then_finish);
private final int mTurnRes;
private final int mNextTurnRes;
PedestrianTurnDirection(@DrawableRes int mainResId, @DrawableRes int nextResId)
{
mTurnRes = mainResId;
mNextTurnRes = nextResId;
}
public void setTurnDrawable(@NonNull ImageView imageView)
{
imageView.setImageResource(mTurnRes);
imageView.setRotation(0.0f);
}
public void setNextTurnDrawable(@NonNull ImageView imageView)
{
imageView.setImageResource(mNextTurnRes);
}
public boolean containsNextTurn()
{
return mNextTurnRes != 0;
}
}
public RoutingInfo(Distance distToTarget, Distance distToTurn, String currentStreet, String nextStreet, String nextNextStreet, double completionPercent,
int vehicleTurnOrdinal, int vehicleNextTurnOrdinal, int pedestrianTurnOrdinal, int exitNum,
int totalTime, SingleLaneInfo[] lanes, double speedLimitMps, boolean speedLimitExceeded,
boolean shouldPlayWarningSignal)
{
this.distToTarget = distToTarget;
this.distToTurn = distToTurn;
this.currentStreet = currentStreet;
this.nextStreet = nextStreet;
this.nextNextStreet = nextNextStreet;
this.totalTimeInSeconds = totalTime;
this.completionPercent = completionPercent;
this.carDirection = CarDirection.values()[vehicleTurnOrdinal];
this.nextCarDirection = CarDirection.values()[vehicleNextTurnOrdinal];
this.lanes = lanes;
this.exitNum = exitNum;
this.pedestrianTurnDirection = PedestrianTurnDirection.values()[pedestrianTurnOrdinal];
this.speedLimitMps = speedLimitMps;
this.speedCamLimitExceeded = speedLimitExceeded;
this.shouldPlayWarningSignal = shouldPlayWarningSignal;
}
public boolean isSpeedCamLimitExceeded()
{
return speedCamLimitExceeded;
}
public boolean shouldPlayWarningSignal()
{
return shouldPlayWarningSignal;
}
}

View file

@ -18,6 +18,10 @@ import androidx.core.view.WindowInsetsCompat;
import app.organicmaps.Framework;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
import app.organicmaps.sdk.Router;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.routing.RoutingOptions;
import app.organicmaps.sdk.routing.TransitRouteInfo;
import app.organicmaps.settings.DrivingOptionsActivity;
import app.organicmaps.util.UiUtils;
import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener;
@ -143,27 +147,27 @@ public class RoutingPlanController extends ToolbarController
private void onTransitModeSelected(@NonNull View v)
{
RoutingController.get().setRouterType(Framework.ROUTER_TYPE_TRANSIT);
RoutingController.get().setRouterType(Router.Transit);
}
private void onBicycleModeSelected(@NonNull View v)
{
RoutingController.get().setRouterType(Framework.ROUTER_TYPE_BICYCLE);
RoutingController.get().setRouterType(Router.Bicycle);
}
private void onRulerModeSelected(@NonNull View v)
{
RoutingController.get().setRouterType(Framework.ROUTER_TYPE_RULER);
RoutingController.get().setRouterType(Router.Ruler);
}
private void onPedestrianModeSelected(@NonNull View v)
{
RoutingController.get().setRouterType(Framework.ROUTER_TYPE_PEDESTRIAN);
RoutingController.get().setRouterType(Router.Pedestrian);
}
private void onVehicleModeSelected(@NonNull View v)
{
RoutingController.get().setRouterType(Framework.ROUTER_TYPE_VEHICLE);
RoutingController.get().setRouterType(Router.Vehicle);
}
@Override
@ -218,35 +222,35 @@ public class RoutingPlanController extends ToolbarController
mRoutingBottomMenuController.showAltitudeChartAndRoutingDetails();
}
public void updateBuildProgress(int progress, @Framework.RouterType int router)
public void updateBuildProgress(int progress, @NonNull Router router)
{
UiUtils.invisible(mProgressVehicle, mProgressPedestrian, mProgressTransit,
mProgressBicycle, mProgressRuler);
WheelProgressView progressView;
switch (router)
{
case Framework.ROUTER_TYPE_VEHICLE:
case Vehicle:
mRouterTypes.check(R.id.vehicle);
progressView = mProgressVehicle;
break;
case Framework.ROUTER_TYPE_PEDESTRIAN:
case Pedestrian:
mRouterTypes.check(R.id.pedestrian);
progressView = mProgressPedestrian;
break;
//case Framework.ROUTER_TYPE_TAXI:
//case Taxi:
// {
// mRouterTypes.check(R.id.taxi);
// progressView = mProgressTaxi;
// }
case Framework.ROUTER_TYPE_TRANSIT:
case Transit:
mRouterTypes.check(R.id.transit);
progressView = mProgressTransit;
break;
case Framework.ROUTER_TYPE_BICYCLE:
case Bicycle:
mRouterTypes.check(R.id.bicycle);
progressView = mProgressBicycle;
break;
case Framework.ROUTER_TYPE_RULER:
case Ruler:
mRouterTypes.check(R.id.ruler);
progressView = mProgressRuler;
break;

View file

@ -8,10 +8,10 @@ import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import app.organicmaps.Framework;
import app.organicmaps.MwmActivity;
import app.organicmaps.R;
import app.organicmaps.base.BaseMwmFragment;
import app.organicmaps.sdk.Router;
public class RoutingPlanFragment extends BaseMwmFragment
{
@ -27,7 +27,7 @@ public class RoutingPlanFragment extends BaseMwmFragment
return res;
}
public void updateBuildProgress(int progress, @Framework.RouterType int router)
public void updateBuildProgress(int progress, Router router)
{
mPlanController.updateBuildProgress(progress, router);
}

View file

@ -1,62 +0,0 @@
package app.organicmaps.routing;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import app.organicmaps.R;
public class SingleLaneInfo
{
public LaneWay[] mLane;
public boolean mIsActive;
/**
* IMPORTANT : Order of enum values MUST BE the same
* with native LaneWay enum (see routing/turns.hpp for details).
* Information for every lane is composed of some number values below.
* For example, a lane may have THROUGH and RIGHT values.
*/
public enum LaneWay
{
NONE(R.drawable.ic_turn_straight),
REVERSE(R.drawable.ic_turn_uleft),
SHARP_LEFT(R.drawable.ic_turn_left_sharp),
LEFT(R.drawable.ic_turn_left),
SLIGHT_LEFT(R.drawable.ic_turn_left_slight),
MERGE_TO_RIGHT(R.drawable.ic_turn_right_slight),
THROUGH(R.drawable.ic_turn_straight),
MERGE_TO_LEFT(R.drawable.ic_turn_left_slight),
SLIGHT_RIGHT(R.drawable.ic_turn_right_slight),
RIGHT(R.drawable.ic_turn_right),
SHARP_RIGHT(R.drawable.ic_turn_right_sharp);
public final int mTurnRes;
LaneWay(@DrawableRes int turnRes)
{
mTurnRes = turnRes;
}
}
public SingleLaneInfo(@NonNull byte[] laneOrdinals, boolean isActive)
{
mLane = new LaneWay[laneOrdinals.length];
final LaneWay[] values = LaneWay.values();
for (int i = 0; i < mLane.length; i++)
mLane[i] = values[laneOrdinals[i]];
mIsActive = isActive;
}
@NonNull
@Override
public String toString()
{
final int initialCapacity = 32;
StringBuilder sb = new StringBuilder(initialCapacity);
sb.append("Is the lane active? ").append(mIsActive).append(". The lane directions IDs are");
for (LaneWay i : mLane)
sb.append(" ").append(i.ordinal());
return sb.toString();
}
}

View file

@ -8,6 +8,7 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import app.organicmaps.R;
import app.organicmaps.sdk.routing.TransitStepInfo;
import java.util.ArrayList;
import java.util.List;

View file

@ -20,6 +20,8 @@ import androidx.annotation.Nullable;
import androidx.core.content.res.ResourcesCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import app.organicmaps.R;
import app.organicmaps.sdk.routing.TransitStepInfo;
import app.organicmaps.sdk.routing.TransitStepType;
import app.organicmaps.widget.recycler.MultilineLayoutManager;
import app.organicmaps.util.ThemeUtils;

View file

@ -0,0 +1,37 @@
package app.organicmaps.sdk;
import androidx.annotation.NonNull;
public enum ChoosePositionMode
{
None(0),
Editor(1),
Api(2);
ChoosePositionMode(int mode)
{
this.mode = mode;
}
/**
* @param isBusiness selection area will be bounded by building borders, if its true (eg. true for businesses in buildings).
* @param applyPosition if true, map will be animated to currently selected object.
*/
public static void set(@NonNull ChoosePositionMode mode, boolean isBusiness, boolean applyPosition)
{
nativeSet(mode.mode, isBusiness, applyPosition);
}
public static ChoosePositionMode get()
{
return ChoosePositionMode.values()[nativeGet()];
}
private final int mode;
private static native void nativeSet(int mode, boolean isBusiness,
boolean applyPosition);
private static native int nativeGet();
}

View file

@ -0,0 +1,59 @@
package app.organicmaps.sdk;
import androidx.annotation.NonNull;
public enum MapStyle
{
Clear(0),
Dark(1),
VehicleClear(3),
VehicleDark(4),
OutdoorsClear(5),
OutdoorsDark(6);
MapStyle(int value)
{
this.value = value;
}
@NonNull
public static MapStyle get()
{
return valueOf(nativeGet());
}
public static void set(@NonNull MapStyle mapStyle)
{
nativeSet(mapStyle.value);
}
/**
* This method allows to set new map style without immediate applying. It can be used before
* engine recreation instead of nativeSetMapStyle to avoid huge flow of OpenGL invocations.
*
* @param mapStyle style index
*/
public static void mark(@NonNull MapStyle mapStyle)
{
nativeMark(mapStyle.value);
}
@NonNull
public static MapStyle valueOf(int value)
{
for (MapStyle mapStyle : MapStyle.values())
{
if (mapStyle.value == value)
return mapStyle;
}
throw new IllegalArgumentException("Unknown map style value: " + value);
}
private final int value;
private static native void nativeSet(int mapStyle);
private static native int nativeGet();
private static native void nativeMark(int mapStyle);
}

View file

@ -0,0 +1,178 @@
package app.organicmaps.sdk;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ProcessLifecycleOwner;
import app.organicmaps.R;
import app.organicmaps.bookmarks.data.BookmarkManager;
import app.organicmaps.maplayer.isolines.IsolinesManager;
import app.organicmaps.maplayer.subway.SubwayManager;
import app.organicmaps.maplayer.traffic.TrafficManager;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.search.SearchEngine;
import app.organicmaps.settings.StoragePathManager;
import app.organicmaps.sound.TtsPlayer;
import app.organicmaps.util.Config;
import app.organicmaps.util.SharedPropertiesUtils;
import app.organicmaps.util.StorageUtils;
import app.organicmaps.util.ThemeSwitcher;
import app.organicmaps.util.UiUtils;
import app.organicmaps.util.log.Logger;
import java.io.IOException;
public final class OrganicMaps implements DefaultLifecycleObserver
{
private static final String TAG = OrganicMaps.class.getSimpleName();
@NonNull
private final Context mContext;
private volatile boolean mFrameworkInitialized;
private volatile boolean mPlatformInitialized;
public OrganicMaps(@NonNull Context context)
{
mContext = context.getApplicationContext();
// Set configuration directory as early as possible.
// Other methods may explicitly use Config, which requires settingsDir to be set.
final String settingsPath = StorageUtils.getSettingsPath(mContext);
if (!StorageUtils.createDirectory(settingsPath))
throw new AssertionError("Can't create settingsDir " + settingsPath);
Logger.d(TAG, "Settings path = " + settingsPath);
nativeSetSettingsDir(settingsPath);
Config.init(mContext);
}
/**
* Initialize native core of application: platform and framework.
*
* @throws IOException - if failed to create directories. Caller must handle
* the exception and do nothing with native code if initialization is failed.
*/
public boolean init(@NonNull Runnable onComplete) throws IOException
{
initNativePlatform();
return initNativeFramework(onComplete);
}
public boolean arePlatformAndCoreInitialized()
{
return mFrameworkInitialized && mPlatformInitialized;
}
@Override
public void onStart(@NonNull LifecycleOwner owner)
{
nativeOnTransit(true);
}
@Override
public void onStop(@NonNull LifecycleOwner owner)
{
nativeOnTransit(false);
}
private void initNativePlatform() throws IOException
{
if (mPlatformInitialized)
return;
final String apkPath = StorageUtils.getApkPath(mContext);
Logger.d(TAG, "Apk path = " + apkPath);
// Note: StoragePathManager uses Config, which requires SettingsDir to be set.
final String writablePath = StoragePathManager.findMapsStorage(mContext);
Logger.d(TAG, "Writable path = " + writablePath);
final String privatePath = StorageUtils.getPrivatePath(mContext);
Logger.d(TAG, "Private path = " + privatePath);
final String tempPath = StorageUtils.getTempPath(mContext);
Logger.d(TAG, "Temp path = " + tempPath);
// If platform directories are not created it means that native part of app will not be able
// to work at all. So, we just ignore native part initialization in this case, e.g. when the
// external storage is damaged or not available (read-only).
createPlatformDirectories(writablePath, privatePath, tempPath);
nativeInitPlatform(mContext,
apkPath,
writablePath,
privatePath,
tempPath,
app.organicmaps.BuildConfig.FLAVOR,
app.organicmaps.BuildConfig.BUILD_TYPE, UiUtils.isTablet(mContext));
Config.setStoragePath(writablePath);
Config.setStatisticsEnabled(SharedPropertiesUtils.isStatisticsEnabled(mContext));
mPlatformInitialized = true;
Logger.i(TAG, "Platform initialized");
}
private boolean initNativeFramework(@NonNull Runnable onComplete)
{
if (mFrameworkInitialized)
return false;
nativeInitFramework(onComplete);
initNativeStrings();
ThemeSwitcher.INSTANCE.initialize(mContext);
SearchEngine.INSTANCE.initialize();
BookmarkManager.loadBookmarks();
TtsPlayer.INSTANCE.initialize(mContext);
ThemeSwitcher.INSTANCE.restart(false);
RoutingController.get().initialize(mContext);
TrafficManager.INSTANCE.initialize();
SubwayManager.from(mContext).initialize();
IsolinesManager.from(mContext).initialize();
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
Logger.i(TAG, "Framework initialized");
mFrameworkInitialized = true;
return true;
}
private void createPlatformDirectories(@NonNull String writablePath,
@NonNull String privatePath,
@NonNull String tempPath) throws IOException
{
SharedPropertiesUtils.emulateBadExternalStorage(mContext);
StorageUtils.requireDirectory(writablePath);
StorageUtils.requireDirectory(privatePath);
StorageUtils.requireDirectory(tempPath);
}
private void initNativeStrings()
{
nativeAddLocalization("core_entrance", mContext.getString(R.string.core_entrance));
nativeAddLocalization("core_exit", mContext.getString(R.string.core_exit));
nativeAddLocalization("core_my_places", mContext.getString(R.string.core_my_places));
nativeAddLocalization("core_my_position", mContext.getString(R.string.core_my_position));
nativeAddLocalization("core_placepage_unknown_place", mContext.getString(R.string.core_placepage_unknown_place));
nativeAddLocalization("postal_code", mContext.getString(R.string.postal_code));
nativeAddLocalization("wifi", mContext.getString(R.string.category_wifi));
}
private static native void nativeSetSettingsDir(String settingsPath);
private static native void nativeInitPlatform(Context context, String apkPath, String writablePath,
String privatePath, String tmpPath, String flavorName,
String buildType, boolean isTablet);
private static native void nativeInitFramework(@NonNull Runnable onComplete);
private static native void nativeAddLocalization(String name, String value);
private static native void nativeOnTransit(boolean foreground);
static
{
System.loadLibrary("organicmaps");
}
}

View file

@ -0,0 +1,24 @@
package app.organicmaps.sdk;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import app.organicmaps.widget.placepage.PlacePageData;
public interface PlacePageActivationListener
{
// Called from JNI.
@Keep
@SuppressWarnings("unused")
void onPlacePageActivated(@NonNull PlacePageData data);
// Called from JNI
@Keep
@SuppressWarnings("unused")
void onPlacePageDeactivated();
// Called from JNI
@Keep
@SuppressWarnings("unused")
void onSwitchFullScreenMode();
}

View file

@ -0,0 +1,53 @@
package app.organicmaps.sdk;
import androidx.annotation.NonNull;
public enum Router
{
Vehicle(0),
Pedestrian(1),
Bicycle(2),
Transit(3),
Ruler(4);
Router(int type)
{
this.type = type;
}
public static void set(@NonNull Router routerType)
{
nativeSet(routerType.type);
}
public static Router get()
{
return valueOf(nativeGet());
}
public static Router getLastUsed()
{
return valueOf(nativeGetLastUsed());
}
public static Router getBest(double srcLat, double srcLon, double dstLat, double dstLon)
{
return Router.values()[nativeGetBest(srcLat, srcLon, dstLat, dstLon)];
}
public static Router valueOf(int type)
{
return Router.values()[type];
}
private final int type;
private static native void nativeSet(int routerType);
private static native int nativeGet();
private static native int nativeGetLastUsed();
private static native int nativeGetBest(double srcLat, double srcLon,
double dstLat, double dstLon);
}

View file

@ -0,0 +1,73 @@
package app.organicmaps.sdk.routing;
import android.widget.ImageView;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import app.organicmaps.R;
/**
* IMPORTANT : Order of enum values MUST BE the same as native CarDirection enum.
*/
public enum CarDirection
{
NO_TURN(R.drawable.ic_turn_straight, 0),
GO_STRAIGHT(R.drawable.ic_turn_straight, 0),
TURN_RIGHT(R.drawable.ic_turn_right, R.drawable.ic_then_right),
TURN_SHARP_RIGHT(R.drawable.ic_turn_right_sharp, R.drawable.ic_then_right_sharp),
TURN_SLIGHT_RIGHT(R.drawable.ic_turn_right_slight, R.drawable.ic_then_right_slight),
TURN_LEFT(R.drawable.ic_turn_left, R.drawable.ic_then_left),
TURN_SHARP_LEFT(R.drawable.ic_turn_left_sharp, R.drawable.ic_then_left_sharp),
TURN_SLIGHT_LEFT(R.drawable.ic_turn_left_slight, R.drawable.ic_then_left_slight),
U_TURN_LEFT(R.drawable.ic_turn_uleft, R.drawable.ic_then_uleft),
U_TURN_RIGHT(R.drawable.ic_turn_uright, R.drawable.ic_then_uright),
ENTER_ROUND_ABOUT(R.drawable.ic_turn_round, R.drawable.ic_then_round),
LEAVE_ROUND_ABOUT(R.drawable.ic_turn_round, R.drawable.ic_then_round),
STAY_ON_ROUND_ABOUT(R.drawable.ic_turn_round, R.drawable.ic_then_round),
START_AT_THE_END_OF_STREET(0, 0),
REACHED_YOUR_DESTINATION(R.drawable.ic_turn_finish, R.drawable.ic_then_finish),
EXIT_HIGHWAY_TO_LEFT(R.drawable.ic_exit_highway_to_left, R.drawable.ic_then_exit_highway_to_left),
EXIT_HIGHWAY_TO_RIGHT(R.drawable.ic_exit_highway_to_right, R.drawable.ic_then_exit_highway_to_right);
private final int mTurnRes;
private final int mNextTurnRes;
CarDirection(@DrawableRes int mainResId, @DrawableRes int nextResId)
{
mTurnRes = mainResId;
mNextTurnRes = nextResId;
}
public int getTurnRes()
{
return mTurnRes;
}
public void setTurnDrawable(@NonNull ImageView imageView)
{
imageView.setImageResource(mTurnRes);
imageView.setRotation(0.0f);
}
public void setNextTurnDrawable(@NonNull ImageView imageView)
{
imageView.setImageResource(mNextTurnRes);
}
public boolean containsNextTurn()
{
return mNextTurnRes != 0;
}
public static boolean isRoundAbout(CarDirection turn)
{
return turn == ENTER_ROUND_ABOUT || turn == LEAVE_ROUND_ABOUT || turn == STAY_ON_ROUND_ABOUT;
}
}

View file

@ -1,16 +1,16 @@
package app.organicmaps.routing;
package app.organicmaps.sdk.routing;
import androidx.annotation.Keep;
// Used by JNI.
@Keep
@SuppressWarnings("unused")
public class JunctionInfo
public final class JunctionInfo
{
public final double mLat;
public final double mLon;
public JunctionInfo(double lat, double lon)
private JunctionInfo(double lat, double lon)
{
mLat = lat;
mLon = lon;

View file

@ -0,0 +1,33 @@
package app.organicmaps.sdk.routing;
import androidx.annotation.DrawableRes;
import app.organicmaps.R;
/**
* IMPORTANT : Order of enum values MUST BE the same
* with native LaneWay enum (see routing/turns.hpp for details).
* Information for every lane is composed of some number values below.
* For example, a lane may have THROUGH and RIGHT values.
*/
public enum LaneWay
{
NONE(R.drawable.ic_turn_straight),
REVERSE(R.drawable.ic_turn_uleft),
SHARP_LEFT(R.drawable.ic_turn_left_sharp),
LEFT(R.drawable.ic_turn_left),
SLIGHT_LEFT(R.drawable.ic_turn_left_slight),
MERGE_TO_RIGHT(R.drawable.ic_turn_right_slight),
THROUGH(R.drawable.ic_turn_straight),
MERGE_TO_LEFT(R.drawable.ic_turn_left_slight),
SLIGHT_RIGHT(R.drawable.ic_turn_right_slight),
RIGHT(R.drawable.ic_turn_right),
SHARP_RIGHT(R.drawable.ic_turn_right_sharp);
public final int mTurnRes;
LaneWay(@DrawableRes int turnRes)
{
mTurnRes = turnRes;
}
}

View file

@ -0,0 +1,44 @@
package app.organicmaps.sdk.routing;
import android.widget.ImageView;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import app.organicmaps.R;
public enum PedestrianTurnDirection
{
NO_TURN(R.drawable.ic_turn_straight, 0),
GO_STRAIGHT(R.drawable.ic_turn_straight, 0),
TURN_RIGHT(R.drawable.ic_turn_right, R.drawable.ic_then_right),
TURN_LEFT(R.drawable.ic_turn_left, R.drawable.ic_then_left),
REACHED_YOUR_DESTINATION(R.drawable.ic_turn_finish, R.drawable.ic_then_finish);
private final int mTurnRes;
private final int mNextTurnRes;
PedestrianTurnDirection(@DrawableRes int mainResId, @DrawableRes int nextResId)
{
mTurnRes = mainResId;
mNextTurnRes = nextResId;
}
public void setTurnDrawable(@NonNull ImageView imageView)
{
imageView.setImageResource(mTurnRes);
imageView.setRotation(0.0f);
}
public void setNextTurnDrawable(@NonNull ImageView imageView)
{
imageView.setImageResource(mNextTurnRes);
}
public boolean containsNextTurn()
{
return mNextTurnRes != 0;
}
}

View file

@ -1,4 +1,4 @@
package app.organicmaps.routing;
package app.organicmaps.sdk.routing;
import androidx.annotation.Keep;
import androidx.annotation.Nullable;
@ -9,14 +9,13 @@ import androidx.annotation.Nullable;
// Called from JNI.
@Keep
@SuppressWarnings("unused")
public class RouteMarkData
public final class RouteMarkData
{
@Nullable
public final String mTitle;
@Nullable
public final String mSubtitle;
@RoutePointInfo.RouteMarkType
public int mPointType;
public RouteMarkType mPointType;
public int mIntermediateIndex;
public final boolean mIsVisible;
public final boolean mIsMyPosition;
@ -24,10 +23,16 @@ public class RouteMarkData
public final double mLat;
public final double mLon;
private RouteMarkData(@Nullable String title, @Nullable String subtitle,
int pointType, int intermediateIndex, boolean isVisible,
boolean isMyPosition, boolean isPassed, double lat, double lon)
{
this(title, subtitle, RouteMarkType.values()[pointType], intermediateIndex, isVisible, isMyPosition, isPassed, lat, lon);
}
public RouteMarkData(@Nullable String title, @Nullable String subtitle,
@RoutePointInfo.RouteMarkType int pointType,
int intermediateIndex, boolean isVisible, boolean isMyPosition,
boolean isPassed, double lat, double lon)
RouteMarkType pointType, int intermediateIndex, boolean isVisible,
boolean isMyPosition, boolean isPassed, double lat, double lon)
{
mTitle = title;
mSubtitle = subtitle;

View file

@ -0,0 +1,8 @@
package app.organicmaps.sdk.routing;
public enum RouteMarkType
{
Start,
Intermediate,
Finish
}

View file

@ -1,18 +1,15 @@
package app.organicmaps.routing;
package app.organicmaps.sdk.routing;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.IntDef;
import androidx.annotation.Keep;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import androidx.annotation.NonNull;
// Called from JNI.
@Keep
@SuppressWarnings("unused")
public class RoutePointInfo implements Parcelable
public final class RoutePointInfo implements Parcelable
{
public static final Creator<RoutePointInfo> CREATOR = new Creator<>()
{
@ -29,44 +26,35 @@ public class RoutePointInfo implements Parcelable
}
};
public static final int ROUTE_MARK_START = 0;
public static final int ROUTE_MARK_INTERMEDIATE = 1;
public static final int ROUTE_MARK_FINISH = 2;
@Retention(RetentionPolicy.SOURCE)
@IntDef({ ROUTE_MARK_START, ROUTE_MARK_INTERMEDIATE, ROUTE_MARK_FINISH })
public @interface RouteMarkType {}
@RouteMarkType
public final int mMarkType;
public final RouteMarkType mMarkType;
public final int mIntermediateIndex;
public RoutePointInfo(@RouteMarkType int markType, int intermediateIndex)
private RoutePointInfo(@NonNull RouteMarkType markType, int intermediateIndex)
{
mMarkType = markType;
mIntermediateIndex = intermediateIndex;
}
private RoutePointInfo(Parcel in)
private RoutePointInfo(@NonNull Parcel in)
{
//noinspection WrongConstant
this(in.readInt() /* mMarkType */, in.readInt() /* mIntermediateIndex */);
this(RouteMarkType.values()[in.readInt()] /* mMarkType */, in.readInt() /* mIntermediateIndex */);
}
boolean isIntermediatePoint()
{
return mMarkType == ROUTE_MARK_INTERMEDIATE;
return mMarkType == RouteMarkType.Intermediate;
}
boolean isFinishPoint()
{
return mMarkType == ROUTE_MARK_FINISH;
return mMarkType == RouteMarkType.Finish;
}
boolean isStartPoint()
{
return mMarkType == ROUTE_MARK_START;
return mMarkType == RouteMarkType.Start;
}
@Override
@ -78,7 +66,7 @@ public class RoutePointInfo implements Parcelable
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeInt(mMarkType);
dest.writeInt(mMarkType.ordinal());
dest.writeInt(mIntermediateIndex);
}
}

View file

@ -0,0 +1,6 @@
package app.organicmaps.sdk.routing;
public enum RouteRecommendationType
{
RebuildAfterPointsLoading
}

View file

@ -0,0 +1,69 @@
package app.organicmaps.sdk.routing;
import androidx.annotation.Keep;
import app.organicmaps.util.Distance;
// Called from JNI.
@Keep
@SuppressWarnings("unused")
public final class RoutingInfo
{
// Target (end point of route).
public final Distance distToTarget;
// Next turn.
public final Distance distToTurn;
public final int totalTimeInSeconds;
// Current street name.
public final String currentStreet;
// The next street name.
public final String nextStreet;
// The next next street name.
public final String nextNextStreet;
public final double completionPercent;
// For vehicle routing.
public final CarDirection carDirection;
public final CarDirection nextCarDirection;
public final int exitNum;
public final SingleLaneInfo[] lanes;
// For pedestrian routing.
public final PedestrianTurnDirection pedestrianTurnDirection;
// Current speed limit in meters per second.
// If no info about speed limit then speedLimitMps < 0.
public final double speedLimitMps;
private final boolean speedCamLimitExceeded;
private final boolean shouldPlayWarningSignal;
private RoutingInfo(Distance distToTarget, Distance distToTurn, String currentStreet, String nextStreet, String nextNextStreet, double completionPercent,
int vehicleTurnOrdinal, int vehicleNextTurnOrdinal, int pedestrianTurnOrdinal, int exitNum,
int totalTime, SingleLaneInfo[] lanes, double speedLimitMps, boolean speedLimitExceeded,
boolean shouldPlayWarningSignal)
{
this.distToTarget = distToTarget;
this.distToTurn = distToTurn;
this.currentStreet = currentStreet;
this.nextStreet = nextStreet;
this.nextNextStreet = nextNextStreet;
this.totalTimeInSeconds = totalTime;
this.completionPercent = completionPercent;
this.carDirection = CarDirection.values()[vehicleTurnOrdinal];
this.nextCarDirection = CarDirection.values()[vehicleNextTurnOrdinal];
this.lanes = lanes;
this.exitNum = exitNum;
this.pedestrianTurnDirection = PedestrianTurnDirection.values()[pedestrianTurnOrdinal];
this.speedLimitMps = speedLimitMps;
this.speedCamLimitExceeded = speedLimitExceeded;
this.shouldPlayWarningSignal = shouldPlayWarningSignal;
}
public boolean isSpeedCamLimitExceeded()
{
return speedCamLimitExceeded;
}
public boolean shouldPlayWarningSignal()
{
return shouldPlayWarningSignal;
}
}

View file

@ -0,0 +1,13 @@
package app.organicmaps.sdk.routing;
import androidx.annotation.Keep;
import androidx.annotation.MainThread;
public interface RoutingListener
{
// Called from JNI
@Keep
@SuppressWarnings("unused")
@MainThread
void onRoutingEvent(int resultCode, String[] missingMaps);
}

View file

@ -0,0 +1,11 @@
package app.organicmaps.sdk.routing;
import androidx.annotation.Keep;
public interface RoutingLoadPointsListener
{
// Called from JNI.
@Keep
@SuppressWarnings("unused")
void onRoutePointsLoaded(boolean success);
}

View file

@ -1,4 +1,4 @@
package app.organicmaps.routing;
package app.organicmaps.sdk.routing;
import androidx.annotation.NonNull;
@ -7,7 +7,7 @@ import app.organicmaps.settings.RoadType;
import java.util.HashSet;
import java.util.Set;
public class RoutingOptions
public final class RoutingOptions
{
public static void addOption(@NonNull RoadType roadType)
{
@ -24,10 +24,6 @@ public class RoutingOptions
return nativeHasOption(roadType.ordinal());
}
private static native void nativeAddOption(int option);
private static native void nativeRemoveOption(int option);
private static native boolean nativeHasOption(int option);
public static boolean hasAnyOptions()
{
for (RoadType each : RoadType.values())
@ -49,4 +45,14 @@ public class RoutingOptions
}
return roadTypes;
}
private RoutingOptions() throws IllegalAccessException
{
throw new IllegalAccessException("RoutingOptions is a utility class and should not be instantiated");
}
private static native void nativeAddOption(int option);
private static native void nativeRemoveOption(int option);
private static native boolean nativeHasOption(int option);
}

View file

@ -0,0 +1,13 @@
package app.organicmaps.sdk.routing;
import androidx.annotation.Keep;
import androidx.annotation.MainThread;
public interface RoutingProgressListener
{
// Called from JNI.
@Keep
@SuppressWarnings("unused")
@MainThread
void onRouteBuildingProgress(float progress);
}

View file

@ -0,0 +1,11 @@
package app.organicmaps.sdk.routing;
import androidx.annotation.Keep;
public interface RoutingRecommendationListener
{
// Called from JNI.
@Keep
@SuppressWarnings("unused")
void onRecommend(RouteRecommendationType recommendation);
}

View file

@ -0,0 +1,31 @@
package app.organicmaps.sdk.routing;
import androidx.annotation.NonNull;
public final class SingleLaneInfo
{
public LaneWay[] mLane;
public boolean mIsActive;
public SingleLaneInfo(@NonNull byte[] laneOrdinals, boolean isActive)
{
mLane = new LaneWay[laneOrdinals.length];
final LaneWay[] values = LaneWay.values();
for (int i = 0; i < mLane.length; i++)
mLane[i] = values[laneOrdinals[i]];
mIsActive = isActive;
}
@NonNull
@Override
public String toString()
{
final int initialCapacity = 32;
StringBuilder sb = new StringBuilder(initialCapacity);
sb.append("Is the lane active? ").append(mIsActive).append(". The lane directions IDs are");
for (LaneWay i : mLane)
sb.append(" ").append(i.ordinal());
return sb.toString();
}
}

View file

@ -1,4 +1,4 @@
package app.organicmaps.routing;
package app.organicmaps.sdk.routing;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
@ -13,7 +13,7 @@ import java.util.List;
// Used by JNI.
@Keep
@SuppressWarnings("unused")
public class TransitRouteInfo
public final class TransitRouteInfo
{
@NonNull
private final String mTotalDistance;
@ -28,7 +28,7 @@ public class TransitRouteInfo
@NonNull
private final TransitStepInfo[] mSteps;
public TransitRouteInfo(@NonNull String totalDistance, @NonNull String totalDistanceUnits, int totalTimeInSec,
private TransitRouteInfo(@NonNull String totalDistance, @NonNull String totalDistanceUnits, int totalTimeInSec,
@NonNull String totalPedestrianDistance, @NonNull String totalPedestrianDistanceUnits,
int totalPedestrianTimeInSec, @NonNull TransitStepInfo[] steps)
{
@ -42,29 +42,29 @@ public class TransitRouteInfo
}
@NonNull
String getTotalPedestrianDistance()
public String getTotalPedestrianDistance()
{
return mTotalPedestrianDistance;
}
int getTotalPedestrianTimeInSec()
public int getTotalPedestrianTimeInSec()
{
return mTotalPedestrianTimeInSec;
}
@NonNull
String getTotalPedestrianDistanceUnits()
public String getTotalPedestrianDistanceUnits()
{
return mTotalPedestrianDistanceUnits;
}
int getTotalTime()
public int getTotalTime()
{
return mTotalTimeInSec;
}
@NonNull
List<TransitStepInfo> getTransitSteps()
public List<TransitStepInfo> getTransitSteps()
{
return new ArrayList<>(Arrays.asList(mSteps));
}

View file

@ -1,34 +1,17 @@
package app.organicmaps.routing;
package app.organicmaps.sdk.routing;
import androidx.annotation.IntDef;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Represents TransitStepInfo from core.
*/
// Used by JNI.
@Keep
@SuppressWarnings("unused")
public class TransitStepInfo
public final class TransitStepInfo
{
private static final int TRANSIT_TYPE_INTERMEDIATE_POINT = 0;
private static final int TRANSIT_TYPE_PEDESTRIAN = 1;
private static final int TRANSIT_TYPE_SUBWAY = 2;
private static final int TRANSIT_TYPE_TRAIN = 3;
private static final int TRANSIT_TYPE_LIGHT_RAIL = 4;
private static final int TRANSIT_TYPE_MONORAIL = 5;
private static final int TRANSIT_TYPE_RULER = 6;
@Retention(RetentionPolicy.SOURCE)
@IntDef({ TRANSIT_TYPE_INTERMEDIATE_POINT, TRANSIT_TYPE_PEDESTRIAN, TRANSIT_TYPE_SUBWAY,
TRANSIT_TYPE_TRAIN, TRANSIT_TYPE_LIGHT_RAIL, TRANSIT_TYPE_MONORAIL, TRANSIT_TYPE_RULER})
@interface TransitType {}
@NonNull
private final TransitStepType mType;
@Nullable
@ -41,8 +24,8 @@ public class TransitStepInfo
private final int mColor;
private final int mIntermediateIndex;
TransitStepInfo(@TransitType int type, @Nullable String distance, @Nullable String distanceUnits,
int timeInSec, @Nullable String number, int color, int intermediateIndex)
private TransitStepInfo(int type, @Nullable String distance, @Nullable String distanceUnits,
int timeInSec, @Nullable String number, int color, int intermediateIndex)
{
mType = TransitStepType.values()[type];
mDistance = distance;
@ -56,13 +39,13 @@ public class TransitStepInfo
@NonNull
public static TransitStepInfo intermediatePoint(int intermediateIndex)
{
return new TransitStepInfo(TRANSIT_TYPE_INTERMEDIATE_POINT, null, null, 0, null, 0, intermediateIndex);
return new TransitStepInfo(TransitStepType.INTERMEDIATE_POINT.ordinal(), null, null, 0, null, 0, intermediateIndex);
}
@NonNull
public static TransitStepInfo ruler(@NonNull String distance, @NonNull String distanceUnits)
{
return new TransitStepInfo(TRANSIT_TYPE_RULER, distance, distanceUnits, 0, null, 0, -1);
return new TransitStepInfo(TransitStepType.RULER.ordinal(), distance, distanceUnits, 0, null, 0, -1);
}
@NonNull

View file

@ -1,4 +1,4 @@
package app.organicmaps.routing;
package app.organicmaps.sdk.routing;
import androidx.annotation.DrawableRes;

View file

@ -14,7 +14,7 @@ import androidx.appcompat.widget.SwitchCompat;
import app.organicmaps.R;
import app.organicmaps.base.BaseMwmToolbarFragment;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.routing.RoutingOptions;
import app.organicmaps.sdk.routing.RoutingOptions;
import java.util.ArrayList;
import java.util.Collections;

View file

@ -24,7 +24,7 @@ import app.organicmaps.editor.data.Language;
import app.organicmaps.help.HelpActivity;
import app.organicmaps.location.LocationHelper;
import app.organicmaps.location.LocationProviderFactory;
import app.organicmaps.routing.RoutingOptions;
import app.organicmaps.sdk.routing.RoutingOptions;
import app.organicmaps.util.Config;
import app.organicmaps.util.NetworkPolicy;
import app.organicmaps.util.PowerManagment;

View file

@ -1,6 +1,5 @@
package app.organicmaps.settings;
import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@ -306,9 +305,9 @@ public class StoragePathManager
* Checks the currently configured storage first, then scans other storages.
* If no map files found uses getDefaultStorage().
*/
public static String findMapsStorage(@NonNull Application application)
public static String findMapsStorage(@NonNull Context context)
{
StoragePathManager mgr = new StoragePathManager(application);
StoragePathManager mgr = new StoragePathManager(context);
mgr.scanAvailableStorages();
String path;
final List<StorageItem> storages = mgr.mStorages;

View file

@ -1,6 +1,5 @@
package app.organicmaps.util;
import android.app.Application;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
@ -91,11 +90,11 @@ public class StorageUtils
}
@NonNull
public static String getApkPath(@NonNull Application application)
public static String getApkPath(@NonNull Context context)
{
try
{
return Utils.getApplicationInfo(application.getPackageManager(), BuildConfig.APPLICATION_ID, 0).sourceDir;
return Utils.getApplicationInfo(context.getPackageManager(), BuildConfig.APPLICATION_ID, 0).sourceDir;
}
catch (final PackageManager.NameNotFoundException e)
{
@ -113,21 +112,21 @@ public class StorageUtils
}
@NonNull
public static String getSettingsPath(@NonNull Application application)
public static String getSettingsPath(@NonNull Context context)
{
return addTrailingSeparator(application.getFilesDir().getAbsolutePath());
return addTrailingSeparator(context.getFilesDir().getAbsolutePath());
}
@NonNull
public static String getPrivatePath(@NonNull Application application)
public static String getPrivatePath(@NonNull Context context)
{
return addTrailingSeparator(application.getFilesDir().getAbsolutePath());
return addTrailingSeparator(context.getFilesDir().getAbsolutePath());
}
@NonNull
public static String getTempPath(@NonNull Application application)
public static String getTempPath(@NonNull Context context)
{
return addTrailingSeparator(application.getCacheDir().getAbsolutePath());
return addTrailingSeparator(context.getCacheDir().getAbsolutePath());
}
public static boolean createDirectory(@NonNull final String path)

View file

@ -15,6 +15,7 @@ import app.organicmaps.display.DisplayManager;
import app.organicmaps.downloader.DownloaderStatusIcon;
import app.organicmaps.location.LocationHelper;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.sdk.MapStyle;
import app.organicmaps.util.concurrency.UiThread;
public enum ThemeSwitcher
@ -68,7 +69,7 @@ public enum ThemeSwitcher
/**
* Changes the UI theme of application and the map style if necessary. If the contract regarding
* the input parameter is broken, the UI will be frozen during attempting to change the map style
* through the synchronous method {@link Framework#nativeSetMapStyle(int)}.
* through the synchronous method {@link MapStyle#set(MapStyle)}.
*
* @param isRendererActive Indicates whether OpenGL renderer is active or not. Must be
* <code>true</code> only if the map is rendered and visible on the screen
@ -93,11 +94,8 @@ public enum ThemeSwitcher
{
UiModeManager uiModeManager = (UiModeManager) mContext.getSystemService(Context.UI_MODE_SERVICE);
String oldTheme = Config.getCurrentUiTheme(mContext);
@Framework.MapStyle
int oldStyle = Framework.nativeGetMapStyle();
@Framework.MapStyle
int style;
MapStyle style;
if (ThemeUtils.isNightTheme(mContext, theme))
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
@ -106,11 +104,11 @@ public enum ThemeSwitcher
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
if (RoutingController.get().isVehicleNavigation())
style = Framework.MAP_STYLE_VEHICLE_DARK;
style = MapStyle.VehicleDark;
else if (Framework.nativeIsOutdoorsLayerEnabled())
style = Framework.MAP_STYLE_OUTDOORS_DARK;
style = MapStyle.OutdoorsDark;
else
style = Framework.MAP_STYLE_DARK;
style = MapStyle.Dark;
}
else
{
@ -120,11 +118,11 @@ public enum ThemeSwitcher
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
if (RoutingController.get().isVehicleNavigation())
style = Framework.MAP_STYLE_VEHICLE_CLEAR;
style = MapStyle.VehicleClear;
else if (Framework.nativeIsOutdoorsLayerEnabled())
style = Framework.MAP_STYLE_OUTDOORS_CLEAR;
style = MapStyle.OutdoorsClear;
else
style = Framework.MAP_STYLE_CLEAR;
style = MapStyle.Clear;
}
if (!theme.equals(oldTheme))
@ -139,14 +137,14 @@ public enum ThemeSwitcher
else
{
// If the UI theme is not changed we just need to change the map style if needed.
int currentStyle = Framework.nativeGetMapStyle();
final MapStyle currentStyle = MapStyle.get();
if (currentStyle == style)
return;
SetMapStyle(style);
}
}
private void SetMapStyle(@Framework.MapStyle int style)
private void SetMapStyle(MapStyle style)
{
// Because of the distinct behavior in auto theme, Android Auto employs its own mechanism for theme switching.
// For the Android Auto theme switcher, please consult the app.organicmaps.car.util.ThemeUtils module.
@ -155,8 +153,8 @@ public enum ThemeSwitcher
// If rendering is not active we can mark map style, because all graphics
// will be recreated after rendering activation.
if (mRendererActive)
Framework.nativeSetMapStyle(style);
MapStyle.set(style);
else
Framework.nativeMarkMapStyle(style);
MapStyle.mark(style);
}
}

View file

@ -583,7 +583,7 @@ public class Utils
public static void detachFragmentIfCoreNotInitialized(@NonNull Context context,
@NonNull Fragment fragment)
{
if (MwmApplication.from(context).arePlatformAndCoreInitialized())
if (MwmApplication.from(context).getOrganicMaps().arePlatformAndCoreInitialized())
return;
FragmentManager manager = fragment.getFragmentManager();

View file

@ -15,7 +15,7 @@ import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.content.ContextCompat;
import app.organicmaps.R;
import app.organicmaps.routing.SingleLaneInfo;
import app.organicmaps.sdk.routing.SingleLaneInfo;
import java.util.Objects;

View file

@ -18,7 +18,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.StyleableRes;
import app.organicmaps.R;
import app.organicmaps.routing.SingleLaneInfo;
import app.organicmaps.sdk.routing.SingleLaneInfo;
public class LanesView extends View
{

View file

@ -14,7 +14,7 @@ import androidx.core.content.ContextCompat;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import app.organicmaps.R;
import app.organicmaps.location.LocationHelper;
import app.organicmaps.routing.RoutingInfo;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sound.TtsPlayer;
import app.organicmaps.util.Graphics;
import app.organicmaps.util.StringUtils;