From a4ba4213e0a6aa9515ffddb1e6cfb64d857825fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 13 Dec 2018 12:40:40 +0100 Subject: [android] register compass sensor listener only if provided data is consumed by the location layer or location camera (cherry picked from commit 1d410c9) --- .../mapbox/mapboxsdk/location/CompassEngine.java | 6 + .../mapbox/mapboxsdk/location/CompassListener.java | 2 +- .../location/LocationCameraController.java | 5 + .../mapboxsdk/location/LocationComponent.java | 104 ++++++++-- .../location/LocationComponentCompassEngine.java | 26 ++- .../location/LocationLayerController.java | 6 +- .../mapboxsdk/location/CompassEngineTest.java | 25 +++ .../mapboxsdk/location/LocationComponentTest.kt | 214 +++++++++++++++++++++ 8 files changed, 363 insertions(+), 25 deletions(-) create mode 100644 platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/CompassEngine.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/CompassEngine.java index 3691bdc0ea..33efa06226 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/CompassEngine.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/CompassEngine.java @@ -55,11 +55,17 @@ public interface CompassEngine { /** * Lifecycle method that can be used for adding or releasing resources. + * + * @deprecated Use {@link #addCompassListener(CompassListener)} */ + @Deprecated void onStart(); /** * Lifecycle method that can be used for adding or releasing resources. + * + * @deprecated Use {@link #removeCompassListener(CompassListener)} */ + @Deprecated void onStop(); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/CompassListener.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/CompassListener.java index 3e5eb7f258..c44218a1d1 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/CompassListener.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/CompassListener.java @@ -7,7 +7,7 @@ public interface CompassListener { /** * Callback's invoked when a new compass update occurs. You can listen into the compass updates - * using {@link LocationComponent#addCompassListener(CompassListener)} and implementing these + * using {@link CompassEngine#addCompassListener(CompassListener)} and implementing these * callbacks. Note that this interface is also used internally to to update the UI chevron/arrow. * * @param userHeading the new compass heading diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java index e3194df009..340ee3d0f2 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java @@ -164,6 +164,11 @@ final class LocationCameraController implements MapboxAnimator.OnCameraAnimation } } + boolean isConsumingCompass() { + return cameraMode == CameraMode.TRACKING_COMPASS + || cameraMode == CameraMode.NONE_COMPASS; + } + private boolean isLocationTracking() { return cameraMode == CameraMode.TRACKING || cameraMode == CameraMode.TRACKING_COMPASS diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java index 9118f926f3..a1d201c950 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java @@ -26,6 +26,8 @@ import com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraIdleListener; import com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveListener; import com.mapbox.mapboxsdk.maps.MapboxMap.OnMapClickListener; +import org.jetbrains.annotations.NotNull; + import java.util.concurrent.CopyOnWriteArrayList; import static android.Manifest.permission.ACCESS_COARSE_LOCATION; @@ -116,6 +118,11 @@ public final class LocationComponent { */ private boolean isLayerReady; + /** + * Indicates whether we are listening for compass updates. + */ + private boolean isListeningToCompass; + private StaleStateManager staleStateManager; private final CopyOnWriteArrayList onLocationStaleListeners = new CopyOnWriteArrayList<>(); @@ -135,6 +142,21 @@ public final class LocationComponent { this.mapboxMap = mapboxMap; } + public LocationComponent(@NotNull MapboxMap mapboxMap, @NotNull LocationEngine locationEngine, + @NotNull LocationLayerController locationLayerController, + @NotNull LocationCameraController locationCameraController, + @NotNull LocationAnimatorCoordinator locationAnimatorCoordinator, + @NotNull StaleStateManager staleStateManager, @NotNull CompassEngine compassEngine) { + this.mapboxMap = mapboxMap; + this.locationEngine = locationEngine; + this.locationLayerController = locationLayerController; + this.locationCameraController = locationCameraController; + this.locationAnimatorCoordinator = locationAnimatorCoordinator; + this.staleStateManager = staleStateManager; + this.compassEngine = compassEngine; + isInitialized = true; + } + /** * This method initializes the component and needs to be called before any other operations are performed. * Afterwards, you can manage component's visibility by {@link #setLocationComponentEnabled(boolean)}. @@ -276,6 +298,7 @@ public final class LocationComponent { locationCameraController.setCameraMode(cameraMode); boolean isGpsNorth = cameraMode == CameraMode.TRACKING_GPS_NORTH; locationAnimatorCoordinator.resetAllCameraAnimations(mapboxMap.getCameraPosition(), isGpsNorth); + updateCompassListenerState(true); } /** @@ -302,6 +325,7 @@ public final class LocationComponent { public void setRenderMode(@RenderMode.Mode int renderMode) { locationLayerController.setRenderMode(renderMode); updateLayerOffsets(true); + updateCompassListenerState(true); } /** @@ -518,10 +542,12 @@ public final class LocationComponent { * * @param compassEngine to be used */ - public void setCompassEngine(@NonNull CompassEngine compassEngine) { - this.compassEngine.removeCompassListener(compassListener); + public void setCompassEngine(@Nullable CompassEngine compassEngine) { + if (this.compassEngine != null) { + updateCompassListenerState(false); + } this.compassEngine = compassEngine; - compassEngine.addCompassListener(compassListener); + updateCompassListenerState(true); } /** @@ -529,7 +555,7 @@ public final class LocationComponent { * * @return compass engine currently being used */ - @NonNull + @Nullable public CompassEngine getCompassEngine() { return compassEngine; } @@ -555,9 +581,11 @@ public final class LocationComponent { * The last known accuracy of the compass sensor, one of SensorManager.SENSOR_STATUS_* * * @return the last know compass accuracy bearing + * @deprecated Use {@link #getCompassEngine()} */ + @Deprecated public float getLastKnownCompassAccuracyStatus() { - return compassEngine.getLastAccuracySensorStatus(); + return compassEngine != null ? compassEngine.getLastAccuracySensorStatus() : 0; } /** @@ -566,9 +594,13 @@ public final class LocationComponent { * * @param compassListener a {@link CompassListener} for listening into compass heading and * accuracy changes + * @deprecated Use {@link #getCompassEngine()} */ + @Deprecated public void addCompassListener(@NonNull CompassListener compassListener) { - compassEngine.addCompassListener(compassListener); + if (compassEngine != null) { + compassEngine.addCompassListener(compassListener); + } } /** @@ -576,9 +608,13 @@ public final class LocationComponent { * * @param compassListener the {@link CompassListener} which you'd like to remove from the listener * list. + * @deprecated Use {@link #getCompassEngine()} */ + @Deprecated public void removeCompassListener(@NonNull CompassListener compassListener) { - compassEngine.removeCompassListener(compassListener); + if (compassEngine != null) { + compassEngine.removeCompassListener(compassListener); + } } /** @@ -714,7 +750,6 @@ public final class LocationComponent { if (options.enableStaleState()) { staleStateManager.onStart(); } - compassEngine.onStart(); } if (isEnabled) { @@ -726,6 +761,7 @@ public final class LocationComponent { } setCameraMode(locationCameraController.getCameraMode()); setLastLocation(); + updateCompassListenerState(true); setLastCompassHeading(); } } @@ -738,7 +774,9 @@ public final class LocationComponent { isLayerReady = false; locationLayerController.hide(); staleStateManager.onStop(); - compassEngine.onStop(); + if (compassEngine != null) { + updateCompassListenerState(false); + } locationAnimatorCoordinator.cancelAllAnimations(); if (locationEngine != null) { if (usingInternalLocationEngine) { @@ -775,8 +813,9 @@ public final class LocationComponent { WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); - compassEngine = new LocationComponentCompassEngine(windowManager, sensorManager); - compassEngine.addCompassListener(compassListener); + if (windowManager != null && sensorManager != null) { + compassEngine = new LocationComponentCompassEngine(windowManager, sensorManager); + } staleStateManager = new StaleStateManager(onLocationStaleListener, options); updateMapWithOptions(options); @@ -804,6 +843,38 @@ public final class LocationComponent { locationEngine.activate(); } + private void updateCompassListenerState(boolean canListen) { + if (compassEngine != null) { + if (!canListen) { + // We shouldn't listen, simply unregistering + removeCompassListener(compassEngine); + return; + } + + if (!isInitialized || !isComponentStarted || !isEnabled) { + return; + } + + if (locationCameraController.isConsumingCompass() || locationLayerController.isConsumingCompass()) { + // If we have a consumer, and not yet listening, then start listening + if (!isListeningToCompass) { + isListeningToCompass = true; + compassEngine.addCompassListener(compassListener); + } + } else { + // If we have no consumers, stop listening + removeCompassListener(compassEngine); + } + } + } + + private void removeCompassListener(@NonNull CompassEngine engine) { + if (isListeningToCompass) { + isListeningToCompass = false; + engine.removeCompassListener(compassListener); + } + } + private void enableLocationComponent() { isEnabled = true; onLocationLayerStart(); @@ -815,9 +886,12 @@ public final class LocationComponent { } private void updateMapWithOptions(final LocationComponentOptions options) { - mapboxMap.setPadding( - options.padding()[0], options.padding()[1], options.padding()[2], options.padding()[3] - ); + int[] padding = options.padding(); + if (padding != null) { + mapboxMap.setPadding( + padding[0], padding[1], padding[2], padding[3] + ); + } mapboxMap.setMaxZoomPreference(options.maxZoom()); mapboxMap.setMinZoomPreference(options.minZoom()); @@ -869,7 +943,7 @@ public final class LocationComponent { } private void setLastCompassHeading() { - updateCompassHeading(compassEngine.getLastHeading()); + updateCompassHeading(compassEngine != null ? compassEngine.getLastHeading() : 0); } @SuppressLint("MissingPermission") diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentCompassEngine.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentCompassEngine.java index 989404d308..6db307369a 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentCompassEngine.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentCompassEngine.java @@ -10,6 +10,8 @@ import android.support.annotation.Nullable; import android.view.Surface; import android.view.WindowManager; +import com.mapbox.mapboxsdk.log.Logger; + import java.util.ArrayList; import java.util.List; @@ -21,15 +23,18 @@ import timber.log.Timber; */ class LocationComponentCompassEngine implements CompassEngine, SensorEventListener { + private static final String TAG = "Mbgl-LocationComponentCompassEngine"; + // The rate sensor events will be delivered at. As the Android documentation states, this is only // a hint to the system and the events might actually be received faster or slower then this // specified rate. Since the minimum Android API levels about 9, we are able to set this value // ourselves rather than using one of the provided constants which deliver updates too quickly for // our use case. The default is set to 100ms - private static final int SENSOR_DELAY_MICROS = 100 * 1000; + static final int SENSOR_DELAY_MICROS = 100 * 1000; // Filtering coefficient 0 < ALPHA < 1 private static final float ALPHA = 0.45f; + @NonNull private final WindowManager windowManager; private final SensorManager sensorManager; private final List compassListeners = new ArrayList<>(); @@ -56,7 +61,7 @@ class LocationComponentCompassEngine implements CompassEngine, SensorEventListen * Construct a new instance of the this class. A internal compass listeners needed to separate it * from the cleared list of public listeners. */ - LocationComponentCompassEngine(WindowManager windowManager, SensorManager sensorManager) { + LocationComponentCompassEngine(@NonNull WindowManager windowManager, @NonNull SensorManager sensorManager) { this.windowManager = windowManager; this.sensorManager = sensorManager; compassSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR); @@ -75,7 +80,7 @@ class LocationComponentCompassEngine implements CompassEngine, SensorEventListen @Override public void addCompassListener(@NonNull CompassListener compassListener) { if (compassListeners.isEmpty()) { - onStart(); + registerSensorListeners(); } compassListeners.add(compassListener); } @@ -84,7 +89,7 @@ class LocationComponentCompassEngine implements CompassEngine, SensorEventListen public void removeCompassListener(@NonNull CompassListener compassListener) { compassListeners.remove(compassListener); if (compassListeners.isEmpty()) { - onStop(); + unregisterSensorListeners(); } } @@ -100,12 +105,16 @@ class LocationComponentCompassEngine implements CompassEngine, SensorEventListen @Override public void onStart() { - registerSensorListeners(); + if (!compassListeners.isEmpty()) { + registerSensorListeners(); + } } @Override public void onStop() { - unregisterSensorListeners(); + if (!compassListeners.isEmpty()) { + unregisterSensorListeners(); + } } @Override @@ -116,7 +125,7 @@ class LocationComponentCompassEngine implements CompassEngine, SensorEventListen return; } if (lastAccuracySensorStatus == SensorManager.SENSOR_STATUS_UNRELIABLE) { - Timber.d("Compass sensor is unreliable, device calibration is needed."); + Logger.d(TAG, "Compass sensor is unreliable, device calibration is needed."); return; } if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) { @@ -233,7 +242,8 @@ class LocationComponentCompassEngine implements CompassEngine, SensorEventListen * @param smoothedValues array of float, that contains previous state * @return float filtered array of float */ - private float[] lowPassFilter(float[] newValues, float[] smoothedValues) { + @NonNull + private float[] lowPassFilter(@NonNull float[] newValues, @Nullable float[] smoothedValues) { if (smoothedValues == null) { return newValues; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationLayerController.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationLayerController.java index da3144eea1..fc4dd1d872 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationLayerController.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationLayerController.java @@ -11,8 +11,8 @@ import com.google.gson.JsonObject; import com.mapbox.geojson.Feature; import com.mapbox.geojson.Point; import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.location.modes.RenderMode; +import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.style.layers.Layer; import com.mapbox.mapboxsdk.style.layers.SymbolLayer; import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; @@ -192,6 +192,10 @@ final class LocationLayerController implements MapboxAnimator.OnLayerAnimationsV return isHidden; } + boolean isConsumingCompass() { + return renderMode == RenderMode.COMPASS; + } + private void setLayerVisibility(String layerId, boolean visible) { Layer layer = mapboxMap.getLayer(layerId); if (layer != null) { diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/CompassEngineTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/CompassEngineTest.java index bc64379263..bebd828118 100644 --- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/CompassEngineTest.java +++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/CompassEngineTest.java @@ -1,6 +1,7 @@ package com.mapbox.mapboxsdk.location; import android.hardware.Sensor; +import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.view.WindowManager; @@ -10,7 +11,10 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import static com.mapbox.mapboxsdk.location.LocationComponentCompassEngine.SENSOR_DELAY_MICROS; import static junit.framework.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -27,8 +31,15 @@ public class CompassEngineTest { @Mock private SensorManager sensorManager; + @Mock + private Sensor compassSensor; + + @Mock + private CompassListener compassListener; + @Before public void setUp() throws Exception { + when(sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR)).thenReturn(compassSensor); compassEngine = new LocationComponentCompassEngine(windowManager, sensorManager); } @@ -61,4 +72,18 @@ public class CompassEngineTest { verify(sensorManager, times(1)).getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); } + + @Test + public void listener_registerOnAdd() { + compassEngine.addCompassListener(compassListener); + verify(sensorManager) + .registerListener(any(SensorEventListener.class), eq(compassSensor), eq(SENSOR_DELAY_MICROS)); + } + + @Test + public void listener_unregisterOnRemove() { + compassEngine.addCompassListener(compassListener); + compassEngine.removeCompassListener(compassListener); + verify(sensorManager).unregisterListener(any(SensorEventListener.class), eq(compassSensor)); + } } diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt new file mode 100644 index 0000000000..5879b8184f --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt @@ -0,0 +1,214 @@ +package com.mapbox.mapboxsdk.location + +import android.content.Context +import com.mapbox.android.core.location.LocationEngine +import com.mapbox.mapboxsdk.camera.CameraPosition +import com.mapbox.mapboxsdk.location.modes.CameraMode +import com.mapbox.mapboxsdk.location.modes.RenderMode +import com.mapbox.mapboxsdk.maps.MapboxMap +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.* +import org.mockito.MockitoAnnotations +import org.robolectric.RobolectricTestRunner + +@RunWith(RobolectricTestRunner::class) +class LocationComponentTest { + private lateinit var locationComponent: LocationComponent + + @Mock + private lateinit var locationComponentOptions: LocationComponentOptions + + @Mock + private lateinit var mapboxMap: MapboxMap + + @Mock + private lateinit var context: Context + + @Mock + private lateinit var locationEngine: LocationEngine + + @Mock + private lateinit var compassEngine: CompassEngine + + @Mock + private lateinit var locationLayerController: LocationLayerController + + @Mock + private lateinit var locationCameraController: LocationCameraController + + @Mock + private lateinit var locationAnimatorCoordinator: LocationAnimatorCoordinator + + @Mock + private lateinit var staleStateManager: StaleStateManager + + @Before + fun before() { + MockitoAnnotations.initMocks(this) + locationComponent = LocationComponent(mapboxMap, locationEngine, locationLayerController, + locationCameraController, locationAnimatorCoordinator, staleStateManager, compassEngine) + } + + @Test + fun compass_listenWhenConsumedByNoneCamera() { + locationComponent.activateLocationComponent(context, locationEngine, locationComponentOptions) + locationComponent.onStart() + locationComponent.isLocationComponentEnabled = true + `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) + + `when`(locationCameraController.isConsumingCompass).thenReturn(true) + locationComponent.cameraMode = CameraMode.NONE_COMPASS + verify(compassEngine).addCompassListener(any(CompassListener::class.java)) + } + + @Test + fun compass_listenWhenConsumedByTrackingCamera() { + locationComponent.activateLocationComponent(context, locationEngine, locationComponentOptions) + locationComponent.onStart() + locationComponent.isLocationComponentEnabled = true + `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) + + `when`(locationCameraController.isConsumingCompass).thenReturn(true) + locationComponent.cameraMode = CameraMode.TRACKING_COMPASS + verify(compassEngine).addCompassListener(any(CompassListener::class.java)) + } + + @Test + fun compass_listenWhenConsumedByLayer() { + locationComponent.activateLocationComponent(context, locationEngine, locationComponentOptions) + locationComponent.onStart() + locationComponent.isLocationComponentEnabled = true + `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) + + `when`(locationLayerController.isConsumingCompass).thenReturn(true) + locationComponent.renderMode = RenderMode.COMPASS + verify(compassEngine).addCompassListener(any(CompassListener::class.java)) + } + + @Test + fun compass_notListenWhenNotConsumed() { + locationComponent.activateLocationComponent(context, locationEngine, locationComponentOptions) + locationComponent.onStart() + locationComponent.isLocationComponentEnabled = true + `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) + + `when`(locationLayerController.isConsumingCompass).thenReturn(false) + `when`(locationCameraController.isConsumingCompass).thenReturn(false) + locationComponent.renderMode = RenderMode.GPS + locationComponent.renderMode = RenderMode.NORMAL + locationComponent.cameraMode = CameraMode.TRACKING + locationComponent.cameraMode = CameraMode.NONE + locationComponent.cameraMode = CameraMode.NONE_GPS + locationComponent.cameraMode = CameraMode.TRACKING_GPS + locationComponent.cameraMode = CameraMode.TRACKING_GPS_NORTH + verify(compassEngine, never()).addCompassListener(any(CompassListener::class.java)) + } + + @Test + fun compass_removeListenerOnChange() { + locationComponent.activateLocationComponent(context, locationEngine, locationComponentOptions) + locationComponent.onStart() + locationComponent.isLocationComponentEnabled = true + `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) + + `when`(locationLayerController.isConsumingCompass).thenReturn(true) + locationComponent.renderMode = RenderMode.COMPASS + `when`(locationLayerController.isConsumingCompass).thenReturn(false) + locationComponent.renderMode = RenderMode.NORMAL + verify(compassEngine).removeCompassListener(any(CompassListener::class.java)) + } + + @Test + fun compass_removeListenerOnStop() { + locationComponent.activateLocationComponent(context, locationEngine, locationComponentOptions) + locationComponent.onStart() + locationComponent.isLocationComponentEnabled = true + `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) + + `when`(locationLayerController.isConsumingCompass).thenReturn(true) + locationComponent.renderMode = RenderMode.COMPASS + locationComponent.onStop() + verify(compassEngine).removeCompassListener(any(CompassListener::class.java)) + } + + @Test + fun compass_reAddListenerOnStart() { + locationComponent.activateLocationComponent(context, locationEngine, locationComponentOptions) + locationComponent.onStart() + locationComponent.isLocationComponentEnabled = true + `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) + + `when`(locationLayerController.isConsumingCompass).thenReturn(true) + locationComponent.renderMode = RenderMode.COMPASS + locationComponent.onStop() + locationComponent.onStart() + verify(compassEngine, times(2)).addCompassListener(any(CompassListener::class.java)) + } + + @Test + fun compass_removeListenerOnStyleStartLoad() { + locationComponent.activateLocationComponent(context, locationEngine, locationComponentOptions) + locationComponent.onStart() + locationComponent.isLocationComponentEnabled = true + `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) + + `when`(locationLayerController.isConsumingCompass).thenReturn(true) + locationComponent.renderMode = RenderMode.COMPASS + locationComponent.onStartLoadingMap() + verify(compassEngine).removeCompassListener(any(CompassListener::class.java)) + } + + @Test + fun compass_reAddListenerOnStyleLoadFinished() { + locationComponent.activateLocationComponent(context, locationEngine, locationComponentOptions) + locationComponent.onStart() + locationComponent.isLocationComponentEnabled = true + `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) + + `when`(locationLayerController.isConsumingCompass).thenReturn(true) + locationComponent.renderMode = RenderMode.COMPASS + locationComponent.onStartLoadingMap() + locationComponent.onFinishLoadingStyle() + verify(compassEngine, times(2)).addCompassListener(any(CompassListener::class.java)) + } + + @Test + fun compass_reAddListenerOnlyWhenEnabled() { + locationComponent.activateLocationComponent(context, locationEngine, locationComponentOptions) + locationComponent.onStart() + locationComponent.isLocationComponentEnabled = true + `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) + + `when`(locationLayerController.isConsumingCompass).thenReturn(true) + locationComponent.renderMode = RenderMode.COMPASS + locationComponent.isLocationComponentEnabled = false + locationComponent.onStartLoadingMap() + locationComponent.onFinishLoadingStyle() + verify(compassEngine).addCompassListener(any(CompassListener::class.java)) + } + + @Test + fun compass_notAdListenerWhenDisabled() { + locationComponent.activateLocationComponent(context, locationEngine, locationComponentOptions) + locationComponent.onStart() + `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) + + `when`(locationLayerController.isConsumingCompass).thenReturn(true) + locationComponent.renderMode = RenderMode.COMPASS + verify(compassEngine, never()).addCompassListener(any(CompassListener::class.java)) + } + + @Test + fun compass_notAdListenerWhenStopped() { + locationComponent.activateLocationComponent(context, locationEngine, locationComponentOptions) + locationComponent.isLocationComponentEnabled = true + `when`(mapboxMap.cameraPosition).thenReturn(CameraPosition.DEFAULT) + + `when`(locationLayerController.isConsumingCompass).thenReturn(true) + locationComponent.renderMode = RenderMode.COMPASS + verify(compassEngine, never()).addCompassListener(any(CompassListener::class.java)) + } +} \ No newline at end of file -- cgit v1.2.1