From 6122934617caab37bc4c164453c2ea122f8ea323 Mon Sep 17 00:00:00 2001 From: Tobrun Van Nuland Date: Thu, 13 Jul 2017 14:35:59 +0200 Subject: [PATCH] [android] - deprecate MapChange and provide dedicated callback methods --- .../annotations/MarkerViewManager.java | 8 +- .../mapboxsdk/maps/AnnotationManager.java | 6 +- .../mapboxsdk/maps/MapChangeDispatcher.java | 215 ++++++++++ .../com/mapbox/mapboxsdk/maps/MapView.java | 388 +++++++++++++++++- .../com/mapbox/mapboxsdk/maps/MapboxMap.java | 21 +- .../mapbox/mapboxsdk/maps/NativeMapView.java | 71 +++- .../com/mapbox/mapboxsdk/maps/Transform.java | 38 +- .../mapboxsdk/maps/AnnotationManagerTest.java | 4 +- .../maps/MapChangeDispatcherTest.java | 200 +++++++++ .../annotation/BulkMarkerActivity.java | 12 +- .../annotation/MarkerViewActivity.java | 26 +- .../activity/maplayout/MapChangeActivity.java | 106 +++-- platform/android/src/native_map_view.cpp | 168 ++++++-- platform/android/src/native_map_view.hpp | 5 +- 14 files changed, 1113 insertions(+), 155 deletions(-) create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapChangeDispatcher.java create mode 100644 platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapChangeDispatcherTest.java diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java index dce6f6b2777..9aceb88b416 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java @@ -15,7 +15,6 @@ import com.mapbox.mapboxsdk.R; import com.mapbox.mapboxsdk.constants.MapboxConstants; -import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.utils.AnimatorUtils; @@ -31,7 +30,7 @@ * This class is responsible for managing a {@link MarkerView} item. *

