From 0b40dd8f0f5729e9ecc9b6c5eb13597d9faffd85 Mon Sep 17 00:00:00 2001 From: alexzatsepin Date: Thu, 20 Apr 2017 14:39:59 +0300 Subject: [PATCH] [android] Added support for vehicle map styles --- android/jni/com/mapswithme/maps/Framework.cpp | 6 ++ .../src/com/mapswithme/maps/Framework.java | 8 ++ .../src/com/mapswithme/maps/MwmActivity.java | 18 +++- .../com/mapswithme/maps/MwmApplication.java | 2 +- .../maps/routing/RoutingController.java | 18 ++-- .../maps/settings/MapPrefsFragment.java | 2 +- android/src/com/mapswithme/util/Config.java | 6 +- .../com/mapswithme/util/ThemeSwitcher.java | 96 +++++++++++-------- 8 files changed, 105 insertions(+), 51 deletions(-) diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index 2e06e5c43b..9f42f9cc06 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -1060,6 +1060,12 @@ Java_com_mapswithme_maps_Framework_nativeSetMapStyle(JNIEnv * env, jclass, jint g_framework->SetMapStyle(val); } +JNIEXPORT jint JNICALL +Java_com_mapswithme_maps_Framework_nativeGetMapStyle(JNIEnv * env, jclass, jint mapStyle) +{ + return g_framework->GetMapStyle(); +} + JNIEXPORT void JNICALL Java_com_mapswithme_maps_Framework_nativeMarkMapStyle(JNIEnv * env, jclass, jint mapStyle) { diff --git a/android/src/com/mapswithme/maps/Framework.java b/android/src/com/mapswithme/maps/Framework.java index 8649d21a00..b5793f0430 100644 --- a/android/src/com/mapswithme/maps/Framework.java +++ b/android/src/com/mapswithme/maps/Framework.java @@ -24,6 +24,11 @@ import java.lang.annotation.RetentionPolicy; */ public class Framework { + @Retention(RetentionPolicy.SOURCE) + @IntDef({MAP_STYLE_CLEAR, MAP_STYLE_DARK, MAP_STYLE_VEHICLE_CLEAR, MAP_STYLE_VEHICLE_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; @@ -200,6 +205,9 @@ public class Framework 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. diff --git a/android/src/com/mapswithme/maps/MwmActivity.java b/android/src/com/mapswithme/maps/MwmActivity.java index a2e66c7fdf..78aedec69b 100644 --- a/android/src/com/mapswithme/maps/MwmActivity.java +++ b/android/src/com/mapswithme/maps/MwmActivity.java @@ -90,6 +90,7 @@ import com.mapswithme.maps.widget.placepage.PlacePageView.State; import com.mapswithme.util.Animations; import com.mapswithme.util.BottomSheetHelper; import com.mapswithme.util.InputUtils; +import com.mapswithme.util.ThemeSwitcher; import com.mapswithme.util.ThemeUtils; import com.mapswithme.util.UiUtils; import com.mapswithme.util.Utils; @@ -960,7 +961,7 @@ public class MwmActivity extends BaseMwmFragmentActivity mTasks.add(mapTask); intent.removeExtra(EXTRA_TASK); - if (MapFragment.nativeIsEngineCreated() && mMapFragment.isContextCreated()) + if (isMapRendererActive()) runTasks(); // mark intent as consumed @@ -968,10 +969,16 @@ public class MwmActivity extends BaseMwmFragmentActivity } } + private boolean isMapRendererActive() + { + return mMapFragment != null && MapFragment.nativeIsEngineCreated() + && mMapFragment.isContextCreated(); + } + private void addTask(MapTask task) { mTasks.add(task); - if (MapFragment.nativeIsEngineCreated() && mMapFragment.isContextCreated()) + if (isMapRendererActive()) runTasks(); } @@ -1740,6 +1747,13 @@ public class MwmActivity extends BaseMwmFragmentActivity if (mNavigationController != null) mNavigationController.stop(this); updateSearchBar(); + ThemeSwitcher.restart(isMapRendererActive()); + } + + @Override + public void onNavigationStarted() + { + ThemeSwitcher.restart(isMapRendererActive()); } private void updateSearchBar() diff --git a/android/src/com/mapswithme/maps/MwmApplication.java b/android/src/com/mapswithme/maps/MwmApplication.java index 803cb0e518..1053f93fcd 100644 --- a/android/src/com/mapswithme/maps/MwmApplication.java +++ b/android/src/com/mapswithme/maps/MwmApplication.java @@ -188,7 +188,7 @@ public class MwmApplication extends Application initNativeStrings(); BookmarkManager.nativeLoadBookmarks(); TtsPlayer.INSTANCE.init(this); - ThemeSwitcher.restart(); + ThemeSwitcher.restart(false); LocationHelper.INSTANCE.initialize(); RoutingController.get().initialize(); TrafficManager.INSTANCE.initialize(); diff --git a/android/src/com/mapswithme/maps/routing/RoutingController.java b/android/src/com/mapswithme/maps/routing/RoutingController.java index b7944aabd0..0b6dfd17be 100644 --- a/android/src/com/mapswithme/maps/routing/RoutingController.java +++ b/android/src/com/mapswithme/maps/routing/RoutingController.java @@ -29,7 +29,6 @@ import com.mapswithme.util.Config; import com.mapswithme.util.ConnectionState; import com.mapswithme.util.NetworkPolicy; import com.mapswithme.util.StringUtils; -import com.mapswithme.util.ThemeSwitcher; import com.mapswithme.util.Utils; import com.mapswithme.util.concurrency.UiThread; import com.mapswithme.util.log.Logger; @@ -73,6 +72,7 @@ public class RoutingController void onUberInfoReceived(@NonNull UberInfo info); void onUberError(@NonNull Uber.ErrorCode code); void onNavigationCancelled(); + void onNavigationStarted(); /** * @param progress progress to be displayed. @@ -410,10 +410,12 @@ public class RoutingController AlohaHelper.logClick(AlohaHelper.ROUTING_START); setState(State.NAVIGATION); - mContainer.showRoutePlan(false, null); - mContainer.showNavigation(true); - - ThemeSwitcher.restart(); + if (mContainer != null) + { + mContainer.showRoutePlan(false, null); + mContainer.showNavigation(true); + mContainer.onNavigationStarted(); + } Framework.nativeFollowRoute(); LocationHelper.INSTANCE.restart(); @@ -477,7 +479,6 @@ public class RoutingController setBuildState(BuildState.NONE); setState(State.NONE); - ThemeSwitcher.restart(); Framework.nativeCloseRouting(); } @@ -537,6 +538,11 @@ public class RoutingController return mState == State.NAVIGATION; } + public boolean isVehicleNavigation() + { + return isNavigating() && isVehicleRouterType(); + } + public boolean isBuilding() { return mState == State.PREPARE && mBuildState == BuildState.BUILDING; diff --git a/android/src/com/mapswithme/maps/settings/MapPrefsFragment.java b/android/src/com/mapswithme/maps/settings/MapPrefsFragment.java index 0bf31548db..20fdea77cc 100644 --- a/android/src/com/mapswithme/maps/settings/MapPrefsFragment.java +++ b/android/src/com/mapswithme/maps/settings/MapPrefsFragment.java @@ -118,7 +118,7 @@ public class MapPrefsFragment extends BaseXmlSettingsFragment if (!Config.setUiThemeSettings(themeName)) return true; - ThemeSwitcher.restart(); + ThemeSwitcher.restart(false); Statistics.INSTANCE.trackEvent(Statistics.EventName.Settings.MAP_STYLE, Statistics.params().add(Statistics.EventParam.NAME, themeName)); diff --git a/android/src/com/mapswithme/util/Config.java b/android/src/com/mapswithme/util/Config.java index 59e0038f05..03f511bc8a 100644 --- a/android/src/com/mapswithme/util/Config.java +++ b/android/src/com/mapswithme/util/Config.java @@ -1,5 +1,6 @@ package com.mapswithme.util; +import android.support.annotation.NonNull; import android.support.v4.app.DialogFragment; import android.text.TextUtils; import android.text.format.DateUtils; @@ -312,6 +313,7 @@ public final class Config setBool(KEY_MISC_FIRST_START_DIALOG_SEEN); } + @NonNull public static String getCurrentUiTheme() { String res = getString(KEY_MISC_UI_THEME, ThemeUtils.THEME_DEFAULT); @@ -321,15 +323,15 @@ public final class Config return ThemeUtils.THEME_DEFAULT; } - public static void setCurrentUiTheme(String theme) + static void setCurrentUiTheme(@NonNull String theme) { if (getCurrentUiTheme().equals(theme)) return; setString(KEY_MISC_UI_THEME, theme); - ThemeSwitcher.changeMapStyle(theme); } + @NonNull public static String getUiThemeSettings() { String res = getString(KEY_MISC_UI_THEME_SETTINGS, ThemeUtils.THEME_AUTO); diff --git a/android/src/com/mapswithme/util/ThemeSwitcher.java b/android/src/com/mapswithme/util/ThemeSwitcher.java index 334951847d..ff825279d4 100644 --- a/android/src/com/mapswithme/util/ThemeSwitcher.java +++ b/android/src/com/mapswithme/util/ThemeSwitcher.java @@ -2,37 +2,22 @@ package com.mapswithme.util; import android.app.Activity; import android.location.Location; +import android.support.annotation.NonNull; import com.mapswithme.maps.Framework; import com.mapswithme.maps.MwmApplication; import com.mapswithme.maps.downloader.DownloaderStatusIcon; import com.mapswithme.maps.location.LocationHelper; -import com.mapswithme.maps.location.LocationListener; import com.mapswithme.maps.routing.RoutingController; import com.mapswithme.util.concurrency.UiThread; public final class ThemeSwitcher { private static final long CHECK_INTERVAL_MS = 30 * 60 * 1000; + private static boolean sRendererActive = false; - private static final Runnable sCheckProc = new Runnable() + private static final Runnable AUTO_THEME_CHECKER = new Runnable() { - private final LocationListener mLocationListener = new LocationListener.Simple() - { - @Override - public void onLocationUpdated(Location location) - { - LocationHelper.INSTANCE.removeListener(this); - run(); - } - - @Override - public void onLocationError(int errorCode) - { - LocationHelper.INSTANCE.removeListener(this); - } - }; - @Override public void run() { @@ -43,57 +28,90 @@ public final class ThemeSwitcher Location last = LocationHelper.INSTANCE.getSavedLocation(); if (last == null) { - LocationHelper.INSTANCE.addListener(mLocationListener, true); theme = Config.getCurrentUiTheme(); } else { - LocationHelper.INSTANCE.removeListener(mLocationListener); - - boolean day = Framework.nativeIsDayTime(System.currentTimeMillis() / 1000, last.getLatitude(), last.getLongitude()); + boolean day = Framework.nativeIsDayTime(System.currentTimeMillis() / 1000, + last.getLatitude(), last.getLongitude()); theme = (day ? ThemeUtils.THEME_DEFAULT : ThemeUtils.THEME_NIGHT); } } - Config.setCurrentUiTheme(theme); - UiThread.cancelDelayedTasks(sCheckProc); + setThemeAndMapStyle(theme); + UiThread.cancelDelayedTasks(AUTO_THEME_CHECKER); if (ThemeUtils.isAutoTheme()) - UiThread.runLater(sCheckProc, CHECK_INTERVAL_MS); + UiThread.runLater(AUTO_THEME_CHECKER, CHECK_INTERVAL_MS); } }; private 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)}. + * + * @param isRendererActive Indicates whether OpenGL renderer is active or not. Must be + * true only if the map is rendered and visible on the screen + * at this moment, otherwise false. + */ @android.support.annotation.UiThread - public static void restart() + public static void restart(boolean isRendererActive) { + sRendererActive = isRendererActive; String theme = Config.getUiThemeSettings(); if (ThemeUtils.isAutoTheme(theme)) { - sCheckProc.run(); + AUTO_THEME_CHECKER.run(); return; } - UiThread.cancelDelayedTasks(sCheckProc); + UiThread.cancelDelayedTasks(AUTO_THEME_CHECKER); + setThemeAndMapStyle(theme); + } + + private static void setThemeAndMapStyle(@NonNull String theme) + { + String oldTheme = Config.getCurrentUiTheme(); Config.setCurrentUiTheme(theme); + changeMapStyle(theme, oldTheme); } @android.support.annotation.UiThread - static void changeMapStyle(String theme) + private static void changeMapStyle(@NonNull String newTheme, @NonNull String oldTheme) { - int style = Framework.MAP_STYLE_CLEAR; - if (ThemeUtils.isNightTheme(theme)) - style = Framework.MAP_STYLE_DARK; + @Framework.MapStyle + int style = RoutingController.get().isVehicleNavigation() + ? Framework.MAP_STYLE_VEHICLE_CLEAR : Framework.MAP_STYLE_CLEAR; + if (ThemeUtils.isNightTheme(newTheme)) + style = RoutingController.get().isVehicleNavigation() + ? Framework.MAP_STYLE_VEHICLE_DARK : Framework.MAP_STYLE_DARK; - // Activity and drape engine will be recreated so we have to mark new map style. - // Changes will be applied in process of recreation. - Framework.nativeMarkMapStyle(style); + if (!newTheme.equals(oldTheme)) + { + // Activity and drape engine will be recreated so we have to mark new map style. + // Changes will be applied in process of recreation. + Framework.nativeMarkMapStyle(style); - DownloaderStatusIcon.clearCache(); + DownloaderStatusIcon.clearCache(); - Activity a = MwmApplication.backgroundTracker().getTopActivity(); - if (a != null && !a.isFinishing()) - a.recreate(); + Activity a = MwmApplication.backgroundTracker().getTopActivity(); + if (a != null && !a.isFinishing()) + a.recreate(); + } + else + { + // If the UI theme is not changed we just need to change the map style if needed. + int currentStyle = Framework.nativeGetMapStyle(); + if (currentStyle == style) + return; + + if (sRendererActive) + Framework.nativeSetMapStyle(style); + else + Framework.nativeMarkMapStyle(style); + } } }