*/ -public class MarkerViewManager implements MapView.OnMapChangedListener { +public class MarkerViewManager { private final ViewGroup markerViewContainer; private final ViewTreeObserver.OnPreDrawListener markerViewPreDrawObserver = @@ -72,9 +71,8 @@ public void bind(MapboxMap mapboxMap) { this.mapboxMap = mapboxMap; } - @Override - public void onMapChanged(@MapView.MapChange int change) { - if (isWaitingForRenderInvoke && change == MapView.DID_FINISH_RENDERING_FRAME_FULLY_RENDERED) { + public void onDidFinishRenderingFrameFully() { + if (isWaitingForRenderInvoke) { isWaitingForRenderInvoke = false; invalidateViewMarkersInVisibleRegion(); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java index 7eec8710a72..7f4f5e50b36 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java @@ -59,7 +59,7 @@ class AnnotationManager { private Polygons polygons; private Polylines polylines; - AnnotationManager(NativeMapView view, MapView mapView, LongSparseArray annotationsArray, + AnnotationManager(MapView mapView, LongSparseArray annotationsArray, MarkerViewManager markerViewManager, IconManager iconManager, Annotations annotations, Markers markers, Polygons polygons, Polylines polylines) { this.mapView = mapView; @@ -70,10 +70,6 @@ class AnnotationManager { this.markers = markers; this.polygons = polygons; this.polylines = polylines; - if (view != null) { - // null checking needed for unit tests - view.addOnMapChangedListener(markerViewManager); - } } // TODO refactor MapboxMap out for Projection and Transform diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapChangeDispatcher.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapChangeDispatcher.java new file mode 100644 index 00000000000..57965972878 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapChangeDispatcher.java @@ -0,0 +1,215 @@ +package com.mapbox.mapboxsdk.maps; + +import java.util.concurrent.CopyOnWriteArrayList; + +import timber.log.Timber; + +/* + * Class responsible for forwarding map change events emitted by core. + *

+ * Events are dispatched to end-user defined callbacks and MapView.MapChangeResultHandler. + *

+ *

+ * This class is responsible for managing the deprecated MapView.OnMapChangeListener API. + *

+ */ +class MapChangeDispatcher { + + // Support deprecated API + private final CopyOnWriteArrayList onMapChangedListeners = new CopyOnWriteArrayList<>(); + + // End-user callbacks + private MapView.OnCameraWillChangeListener onCameraWillChangeListener; + private MapView.OnCameraIsChangingListener onCameraIsChangingListener; + private MapView.OnCameraDidChangeListener onCameraDidChangeListener; + private MapView.OnWillStartLoadingMapListener onWillStartLoadingMapListener; + private MapView.OnDidFinishLoadingMapListener onDidFinishLoadingMapListener; + private MapView.OnDidFailLoadingMapListener onDidFailLoadingMapListener; + private MapView.OnWillStartRenderingFrameListener onWillStartRenderingFrameListener; + private MapView.OnDidFinishRenderingFrameListener onDidFinishRenderingFrameListener; + private MapView.OnWillStartRenderingMapListener onWillStartRenderingMapListener; + private MapView.OnDidFinishRenderingMapListener onDidFinishRenderingMapListener; + private MapView.OnDidFinishLoadingStyleListener onDidFinishLoadingStyleListener; + private MapView.OnSourceChangedListener onSourceChangedListener; + + // Internal components callback + private MapView.MapChangeResultHandler mapChangeResultHandler; + + /* + * Binds the result handler to notify internal components about map change events. + */ + void bind(MapView.MapChangeResultHandler mapChangeResultHandler) { + this.mapChangeResultHandler = mapChangeResultHandler; + } + + void setOnCameraWillChangeListener(MapView.OnCameraWillChangeListener listener) { + this.onCameraWillChangeListener = listener; + } + + void setOnCameraIsChangingListener(MapView.OnCameraIsChangingListener listener) { + this.onCameraIsChangingListener = listener; + } + + void setOnCameraDidChangeListener(MapView.OnCameraDidChangeListener listener) { + this.onCameraDidChangeListener = listener; + } + + void setOnWillStartLoadingMapListener(MapView.OnWillStartLoadingMapListener listener) { + this.onWillStartLoadingMapListener = listener; + } + + void setOnDidFinishLoadingMapListener(MapView.OnDidFinishLoadingMapListener listener) { + this.onDidFinishLoadingMapListener = listener; + } + + void setOnDidFailLoadingMapListener(MapView.OnDidFailLoadingMapListener listener) { + this.onDidFailLoadingMapListener = listener; + } + + void setOnWillStartRenderingFrameListener(MapView.OnWillStartRenderingFrameListener listener) { + this.onWillStartRenderingFrameListener = listener; + } + + void setOnDidFinishRenderingFrameListener(MapView.OnDidFinishRenderingFrameListener listener) { + this.onDidFinishRenderingFrameListener = listener; + } + + void setOnWillStartRenderingMapListener(MapView.OnWillStartRenderingMapListener listener) { + this.onWillStartRenderingMapListener = listener; + } + + void setOnDidFinishRenderingMapListener(MapView.OnDidFinishRenderingMapListener listener) { + this.onDidFinishRenderingMapListener = listener; + } + + void setOnDidFinishLoadingStyleListener(MapView.OnDidFinishLoadingStyleListener listener) { + onDidFinishLoadingStyleListener = listener; + } + + void setOnSourceChangedListener(MapView.OnSourceChangedListener listener) { + onSourceChangedListener = listener; + } + + void onCameraWillChange(boolean animated) { + if (onCameraWillChangeListener != null) { + onCameraWillChangeListener.onCameraWillChange(animated); + } + onMapChange(animated ? MapView.REGION_WILL_CHANGE_ANIMATED : MapView.REGION_WILL_CHANGE); + } + + void onCameraIsChanging() { + if (onCameraIsChangingListener != null) { + onCameraIsChangingListener.onCameraIsChanging(); + } + if (mapChangeResultHandler != null) { + mapChangeResultHandler.onCameraIsChanging(); + } + onMapChange(MapView.REGION_IS_CHANGING); + } + + void onCameraDidChange(boolean animated) { + if (onCameraDidChangeListener != null) { + onCameraDidChangeListener.onCameraDidChange(animated); + } + if (mapChangeResultHandler != null) { + mapChangeResultHandler.onCameraDidChange(animated); + } + onMapChange(animated ? MapView.REGION_DID_CHANGE_ANIMATED : MapView.REGION_DID_CHANGE); + } + + void onWillStartLoadingMap() { + if (onWillStartLoadingMapListener != null) { + onWillStartLoadingMapListener.onWillStartLoadingMap(); + } + onMapChange(MapView.WILL_START_LOADING_MAP); + } + + void onDidFinishLoadingMap() { + if (onDidFinishLoadingMapListener != null) { + onDidFinishLoadingMapListener.onDidFinishLoadingMap(); + } + if (mapChangeResultHandler != null) { + mapChangeResultHandler.onDidFinishLoadingMap(); + } + onMapChange(MapView.DID_FINISH_LOADING_MAP); + } + + void onDidFailLoadingMap(String errorMessage) { + if (onDidFailLoadingMapListener != null) { + onDidFailLoadingMapListener.onDidFailLoadingMap(errorMessage); + } + onMapChange(MapView.DID_FAIL_LOADING_MAP); + } + + void onWillStartRenderingFrame() { + if (onWillStartRenderingFrameListener != null) { + onWillStartRenderingFrameListener.onWillStartRenderingFrame(); + } + onMapChange(MapView.WILL_START_RENDERING_FRAME); + } + + void onDidFinishRenderingFrame(boolean partial) { + if (onDidFinishRenderingFrameListener != null) { + onDidFinishRenderingFrameListener.onDidFinishRenderingFrame(partial); + } + if (mapChangeResultHandler != null) { + mapChangeResultHandler.onDidFinishRenderingFrame(partial); + } + onMapChange(partial ? MapView.DID_FINISH_RENDERING_FRAME : MapView.DID_FINISH_RENDERING_FRAME_FULLY_RENDERED); + } + + void onWillStartRenderingMap() { + if (onWillStartRenderingMapListener != null) { + onWillStartRenderingMapListener.onWillStartRenderingMap(); + } + onMapChange(MapView.WILL_START_RENDERING_MAP); + } + + void onDidFinishRenderingMap(boolean partial) { + if (onDidFinishRenderingMapListener != null) { + onDidFinishRenderingMapListener.onDidFinishRenderingMap(partial); + } + onMapChange(partial ? MapView.DID_FINISH_RENDERING_MAP : MapView.DID_FINISH_RENDERING_MAP_FULLY_RENDERED); + } + + void onDidFinishLoadingStyle() { + if (onDidFinishLoadingStyleListener != null) { + onDidFinishLoadingStyleListener.onDidFinishLoadingStyle(); + } + if (mapChangeResultHandler != null) { + mapChangeResultHandler.onDidFinishLoadingStyle(); + } + onMapChange(MapView.DID_FINISH_LOADING_STYLE); + } + + void onSourceChanged(String id) { + if (onSourceChangedListener != null) { + onSourceChangedListener.onSourceChangedListener(id); + } + onMapChange(MapView.SOURCE_DID_CHANGE); + } + + // + // Deprecated API since 5.2.0 + // + + void onMapChange(int onMapChange) { + if (!onMapChangedListeners.isEmpty()) { + for (MapView.OnMapChangedListener onMapChangedListener : onMapChangedListeners) { + try { + onMapChangedListener.onMapChanged(onMapChange); + } catch (RuntimeException err) { + Timber.e("Exception (%s) in MapView.OnMapChangedListener: %s", err.getClass(), err.getMessage()); + } + } + } + } + + void addOnMapChangedListener(MapView.OnMapChangedListener listener) { + onMapChangedListeners.add(listener); + } + + void removeOnMapChangedListener(MapView.OnMapChangedListener listener) { + onMapChangedListeners.remove(listener); + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java index a0aebfda50a..e4c45a18638 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java @@ -65,7 +65,8 @@ public class MapView extends FrameLayout { private boolean hasSurface; private MapboxMap mapboxMap; - private MapCallback mapCallback; + private MapChangeResultHandler mapCallback; + private MapChangeDispatcher mapChangeDispatcher; private MapGestureDetector mapGestureDetector; private MapKeyListener mapKeyListener; @@ -115,7 +116,7 @@ private void initialise(@NonNull final Context context, @NonNull final MapboxMap setContentDescription(context.getString(R.string.mapbox_mapActionDescription)); // create native Map object - nativeMapView = new NativeMapView(this); + nativeMapView = new NativeMapView(this, mapChangeDispatcher = new MapChangeDispatcher()); // callback for focal point invalidation FocalPointInvalidator focalPoint = new FocalPointInvalidator(compassView); @@ -141,8 +142,8 @@ private void initialise(@NonNull final Context context, @NonNull final MapboxMap Markers markers = new MarkerContainer(nativeMapView, this, annotationsArray, iconManager, markerViewManager); Polygons polygons = new PolygonContainer(nativeMapView, annotationsArray); Polylines polylines = new PolylineContainer(nativeMapView, annotationsArray); - AnnotationManager annotationManager = new AnnotationManager(nativeMapView, this, annotationsArray, - markerViewManager, iconManager, annotations, markers, polygons, polylines); + AnnotationManager annotationManager = new AnnotationManager(this, annotationsArray, markerViewManager, + iconManager, annotations, markers, polygons, polylines); Transform transform = new Transform(nativeMapView, annotationManager.getMarkerViewManager(), trackingSettings, cameraChangeDispatcher); mapboxMap = new MapboxMap(nativeMapView, transform, uiSettings, trackingSettings, myLocationViewSettings, proj, @@ -174,6 +175,9 @@ private void initialise(@NonNull final Context context, @NonNull final MapboxMap // notify Map object about current connectivity state nativeMapView.setReachability(ConnectivityReceiver.instance(context).isConnected(context)); + // bind internal components for map change events + mapChangeDispatcher.bind(mapCallback = new MapChangeResultHandler(mapboxMap)); + // initialise MapboxMap mapboxMap.initialise(context, options); } @@ -202,7 +206,6 @@ public void onCreate(@Nullable Bundle savedInstanceState) { } initialiseDrawingSurface(textureMode); - addOnMapChangedListener(mapCallback = new MapCallback(mapboxMap)); } private void initialiseDrawingSurface(boolean textureMode) { @@ -501,7 +504,7 @@ public void onSurfaceTextureUpdated(SurfaceTexture surface) { if (destroyed) { return; } - mapboxMap.onUpdateRegionChange(); + mapboxMap.onCameraChange(); } } @@ -540,7 +543,14 @@ protected void onVisibilityChanged(@NonNull View changedView, int visibility) { * * @param listener The callback that's invoked on every frame rendered to the map view. * @see MapView#removeOnMapChangedListener(OnMapChangedListener) + * @deprecated use {@link OnCameraWillChangeListener}, {@link OnCameraDidChangeListener}, + * {@link OnCameraIsChangingListener}, {@link OnWillStartLoadingMapListener}, {@link OnDidFinishLoadingMapListener}, + * {@link OnDidFailLoadingMapListener}, {@link OnDidFinishRenderingFrameListener}, + * {@link OnDidFinishRenderingFrameListener}, {@link OnWillStartRenderingMapListener}. + * {@link OnDidFinishRenderingMapListener}, {@link OnDidFinishLoadingStyleListener} and + * {@link OnSourceChangedListener} instead */ + @Deprecated public void addOnMapChangedListener(@Nullable OnMapChangedListener listener) { if (listener != null) { nativeMapView.addOnMapChangedListener(listener); @@ -552,6 +562,12 @@ public void addOnMapChangedListener(@Nullable OnMapChangedListener listener) { * * @param listener The previously added callback to remove. * @see MapView#addOnMapChangedListener(OnMapChangedListener) + * @deprecated use {@link OnCameraWillChangeListener}, {@link OnCameraDidChangeListener}, + * {@link OnCameraIsChangingListener}, {@link OnWillStartLoadingMapListener}, + * {@link OnDidFinishLoadingMapListener}, {@link OnDidFailLoadingMapListener}, + * {@link OnDidFinishRenderingFrameListener}, {@link OnDidFinishRenderingFrameListener}, + * {@link OnWillStartRenderingMapListener}. {@link OnDidFinishRenderingMapListener}, + * {@link OnDidFinishLoadingStyleListener} and {@link OnSourceChangedListener} instead */ public void removeOnMapChangedListener(@Nullable OnMapChangedListener listener) { if (listener != null) { @@ -559,6 +575,114 @@ public void removeOnMapChangedListener(@Nullable OnMapChangedListener listener) } } + /** + * Set a callback that's invoked when the camera region will change. + * + * @param listener The callback that's invoked when the camera region will change + */ + public void setOnCameraWillChangeListener(OnCameraWillChangeListener listener) { + mapChangeDispatcher.setOnCameraWillChangeListener(listener); + } + + /** + * Set a callback that's invoked when the camera is changing. + * + * @param listener The callback that's invoked when the camera is changing + */ + public void setOnCameraIsChangingListener(OnCameraIsChangingListener listener) { + mapChangeDispatcher.setOnCameraIsChangingListener(listener); + } + + /** + * Set a callback that's invoked when the camera region did change. + * + * @param listener The callback that's invoked when the camera region did change + */ + public void setOnCameraDidChangeListener(OnCameraDidChangeListener listener) { + mapChangeDispatcher.setOnCameraDidChangeListener(listener); + } + + /** + * Set a callback that's invoked when the map will start loading. + * + * @param listener The callback that's invoked when the map will start loading + */ + public void setOnWillStartLoadingMapListener(OnWillStartLoadingMapListener listener) { + mapChangeDispatcher.setOnWillStartLoadingMapListener(listener); + } + + /** + * Set a callback that's invoked when the map has finished loading. + * + * @param listener The callback that's invoked when the map has finished loading + */ + public void setOnDidFinishLoadingMapListener(OnDidFinishLoadingMapListener listener) { + mapChangeDispatcher.setOnDidFinishLoadingMapListener(listener); + } + + /** + * Set a callback that's invoked when the map failed to load. + * + * @param listener The callback that's invoked when the map failed to load + */ + public void setOnDidFailLoadingMapListener(OnDidFailLoadingMapListener listener) { + mapChangeDispatcher.setOnDidFailLoadingMapListener(listener); + } + + /** + * Set a callback that's invoked when the map will start rendering a frame. + * + * @param listener The callback that's invoked when the camera will start rendering a frame + */ + public void setOnWillStartRenderingFrameListener(OnWillStartRenderingFrameListener listener) { + mapChangeDispatcher.setOnWillStartRenderingFrameListener(listener); + } + + /** + * Set a callback that's invoked when the map has finished rendering a frame. + * + * @param listener The callback that's invoked when the map has finished rendering a frame + */ + public void setOnDidFinishRenderingFrameListener(OnDidFinishRenderingFrameListener listener) { + mapChangeDispatcher.setOnDidFinishRenderingFrameListener(listener); + } + + /** + * Set a callback that's invoked when the map will start rendering. + * + * @param listener The callback that's invoked when the map will start rendering + */ + public void setOnWillStartRenderingMapListener(OnWillStartRenderingMapListener listener) { + mapChangeDispatcher.setOnWillStartRenderingMapListener(listener); + } + + /** + * Set a callback that's invoked when the map has finished rendering. + * + * @param listener The callback that's invoked when the map has finished rendering + */ + public void setOnDidFinishRenderingMapListener(OnDidFinishRenderingMapListener listener) { + mapChangeDispatcher.setOnDidFinishRenderingMapListener(listener); + } + + /** + * Set a callback that's invoked when the style has finished loading. + * + * @param listener The callback that's invoked when the style has finished loading + */ + public void setOnDidFinishLoadingStyleListener(OnDidFinishLoadingStyleListener listener) { + mapChangeDispatcher.setOnDidFinishLoadingStyleListener(listener); + } + + /** + * Set a callback that's invoked when a map source has changed. + * + * @param listener The callback that's invoked when the source has changed + */ + public void setOnSourceChangedListener(OnSourceChangedListener listener) { + mapChangeDispatcher.setOnSourceChangedListener(listener); + } + /** * Sets a callback object which will be triggered when the {@link MapboxMap} instance is ready to be used. * @@ -587,6 +711,12 @@ void setMapboxMap(MapboxMap mapboxMap) { * Definition of a map change event. * * @see MapView.OnMapChangedListener#onMapChanged(int) + * @deprecated use {@link OnCameraWillChangeListener}, {@link OnCameraDidChangeListener}, + * {@link OnCameraIsChangingListener}, {@link OnWillStartLoadingMapListener}, + * {@link OnDidFinishLoadingMapListener}, {@link OnDidFailLoadingMapListener}, + * {@link OnDidFinishRenderingFrameListener}, {@link OnDidFinishRenderingFrameListener}, + * {@link OnWillStartRenderingMapListener}, {@link OnDidFinishRenderingMapListener}, + * {@link OnDidFinishLoadingStyleListener} and {@link OnSourceChangedListener} instead */ @IntDef( {REGION_WILL_CHANGE, REGION_WILL_CHANGE_ANIMATED, @@ -606,6 +736,7 @@ void setMapboxMap(MapboxMap mapboxMap) { SOURCE_DID_CHANGE }) @Retention(RetentionPolicy.SOURCE) + @Deprecated public @interface MapChange { } @@ -618,7 +749,9 @@ void setMapboxMap(MapboxMap mapboxMap) { * * @see MapChange * @see MapView.OnMapChangedListener + * @deprecated use {@link OnCameraWillChangeListener} instead */ + @Deprecated public static final int REGION_WILL_CHANGE = 0; /** @@ -630,7 +763,9 @@ void setMapboxMap(MapboxMap mapboxMap) { * * @see MapChange * @see MapView.OnMapChangedListener + * @deprecated use {@link OnCameraWillChangeListener} instead */ + @Deprecated public static final int REGION_WILL_CHANGE_ANIMATED = 1; /** @@ -641,7 +776,9 @@ void setMapboxMap(MapboxMap mapboxMap) { * * @see MapChange * @see MapView.OnMapChangedListener + * @deprecated use {@link OnCameraIsChangingListener} instead */ + @Deprecated public static final int REGION_IS_CHANGING = 2; /** @@ -653,7 +790,9 @@ void setMapboxMap(MapboxMap mapboxMap) { * * @see MapChange * @see MapView.OnMapChangedListener + * @deprecated use {@link OnCameraDidChangeListener} instead */ + @Deprecated public static final int REGION_DID_CHANGE = 3; /** @@ -665,7 +804,9 @@ void setMapboxMap(MapboxMap mapboxMap) { * * @see MapChange * @see MapView.OnMapChangedListener + * @deprecated use {@link OnCameraDidChangeListener} instead */ + @Deprecated public static final int REGION_DID_CHANGE_ANIMATED = 4; /** @@ -676,7 +817,9 @@ void setMapboxMap(MapboxMap mapboxMap) { * * @see MapChange * @see MapView.OnMapChangedListener + * @deprecated use {@link OnWillStartLoadingMapListener} instead */ + @Deprecated public static final int WILL_START_LOADING_MAP = 5; /** @@ -687,7 +830,9 @@ void setMapboxMap(MapboxMap mapboxMap) { * * @see MapChange * @see MapView.OnMapChangedListener + * @deprecated use {@link OnDidFinishLoadingMapListener} instead */ + @Deprecated public static final int DID_FINISH_LOADING_MAP = 6; /** @@ -698,7 +843,9 @@ void setMapboxMap(MapboxMap mapboxMap) { * * @see MapChange * @see MapView.OnMapChangedListener + * @deprecated use {@link OnDidFailLoadingMapListener} instead */ + @Deprecated public static final int DID_FAIL_LOADING_MAP = 7; /** @@ -709,7 +856,9 @@ void setMapboxMap(MapboxMap mapboxMap) { * * @see MapChange * @see MapView.OnMapChangedListener + * @deprecated use {@link OnWillStartRenderingFrameListener} instead */ + @Deprecated public static final int WILL_START_RENDERING_FRAME = 8; /** @@ -720,7 +869,9 @@ void setMapboxMap(MapboxMap mapboxMap) { * * @see MapChange * @see MapView.OnMapChangedListener + * @deprecated use {@link OnDidFinishRenderingFrameListener} instead */ + @Deprecated public static final int DID_FINISH_RENDERING_FRAME = 9; /** @@ -731,7 +882,9 @@ void setMapboxMap(MapboxMap mapboxMap) { * * @see MapChange * @see MapView.OnMapChangedListener + * @deprecated use {@link OnDidFinishRenderingFrameListener} instead */ + @Deprecated public static final int DID_FINISH_RENDERING_FRAME_FULLY_RENDERED = 10; /** @@ -742,7 +895,9 @@ void setMapboxMap(MapboxMap mapboxMap) { * * @see MapChange * @see MapView.OnMapChangedListener + * @deprecated use {@link OnWillStartRenderingMapListener} instead */ + @Deprecated public static final int WILL_START_RENDERING_MAP = 11; /** @@ -753,7 +908,9 @@ void setMapboxMap(MapboxMap mapboxMap) { * * @see MapChange * @see MapView.OnMapChangedListener + * @deprecated use {@link OnDidFinishRenderingMapListener} instead */ + @Deprecated public static final int DID_FINISH_RENDERING_MAP = 12; /** @@ -764,7 +921,9 @@ void setMapboxMap(MapboxMap mapboxMap) { * * @see MapChange * @see MapView.OnMapChangedListener + * @deprecated use {@link OnDidFinishLoadingMapListener} instead */ + @Deprecated public static final int DID_FINISH_RENDERING_MAP_FULLY_RENDERED = 13; /** @@ -775,7 +934,9 @@ void setMapboxMap(MapboxMap mapboxMap) { * * @see MapChange * @see MapView.OnMapChangedListener + * @deprecated use {@link OnDidFinishLoadingStyleListener} instead */ + @Deprecated public static final int DID_FINISH_LOADING_STYLE = 14; /** @@ -786,9 +947,176 @@ void setMapboxMap(MapboxMap mapboxMap) { * * @see MapChange * @see MapView.OnMapChangedListener + * @deprecated use {@link OnSourceChangedListener} instead */ + @Deprecated public static final int SOURCE_DID_CHANGE = 15; + /** + * Interface definition for a callback to be invoked when the camera region will change. + *

+ * Register this callback with {@link MapView#setOnCameraWillChangeListener(OnCameraWillChangeListener)} + *

+ */ + public interface OnCameraWillChangeListener { + + /** + * Called when the camera region will change. + */ + void onCameraWillChange(boolean animated); + } + + /** + * Interface definition for a callback to be invoked when the camera is changing. + *

+ * {@link MapView#setOnCameraIsChangingListener(OnCameraIsChangingListener)} + *

+ */ + public interface OnCameraIsChangingListener { + /** + * Called when the camera is changing. + */ + void onCameraIsChanging(); + } + + /** + * Interface definition for a callback to be invoked when the map region did change. + *

+ * {@link MapView#setOnCameraDidChangeListener(OnCameraDidChangeListener)} + *

+ */ + public interface OnCameraDidChangeListener { + /** + * Called when the camera did change. + */ + void onCameraDidChange(boolean animated); + } + + /** + * Interface definition for a callback to be invoked when the map will start loading. + *

+ * {@link MapView#setOnWillStartLoadingMapListener(OnWillStartLoadingMapListener)} + *

+ */ + public interface OnWillStartLoadingMapListener { + /** + * Called when the map will start loading. + */ + void onWillStartLoadingMap(); + } + + /** + * Interface definition for a callback to be invoked when the map finished loading. + *

+ * {@link MapView#setOnDidFinishLoadingMapListener(OnDidFinishLoadingMapListener)} + *

+ */ + public interface OnDidFinishLoadingMapListener { + /** + * Called when the map has finished loading. + */ + void onDidFinishLoadingMap(); + } + + /** + * Interface definition for a callback to be invoked when the map is changing. + *

+ * {@link MapView#setOnDidFailLoadingMapListener(OnDidFailLoadingMapListener)} + *

+ */ + public interface OnDidFailLoadingMapListener { + /** + * Called when the map failed to load. + * + * @param errorMessage The reason why the map failed to load + */ + void onDidFailLoadingMap(String errorMessage); + } + + /** + * Interface definition for a callback to be invoked when the map will start rendering a frame. + *

+ * {@link MapView#setOnWillStartRenderingFrameListener(OnWillStartRenderingFrameListener)} + *

+ */ + public interface OnWillStartRenderingFrameListener { + /** + * Called when the map will start rendering a frame. + */ + void onWillStartRenderingFrame(); + } + + /** + * Interface definition for a callback to be invoked when the map finished rendering a frame. + *

+ * {@link MapView#setOnDidFinishRenderingFrameListener(OnDidFinishRenderingFrameListener)} + *

+ */ + public interface OnDidFinishRenderingFrameListener { + /** + * Called when the map has finished rendering a frame + * + * @param partial true if map is still rendering frames, false if all frames have been rendered + */ + void onDidFinishRenderingFrame(boolean partial); + } + + /** + * Interface definition for a callback to be invoked when the map will start rendering the map. + *

+ * {@link MapView#setOnDidFailLoadingMapListener(OnDidFailLoadingMapListener)} + *

+ */ + public interface OnWillStartRenderingMapListener { + /** + * Called when the map will start rendering. + */ + void onWillStartRenderingMap(); + } + + /** + * Interface definition for a callback to be invoked when the map is changing. + *

+ * {@link MapView#setOnDidFinishRenderingMapListener(OnDidFinishRenderingMapListener)} + *

+ */ + public interface OnDidFinishRenderingMapListener { + /** + * Called when the map has finished rendering. + * + * @param partial true if map is partially rendered, false if fully rendered + */ + void onDidFinishRenderingMap(boolean partial); + } + + /** + * Interface definition for a callback to be invoked when the map has loaded the style. + *

+ * {@link MapView#setOnDidFailLoadingMapListener(OnDidFailLoadingMapListener)} + *

+ */ + public interface OnDidFinishLoadingStyleListener { + /** + * Called when a style has finished loading. + */ + void onDidFinishLoadingStyle(); + } + + /** + * Interface definition for a callback to be invoked when a map source has changed. + *

+ * {@link MapView#setOnDidFailLoadingMapListener(OnDidFailLoadingMapListener)} + *

+ */ + public interface OnSourceChangedListener { + /** + * Called when a map source has changed. + * + * @param id the id of the source that has changed + */ + void onSourceChangedListener(String id); + } + /** * Interface definition for a callback to be invoked when the displayed map view changes. *

@@ -797,6 +1125,12 @@ void setMapboxMap(MapboxMap mapboxMap) { * * @see MapView#addOnMapChangedListener(OnMapChangedListener) * @see MapView.MapChange + * @deprecated use {@link OnCameraWillChangeListener}, {@link OnCameraDidChangeListener}, + * {@link OnCameraIsChangingListener}, {@link OnWillStartLoadingMapListener}, {@link OnDidFinishLoadingMapListener}, + * {@link OnDidFailLoadingMapListener}, {@link OnDidFinishRenderingFrameListener}, + * {@link OnDidFinishRenderingFrameListener},{@link OnWillStartRenderingMapListener}, + * {@link OnDidFinishRenderingMapListener}, {@link OnDidFinishLoadingStyleListener} and + * {@link OnSourceChangedListener} instead */ public interface OnMapChangedListener { /** @@ -917,19 +1251,21 @@ private void setZoom(double zoomLevel, @Nullable PointF focalPoint, @NonNull Tra } } - private static class MapCallback implements OnMapChangedListener { + static class MapChangeResultHandler implements MapView.OnDidFinishLoadingStyleListener, + MapView.OnDidFinishRenderingFrameListener, MapView.OnDidFinishLoadingMapListener, + MapView.OnCameraIsChangingListener, MapView.OnCameraDidChangeListener { private final MapboxMap mapboxMap; private final List onMapReadyCallbackList = new ArrayList<>(); private boolean initialLoad = true; - MapCallback(MapboxMap mapboxMap) { + MapChangeResultHandler(MapboxMap mapboxMap) { this.mapboxMap = mapboxMap; } @Override - public void onMapChanged(@MapChange int change) { - if (change == DID_FINISH_LOADING_STYLE && initialLoad) { + public void onDidFinishLoadingStyle() { + if (initialLoad) { initialLoad = false; new Handler().post(new Runnable() { @Override @@ -939,13 +1275,37 @@ public void run() { mapboxMap.onPostMapReady(); } }); - } else if (change == DID_FINISH_RENDERING_FRAME || change == DID_FINISH_RENDERING_FRAME_FULLY_RENDERED) { - mapboxMap.onUpdateFullyRendered(); - } else if (change == REGION_IS_CHANGING || change == REGION_DID_CHANGE || change == DID_FINISH_LOADING_MAP) { - mapboxMap.onUpdateRegionChange(); } } + @Override + public void onDidFinishRenderingFrame(boolean partial) { + if (partial) { + mapboxMap.onDidFinishRenderingFrame(); + } + mapboxMap.onDidFinishRenderingFrameFully(); + } + + @Override + public void onDidFinishLoadingMap() { + // we require an additional update after the map has finished loading + // in case an end user action hasn't been invoked at that time + mapboxMap.onCameraChange(); + } + + @Override + public void onCameraIsChanging() { + mapboxMap.onCameraChange(); + } + + @Override + public void onCameraDidChange(boolean animated) { + if (animated) { + mapboxMap.onCameraDidChangeAnimated(); + } + mapboxMap.onCameraChange(); + } + private void onMapReady() { if (onMapReadyCallbackList.size() > 0) { // Notify listeners, clear when done diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java index 6233efa966a..3333e38041e 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java @@ -182,23 +182,38 @@ void onPostMapReady() { } /** - * Called when the region is changing or has changed. + * Called when the camera has changed or triggered manually for updating components. */ - void onUpdateRegionChange() { + void onCameraChange() { + Timber.e("OnCamerChange"); trackingSettings.update(); annotationManager.update(); } + /** + * Called when the region did change animated. + */ + void onCameraDidChangeAnimated() { + transform.onCameraDidChangeAnimated(); + } + /** * Called when the map frame is fully rendered. */ - void onUpdateFullyRendered() { + void onDidFinishRenderingFrame() { CameraPosition cameraPosition = transform.invalidateCameraPosition(); if (cameraPosition != null) { uiSettings.update(cameraPosition); } } + /** + * + */ + void onDidFinishRenderingFrameFully() { + annotationManager.getMarkerViewManager().onDidFinishRenderingFrameFully(); + } + // Style /** diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java index a88a11d387d..18f11790f6c 100755 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java @@ -35,7 +35,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; import timber.log.Timber; @@ -57,8 +56,8 @@ final class NativeMapView { // Device density private final float pixelRatio; - // Listeners for Map change events - private CopyOnWriteArrayList onMapChangedListeners; + // Dispatcher for incoming Map change events + private MapChangeDispatcher mapChangeDispatcher; // Listener invoked to return a bitmap of the map private MapboxMap.SnapshotReadyCallback snapshotReadyCallback; @@ -71,14 +70,13 @@ final class NativeMapView { // Constructors // - public NativeMapView(MapView mapView) { + public NativeMapView(MapView mapView, MapChangeDispatcher mapChangeDispatcher) { Context context = mapView.getContext(); fileSource = FileSource.getInstance(context); pixelRatio = context.getResources().getDisplayMetrics().density; - onMapChangedListeners = new CopyOnWriteArrayList<>(); this.mapView = mapView; - + this.mapChangeDispatcher = mapChangeDispatcher; String programCacheDir = context.getCacheDir().getAbsolutePath(); nativeInitialize(this, fileSource, pixelRatio, programCacheDir); } @@ -886,16 +884,53 @@ protected void onInvalidate() { } } - protected void onMapChanged(int rawChange) { - if (onMapChangedListeners != null) { - for (MapView.OnMapChangedListener onMapChangedListener : onMapChangedListeners) { - try { - onMapChangedListener.onMapChanged(rawChange); - } catch (RuntimeException err) { - Timber.e("Exception (%s) in MapView.OnMapChangedListener: %s", err.getClass(), err.getMessage()); - } - } - } + protected void onCameraWillChange(boolean animated) { + mapChangeDispatcher.onCameraWillChange(animated); + } + + protected void onCameraIsChanging() { + Timber.e("Camera is changing"); + mapChangeDispatcher.onCameraIsChanging(); + } + + protected void onCameraDidChange(boolean animated) { + mapChangeDispatcher.onCameraDidChange(animated); + } + + protected void onWillStartLoadingMap() { + mapChangeDispatcher.onWillStartLoadingMap(); + } + + protected void onDidFinishLoadingMap() { + mapChangeDispatcher.onDidFinishLoadingMap(); + } + + protected void onDidFailLoadingMap(String erorMessage) { + mapChangeDispatcher.onDidFailLoadingMap(erorMessage); + } + + protected void onWillStartRenderingFrame() { + mapChangeDispatcher.onWillStartRenderingFrame(); + } + + protected void onDidFinishRenderingFrame(boolean partial) { + mapChangeDispatcher.onDidFinishRenderingFrame(partial); + } + + protected void onWillStartRenderingMap() { + mapChangeDispatcher.onWillStartRenderingMap(); + } + + protected void onDidFinishRenderingMap(boolean partial) { + mapChangeDispatcher.onDidFinishRenderingMap(partial); + } + + protected void onDidFinishLoadingStyle() { + mapChangeDispatcher.onDidFinishLoadingStyle(); + } + + protected void onSourceChanged(String id) { + mapChangeDispatcher.onSourceChanged(id); } protected void onFpsChanged(double fps) { @@ -1130,11 +1165,11 @@ int getHeight() { // void addOnMapChangedListener(@NonNull MapView.OnMapChangedListener listener) { - onMapChangedListeners.add(listener); + mapChangeDispatcher.addOnMapChangedListener(listener); } void removeOnMapChangedListener(@NonNull MapView.OnMapChangedListener listener) { - onMapChangedListeners.remove(listener); + mapChangeDispatcher.removeOnMapChangedListener(listener); } // diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java index d788b7772b5..1282e2a2d06 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java @@ -15,7 +15,6 @@ import timber.log.Timber; -import static com.mapbox.mapboxsdk.maps.MapView.REGION_DID_CHANGE_ANIMATED; import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveStartedListener; /** @@ -25,7 +24,7 @@ * {@link com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraChangeListener}. *

*/ -final class Transform implements MapView.OnMapChangedListener { +final class Transform { private final NativeMapView mapView; private final MarkerViewManager markerViewManager; @@ -34,10 +33,10 @@ final class Transform implements MapView.OnMapChangedListener { private CameraPosition cameraPosition; private MapboxMap.CancelableCallback cameraCancelableCallback; - private MapboxMap.OnCameraChangeListener onCameraChangeListener; private CameraChangeDispatcher cameraChangeDispatcher; + private boolean observeAnimatedCameraChange; Transform(NativeMapView mapView, MarkerViewManager markerViewManager, TrackingSettings trackingSettings, CameraChangeDispatcher cameraChangeDispatcher) { @@ -77,16 +76,15 @@ void updateCameraPosition(@NonNull CameraPosition position) { markerViewManager.setTilt((float) position.tilt); } - @Override - public void onMapChanged(@MapView.MapChange int change) { - if (change == REGION_DID_CHANGE_ANIMATED) { + public void onCameraDidChangeAnimated() { + if (observeAnimatedCameraChange) { + observeAnimatedCameraChange = false; updateCameraPosition(invalidateCameraPosition()); if (cameraCancelableCallback != null) { cameraCancelableCallback.onFinish(); cameraCancelableCallback = null; } cameraChangeDispatcher.onCameraIdle(); - mapView.removeOnMapChangedListener(this); } } @@ -117,7 +115,7 @@ final void easeCamera(MapboxMap mapboxMap, CameraUpdate update, int durationMs, if (callback != null) { cameraCancelableCallback = callback; } - mapView.addOnMapChangedListener(this); + observeAnimatedCameraChange = true; mapView.easeTo(cameraPosition.bearing, cameraPosition.target, durationMs, cameraPosition.tilt, cameraPosition.zoom, easingInterpolator); } @@ -135,7 +133,7 @@ final void animateCamera(MapboxMap mapboxMap, CameraUpdate update, int durationM if (callback != null) { cameraCancelableCallback = callback; } - mapView.addOnMapChangedListener(this); + observeAnimatedCameraChange = true; mapView.flyTo(cameraPosition.bearing, cameraPosition.target, durationMs, cameraPosition.tilt, cameraPosition.zoom); } @@ -226,15 +224,9 @@ void setZoom(double zoom, @NonNull PointF focalPoint) { } void setZoom(double zoom, @NonNull PointF focalPoint, long duration) { - mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() { - @Override - public void onMapChanged(int change) { - if (change == MapView.REGION_DID_CHANGE_ANIMATED) { - cameraChangeDispatcher.onCameraIdle(); - mapView.removeOnMapChangedListener(this); - } - } - }); + if (duration > 0) { + observeAnimatedCameraChange = true; + } mapView.setZoom(zoom, focalPoint, duration); } @@ -327,15 +319,7 @@ void zoomBy(double z, float x, float y) { void moveBy(double offsetX, double offsetY, long duration) { if (duration > 0) { - mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() { - @Override - public void onMapChanged(int change) { - if (change == MapView.REGION_DID_CHANGE_ANIMATED) { - mapView.removeOnMapChangedListener(this); - cameraChangeDispatcher.onCameraIdle(); - } - } - }); + observeAnimatedCameraChange = true; } mapView.moveBy(offsetX, offsetY, duration); } diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/AnnotationManagerTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/AnnotationManagerTest.java index 0d592f9bb37..6e74e85ad0b 100644 --- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/AnnotationManagerTest.java +++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/AnnotationManagerTest.java @@ -32,7 +32,7 @@ public void checksAddAMarker() throws Exception { Markers markers = new MarkerContainer(aNativeMapView, aMapView, annotationsArray, aIconManager, aMarkerViewManager); Polygons polygons = new PolygonContainer(aNativeMapView, annotationsArray); Polylines polylines = new PolylineContainer(aNativeMapView, annotationsArray); - AnnotationManager annotationManager = new AnnotationManager(aNativeMapView, aMapView, annotationsArray, + AnnotationManager annotationManager = new AnnotationManager(aMapView, annotationsArray, aMarkerViewManager, aIconManager, annotations, markers, polygons, polylines); Marker aMarker = mock(Marker.class); long aId = 5L; @@ -58,7 +58,7 @@ public void checksAddMarkers() throws Exception { Markers markers = new MarkerContainer(aNativeMapView, aMapView, annotationsArray, aIconManager, aMarkerViewManager); Polygons polygons = new PolygonContainer(aNativeMapView, annotationsArray); Polylines polylines = new PolylineContainer(aNativeMapView, annotationsArray); - AnnotationManager annotationManager = new AnnotationManager(aNativeMapView, aMapView, annotationsArray, + AnnotationManager annotationManager = new AnnotationManager(aMapView, annotationsArray, aMarkerViewManager, aIconManager, annotations, markers, polygons, polylines); long firstId = 1L; long secondId = 2L; diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapChangeDispatcherTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapChangeDispatcherTest.java new file mode 100644 index 00000000000..5065ee93b5d --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapChangeDispatcherTest.java @@ -0,0 +1,200 @@ +package com.mapbox.mapboxsdk.maps; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import static org.mockito.Mockito.verify; + +public class MapChangeDispatcherTest { + + private MapChangeDispatcher mapChangeDispatcher; + + @Mock + private MapView.OnCameraWillChangeListener onCameraWillChangeListener; + + @Mock + private MapView.OnCameraDidChangeListener onCameraDidChangeListener; + + @Mock + private MapView.OnCameraIsChangingListener onCameraIsChangingListener; + + @Mock + private MapView.OnWillStartLoadingMapListener onWillStartLoadingMapListener; + + @Mock + private MapView.OnDidFinishLoadingMapListener onDidFinishLoadingMapListener; + + @Mock + private MapView.OnDidFailLoadingMapListener onDidFailLoadingMapListener; + + @Mock + private MapView.OnWillStartRenderingFrameListener onWillStartRenderingFrameListener; + + @Mock + private MapView.OnDidFinishRenderingFrameListener onDidFinishRenderingFrameListener; + + @Mock + private MapView.OnWillStartRenderingMapListener onWillStartRenderingMapListener; + + @Mock + private MapView.OnDidFinishRenderingMapListener onDidFinishRenderingMapListener; + + @Mock + private MapView.OnDidFinishLoadingStyleListener onDidFinishLoadingStyleListener; + + @Mock + private MapView.OnSourceChangedListener onSourceChangedListener; + + @Mock + private MapView.OnMapChangedListener onMapChangedListener; + + @Mock + private MapView.MapChangeResultHandler mapCallback; + + @Before + public void beforeTest() { + MockitoAnnotations.initMocks(this); + mapChangeDispatcher = new MapChangeDispatcher(); + mapChangeDispatcher.addOnMapChangedListener(onMapChangedListener); + mapChangeDispatcher.bind(mapCallback); + } + + @Test + public void testOnCameraRegionWillChangeListener() throws Exception { + mapChangeDispatcher.setOnCameraWillChangeListener(onCameraWillChangeListener); + mapChangeDispatcher.onCameraWillChange(false); + verify(onCameraWillChangeListener).onCameraWillChange(false); + verify(onMapChangedListener).onMapChanged(MapView.REGION_WILL_CHANGE); + } + + @Test + public void testOnCameraRegionWillChangeAnimatedListener() throws Exception { + mapChangeDispatcher.setOnCameraWillChangeListener(onCameraWillChangeListener); + mapChangeDispatcher.onCameraWillChange(true); + verify(onCameraWillChangeListener).onCameraWillChange(true); + verify(onMapChangedListener).onMapChanged(MapView.REGION_WILL_CHANGE_ANIMATED); + } + + @Test + public void testOnCameraIsChangingListener() throws Exception { + mapChangeDispatcher.setOnCameraIsChangingListener(onCameraIsChangingListener); + mapChangeDispatcher.onCameraIsChanging(); + verify(onCameraIsChangingListener).onCameraIsChanging(); + verify(onMapChangedListener).onMapChanged(MapView.REGION_IS_CHANGING); + verify(mapCallback).onCameraIsChanging(); + } + + @Test + public void testOnCameraRegionDidChangeListener() throws Exception { + mapChangeDispatcher.setOnCameraDidChangeListener(onCameraDidChangeListener); + mapChangeDispatcher.onCameraDidChange(false); + verify(onCameraDidChangeListener).onCameraDidChange(false); + verify(onMapChangedListener).onMapChanged(MapView.REGION_DID_CHANGE); + verify(mapCallback).onCameraDidChange(false); + } + + @Test + public void testOnCameraRegionDidChangeAnimatedListener() throws Exception { + mapChangeDispatcher.setOnCameraDidChangeListener(onCameraDidChangeListener); + mapChangeDispatcher.onCameraDidChange(true); + verify(onCameraDidChangeListener).onCameraDidChange(true); + verify(onMapChangedListener).onMapChanged(MapView.REGION_DID_CHANGE_ANIMATED); + verify(mapCallback).onCameraDidChange(true); + } + + @Test + public void testOnWillStartLoadingMapListener() throws Exception { + mapChangeDispatcher.setOnWillStartLoadingMapListener(onWillStartLoadingMapListener); + mapChangeDispatcher.onWillStartLoadingMap(); + verify(onWillStartLoadingMapListener).onWillStartLoadingMap(); + verify(onMapChangedListener).onMapChanged(MapView.WILL_START_LOADING_MAP); + } + + @Test + public void testOnDidFinishLoadingMapListener() throws Exception { + mapChangeDispatcher.setOnDidFinishLoadingMapListener(onDidFinishLoadingMapListener); + mapChangeDispatcher.onDidFinishLoadingMap(); + verify(onDidFinishLoadingMapListener).onDidFinishLoadingMap(); + verify(onMapChangedListener).onMapChanged(MapView.DID_FINISH_LOADING_MAP); + verify(mapCallback).onDidFinishLoadingMap(); + } + + @Test + public void testOnDidFailLoadingMapListener() throws Exception { + String errorMessage = "fail"; + mapChangeDispatcher.setOnDidFailLoadingMapListener(onDidFailLoadingMapListener); + mapChangeDispatcher.onDidFailLoadingMap(errorMessage); + verify(onDidFailLoadingMapListener).onDidFailLoadingMap(errorMessage); + verify(onMapChangedListener).onMapChanged(MapView.DID_FAIL_LOADING_MAP); + } + + @Test + public void testOnWillStartRenderingFrameListener() throws Exception { + mapChangeDispatcher.setOnWillStartRenderingFrameListener(onWillStartRenderingFrameListener); + mapChangeDispatcher.onWillStartRenderingFrame(); + verify(onWillStartRenderingFrameListener).onWillStartRenderingFrame(); + verify(onMapChangedListener).onMapChanged(MapView.WILL_START_RENDERING_FRAME); + } + + @Test + public void testOnDidFinishRenderingFrameListener() throws Exception { + mapChangeDispatcher.setOnDidFinishRenderingFrameListener(onDidFinishRenderingFrameListener); + mapChangeDispatcher.onDidFinishRenderingFrame(true); + verify(onDidFinishRenderingFrameListener).onDidFinishRenderingFrame(true); + verify(onMapChangedListener).onMapChanged(MapView.DID_FINISH_RENDERING_FRAME); + verify(mapCallback).onDidFinishRenderingFrame(true); + } + + @Test + public void testOnDidFinishRenderingFrameFullyRenderedListener() throws Exception { + mapChangeDispatcher.setOnDidFinishRenderingFrameListener(onDidFinishRenderingFrameListener); + mapChangeDispatcher.onDidFinishRenderingFrame(false); + verify(onDidFinishRenderingFrameListener).onDidFinishRenderingFrame(false); + verify(onMapChangedListener).onMapChanged(MapView.DID_FINISH_RENDERING_FRAME_FULLY_RENDERED); + verify(mapCallback).onDidFinishRenderingFrame(false); + } + + @Test + public void testOnWillStartRenderingMapListener() throws Exception { + mapChangeDispatcher.setOnWillStartRenderingMapListener(onWillStartRenderingMapListener); + mapChangeDispatcher.onWillStartRenderingMap(); + verify(onWillStartRenderingMapListener).onWillStartRenderingMap(); + verify(onMapChangedListener).onMapChanged(MapView.WILL_START_RENDERING_MAP); + } + + @Test + public void testOnDidFinishRenderingMapListener() throws Exception { + mapChangeDispatcher.setOnDidFinishRenderingMapListener(onDidFinishRenderingMapListener); + mapChangeDispatcher.onDidFinishRenderingMap(true); + verify(onDidFinishRenderingMapListener).onDidFinishRenderingMap(true); + verify(onMapChangedListener).onMapChanged(MapView.DID_FINISH_RENDERING_MAP); + } + + @Test + public void testOnDidFinishRenderingMapFullyRenderedListener() throws Exception { + mapChangeDispatcher.setOnDidFinishRenderingMapListener(onDidFinishRenderingMapListener); + mapChangeDispatcher.onDidFinishRenderingMap(false); + verify(onDidFinishRenderingMapListener).onDidFinishRenderingMap(false); + verify(onMapChangedListener).onMapChanged(MapView.DID_FINISH_RENDERING_MAP_FULLY_RENDERED); + } + + @Test + public void testOnDidFinishLoadingStyleListener() throws Exception { + mapChangeDispatcher.setOnDidFinishLoadingStyleListener(onDidFinishLoadingStyleListener); + mapChangeDispatcher.onDidFinishLoadingStyle(); + verify(onDidFinishLoadingStyleListener).onDidFinishLoadingStyle(); + verify(onMapChangedListener).onMapChanged(MapView.DID_FINISH_LOADING_STYLE); + verify(mapCallback).onDidFinishLoadingStyle(); + } + + @Test + public void testOnSourceChangedListener() throws Exception { + String sourceId = "sourceId"; + mapChangeDispatcher.setOnSourceChangedListener(onSourceChangedListener); + mapChangeDispatcher.onSourceChanged(sourceId); + verify(onSourceChangedListener).onSourceChangedListener(sourceId); + verify(onMapChangedListener).onMapChanged(MapView.SOURCE_DID_CHANGE); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java index 8b238e49a8f..6593453562b 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java @@ -228,14 +228,12 @@ public void onAnimationEnd(Animator animation) { viewCountView = (TextView) findViewById(R.id.countView); - mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() { + mapView.setOnCameraIsChangingListener(new MapView.OnCameraIsChangingListener() { @Override - public void onMapChanged(@MapView.MapChange int change) { - if (change == MapView.REGION_IS_CHANGING || change == MapView.REGION_DID_CHANGE) { - if (!mapboxMap.getMarkerViewManager().getMarkerViewAdapters().isEmpty()) { - viewCountView.setText(String.format(Locale.getDefault(), "ViewCache size %d", - mapboxMap.getMarkerViewManager().getMarkerViewContainer().getChildCount())); - } + public void onCameraIsChanging() { + if (!mapboxMap.getMarkerViewManager().getMarkerViewAdapters().isEmpty()) { + viewCountView.setText(String.format(Locale.getDefault(), "ViewCache size %d", + mapboxMap.getMarkerViewManager().getMarkerViewContainer().getChildCount())); } } }); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java index f2f82865d19..db662487a4f 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java @@ -36,6 +36,7 @@ import com.mapbox.mapboxsdk.testapp.model.annotations.TextMarkerView; import com.mapbox.mapboxsdk.testapp.model.annotations.TextMarkerViewOptions; +import java.util.Locale; import java.util.Random; /** @@ -144,15 +145,18 @@ public void onMapReady(@NonNull MapboxMap mapboxMap) { final ViewGroup markerViewContainer = markerViewManager.getMarkerViewContainer(); - // add a change listener to validate the size of amount of child views - mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() { + + mapView.setOnCameraIsChangingListener(new MapView.OnCameraIsChangingListener() { @Override - public void onMapChanged(@MapView.MapChange int change) { - if (change == MapView.REGION_IS_CHANGING || change == MapView.REGION_DID_CHANGE) { - if (!markerViewManager.getMarkerViewAdapters().isEmpty() && viewCountView != null) { - viewCountView.setText("ViewCache size " + markerViewContainer.getChildCount()); - } - } + public void onCameraIsChanging() { + updateMarkerViewCountText(markerViewManager, viewCountView, markerViewContainer); + } + }); + + mapView.setOnCameraDidChangeListener(new MapView.OnCameraDidChangeListener() { + @Override + public void onCameraDidChange(boolean animated) { + updateMarkerViewCountText(markerViewManager, viewCountView, markerViewContainer); } }); @@ -200,6 +204,12 @@ public boolean onMarkerClick(@NonNull Marker marker, @NonNull View view, }); } + private void updateMarkerViewCountText(MarkerViewManager markerViewManager, TextView countView, ViewGroup group) { + if (!markerViewManager.getMarkerViewAdapters().isEmpty() && countView != null) { + countView.setText(String.format(Locale.getDefault(), "ViewCache size %d", group.getChildCount())); + } + } + private void loopMarkerRotate() { rotateUpdateHandler.postDelayed(rotateMarkerRunnable, 800); } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapChangeActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapChangeActivity.java index 32344248bc7..ec4875a30ce 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapChangeActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapChangeActivity.java @@ -1,7 +1,6 @@ package com.mapbox.mapboxsdk.testapp.activity.maplayout; import android.os.Bundle; -import android.support.v4.util.LongSparseArray; import android.support.v7.app.AppCompatActivity; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; @@ -26,12 +25,88 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_map_simple); - final LongSparseArray mapChangeMap = buildMapChangeStringValueSparseArray(); mapView = (MapView) findViewById(R.id.mapView); - mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() { + mapView.setOnCameraIsChangingListener(new MapView.OnCameraIsChangingListener() { @Override - public void onMapChanged(int change) { - Timber.e("OnMapChange: %s, %s", change, mapChangeMap.get(change)); + public void onCameraIsChanging() { + Timber.v("OnCameraIsChanging"); + } + }); + + mapView.setOnCameraDidChangeListener(new MapView.OnCameraDidChangeListener() { + @Override + public void onCameraDidChange(boolean animated) { + Timber.v("OnCamaraDidChange: animated: %s", animated); + } + }); + + mapView.setOnCameraWillChangeListener(new MapView.OnCameraWillChangeListener() { + @Override + public void onCameraWillChange(boolean animated) { + Timber.v("OnCameraWilChange: animated: %s", animated); + } + }); + + mapView.setOnDidFailLoadingMapListener(new MapView.OnDidFailLoadingMapListener() { + @Override + public void onDidFailLoadingMap(String errorMessage) { + Timber.v("OnDidFailLoadingMap: %s", errorMessage); + } + }); + + mapView.setOnDidFinishLoadingMapListener(new MapView.OnDidFinishLoadingMapListener() { + @Override + public void onDidFinishLoadingMap() { + Timber.v("OnDidFinishLoadingMap"); + } + }); + + mapView.setOnDidFinishLoadingStyleListener(new MapView.OnDidFinishLoadingStyleListener() { + @Override + public void onDidFinishLoadingStyle() { + Timber.v("OnDidFinishLoadingStyle"); + } + }); + + mapView.setOnDidFinishRenderingFrameListener(new MapView.OnDidFinishRenderingFrameListener() { + @Override + public void onDidFinishRenderingFrame(boolean partial) { + Timber.v("OnDidFinishRenderingFrame: partial: %s", partial); + } + }); + + mapView.setOnDidFinishRenderingMapListener(new MapView.OnDidFinishRenderingMapListener() { + @Override + public void onDidFinishRenderingMap(boolean partial) { + Timber.v("OnDidFinishRenderingMap: partial: %s", partial); + } + }); + + mapView.setOnSourceChangedListener(new MapView.OnSourceChangedListener() { + @Override + public void onSourceChangedListener(String sourceId) { + Timber.v("OnSourceChangedListener: source with id: %s", sourceId); + } + }); + + mapView.setOnWillStartLoadingMapListener(new MapView.OnWillStartLoadingMapListener() { + @Override + public void onWillStartLoadingMap() { + Timber.v("OnWillStartLoadingMap"); + } + }); + + mapView.setOnWillStartRenderingFrameListener(new MapView.OnWillStartRenderingFrameListener() { + @Override + public void onWillStartRenderingFrame() { + Timber.v("OnWillStartRenderingFrame"); + } + }); + + mapView.setOnWillStartRenderingMapListener(new MapView.OnWillStartRenderingMapListener() { + @Override + public void onWillStartRenderingMap() { + Timber.v("OnWillStartRenderingMap"); } }); @@ -46,27 +121,6 @@ public void onMapReady(MapboxMap map) { }); } - private LongSparseArray buildMapChangeStringValueSparseArray() { - LongSparseArray mapChangeArray = new LongSparseArray<>(); - mapChangeArray.put(MapView.REGION_WILL_CHANGE, "Region will change"); - mapChangeArray.put(MapView.REGION_WILL_CHANGE_ANIMATED, "Region will change animated"); - mapChangeArray.put(MapView.REGION_IS_CHANGING, "Region is changing"); - mapChangeArray.put(MapView.REGION_DID_CHANGE, "Region did change"); - mapChangeArray.put(MapView.REGION_DID_CHANGE_ANIMATED, "Region did change animated"); - mapChangeArray.put(MapView.WILL_START_LOADING_MAP, "Will start loading map"); - mapChangeArray.put(MapView.DID_FINISH_LOADING_MAP, "Did finish loading map"); - mapChangeArray.put(MapView.DID_FAIL_LOADING_MAP, "Did fail loading map"); - mapChangeArray.put(MapView.WILL_START_RENDERING_FRAME, "Will start rendering frame"); - mapChangeArray.put(MapView.DID_FINISH_RENDERING_FRAME, "Did finish rendering frame"); - mapChangeArray.put(MapView.DID_FINISH_RENDERING_FRAME_FULLY_RENDERED, "Did finish rendering frame fully rendered"); - mapChangeArray.put(MapView.WILL_START_RENDERING_MAP, "Will start rendering map"); - mapChangeArray.put(MapView.DID_FINISH_RENDERING_MAP, "Did finish rendering map"); - mapChangeArray.put(MapView.DID_FINISH_RENDERING_MAP_FULLY_RENDERED, "Did finish rendering map fully rendered"); - mapChangeArray.put(MapView.DID_FINISH_LOADING_STYLE, "Did finish loading style"); - mapChangeArray.put(MapView.SOURCE_DID_CHANGE, "Source did change"); - return mapChangeArray; - } - @Override protected void onStart() { super.onStart(); diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index 8cc45b3930e..48b5779d199 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -176,80 +176,176 @@ void NativeMapView::invalidate() { } /** - * From mbgl::RendererBackend. Callback to java NativeMapView#onMapChanged(int). + * From mbgl::MapObserver. Callback to java NativeMapView#onCameraWillChange(). * - * May be called from any thread + * Called from the main thread */ -void NativeMapView::notifyMapChange(mbgl::MapChange change) { - assert(vm != nullptr); - - android::UniqueEnv _env = android::AttachEnv(); - static auto onMapChanged = javaClass.GetMethod(*_env, "onMapChanged"); - javaPeer->Call(*_env, onMapChanged, (int) change); -} - void NativeMapView::onCameraWillChange(MapObserver::CameraChangeMode mode) { - if (mode == MapObserver::CameraChangeMode::Immediate) { - notifyMapChange(MapChange::MapChangeRegionWillChange); - } else { - notifyMapChange(MapChange::MapChangeRegionWillChangeAnimated); + JNIEnv* env = nullptr; + int resultCode = vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); + if(resultCode == JNI_OK) { + static auto onCameraWillChange = javaClass.GetMethod(*env, "onCameraWillChange"); + javaPeer->Call(*env, onCameraWillChange, (jboolean) (mode == MapObserver::CameraChangeMode::Animated)); } } +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onCameraIsChanging(). + * + * Called from the main thread + */ void NativeMapView::onCameraIsChanging() { - notifyMapChange(MapChange::MapChangeRegionIsChanging); + JNIEnv* env = nullptr; + int resultCode = vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); + if(resultCode == JNI_OK) { + static auto onCameraIsChanging = javaClass.GetMethod(*env, "onCameraIsChanging"); + javaPeer->Call(*env, onCameraIsChanging); + } } +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onCameraDidChange(). + * + * Called from the map thread (main thread) + */ void NativeMapView::onCameraDidChange(MapObserver::CameraChangeMode mode) { - if (mode == MapObserver::CameraChangeMode::Immediate) { - notifyMapChange(MapChange::MapChangeRegionDidChange); - } else { - notifyMapChange(MapChange::MapChangeRegionDidChangeAnimated); + JNIEnv* env = nullptr; + int resultCode = vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); + if(resultCode == JNI_OK) { + static auto onCameraDidChange = javaClass.GetMethod(*env, "onCameraDidChange"); + javaPeer->Call(*env, onCameraDidChange, (jboolean) (mode == MapObserver::CameraChangeMode::Animated)); } } +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onWillStartLoadingMap(). + * + * Called from the map thread (main thread) + */ void NativeMapView::onWillStartLoadingMap() { - notifyMapChange(MapChange::MapChangeWillStartLoadingMap); + JNIEnv* env = nullptr; + int resultCode = vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); + if(resultCode == JNI_OK) { + static auto onWillStartLoadingMap = javaClass.GetMethod(*env, "onWillStartLoadingMap"); + javaPeer->Call(*env, onWillStartLoadingMap); + } } +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onDidFinishLoadingMap(). + * + * Called from the map thread (main thread) + */ void NativeMapView::onDidFinishLoadingMap() { - notifyMapChange(MapChange::MapChangeDidFinishLoadingMap); + JNIEnv* env = nullptr; + int resultCode = vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); + if(resultCode == JNI_OK) { + static auto onDidFinishLoadingMap = javaClass.GetMethod(*env, "onDidFinishLoadingMap"); + javaPeer->Call(*env, onDidFinishLoadingMap); + } } -void NativeMapView::onDidFailLoadingMap(std::exception_ptr) { - notifyMapChange(MapChange::MapChangeDidFailLoadingMap); +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onDidFailLoadingMap(). + * + * Called from the map thread (main thread) + */ +void NativeMapView::onDidFailLoadingMap(std::exception_ptr eptr) { + assert(vm != nullptr); + try { + if(eptr) { + std::rethrow_exception(eptr); + } + } catch (const std::exception &e) { + std::string errorMessage = e.what(); + android::UniqueEnv _env = android::AttachEnv(); + static auto onDidFailLoadingMap = javaClass.GetMethod(*_env, "onDidFailLoadingMap"); + javaPeer->Call(*_env, onDidFailLoadingMap, jni::Make(*_env, errorMessage)); + } } +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onWillStartRenderingFrame(). + * + * Called from the map thread (main thread) + */ void NativeMapView::onWillStartRenderingFrame() { - notifyMapChange(MapChange::MapChangeWillStartRenderingFrame); + JNIEnv* env = nullptr; + int resultCode = vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); + if(resultCode == JNI_OK) { + static auto onWillStartRenderingFrame = javaClass.GetMethod(*env, "onWillStartRenderingFrame"); + javaPeer->Call(*env, onWillStartRenderingFrame); + } } +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onDidFinishRenderingFrame(). + * + * Called from the map thread (main thread) + */ void NativeMapView::onDidFinishRenderingFrame(MapObserver::RenderMode mode) { - if (mode == MapObserver::RenderMode::Partial) { - notifyMapChange(MapChange::MapChangeDidFinishRenderingFrame); - } else { - notifyMapChange(MapChange::MapChangeDidFinishRenderingFrameFullyRendered); + JNIEnv* env = nullptr; + int resultCode = vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); + if(resultCode == JNI_OK) { + static auto onDidFinishRenderingFrame = javaClass.GetMethod(*env, "onDidFinishRenderingFrame"); + javaPeer->Call(*env, onDidFinishRenderingFrame, (jboolean) (mode == MapObserver::RenderMode::Partial)); } } +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onWillStartRenderingMap(). + * + * Called from the map thread (main thread) + */ void NativeMapView::onWillStartRenderingMap() { - notifyMapChange(MapChange::MapChangeWillStartRenderingMap); + JNIEnv* env = nullptr; + int resultCode = vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); + if(resultCode == JNI_OK) { + static auto onWillStartRenderingMap = javaClass.GetMethod(*env, "onWillStartRenderingMap"); + javaPeer->Call(*env, onWillStartRenderingMap); + } } +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onDidFinishRenderingMap(). + * + * Called from the map thread (main thread) + */ void NativeMapView::onDidFinishRenderingMap(MapObserver::RenderMode mode) { - if (mode == MapObserver::RenderMode::Partial) { - notifyMapChange(MapChange::MapChangeDidFinishRenderingMap); - } else { - notifyMapChange(MapChange::MapChangeDidFinishRenderingMapFullyRendered); + JNIEnv* env = nullptr; + int resultCode = vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); + if(resultCode == JNI_OK) { + static auto onDidFinishRenderingMap = javaClass.GetMethod(*env, "onDidFinishRenderingMap"); + javaPeer->Call(*env, onDidFinishRenderingMap, (jboolean) (mode == MapObserver::RenderMode::Partial)); } } +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onDidFinishLoadingStyle(). + * + * Called from the map thread (main thread) + */ void NativeMapView::onDidFinishLoadingStyle() { - notifyMapChange(MapChange::MapChangeDidFinishLoadingStyle); + JNIEnv* env = nullptr; + int resultCode = vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); + if(resultCode == JNI_OK) { + static auto onDidFinishLoadingStyle = javaClass.GetMethod(*env, "onDidFinishLoadingStyle"); + javaPeer->Call(*env, onDidFinishLoadingStyle); + } } -void NativeMapView::onSourceChanged(mbgl::style::Source&) { - notifyMapChange(MapChange::MapChangeSourceDidChange); +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onSourceChanged(). + * + * Called from the map thread (main thread) + */ +void NativeMapView::onSourceChanged(mbgl::style::Source& source) { + JNIEnv* env = nullptr; + int resultCode = vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); + if(resultCode == JNI_OK) { + static auto onSourceChanged = javaClass.GetMethod(*env, "onSourceChanged"); + javaPeer->Call(*env, onSourceChanged, jni::Make(*env, source.getID())); + } } // JNI Methods // diff --git a/platform/android/src/native_map_view.hpp b/platform/android/src/native_map_view.hpp index ef0e9e936cf..0e5ab8236e6 100755 --- a/platform/android/src/native_map_view.hpp +++ b/platform/android/src/native_map_view.hpp @@ -63,10 +63,7 @@ class NativeMapView : public View, public RendererBackend, public MapObserver { void updateAssumedState() override; - // Deprecated // - void notifyMapChange(mbgl::MapChange); - - // mbgl::RendererBackend (mbgl::MapObserver) // + // mbgl::MapObserver void onCameraWillChange(MapObserver::CameraChangeMode) override; void onCameraIsChanging() override; void onCameraDidChange(MapObserver::CameraChangeMode) override;