diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5fb33f7ca..e3b07dd32 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,8 +3,62 @@
Mapbox welcomes participation and contributions from everyone. If you'd like to do so please see the [`Contributing Guide`](https://github.com/mapbox/mapbox-gl-native/blob/master/CONTRIBUTING.md) first to get started.
## master
+
+### Performance improvements
+ - Improved rendering performance for the styles with multiple sources [#15756](https://github.com/mapbox/mapbox-gl-native/pull/15756)
+
+## 8.5.0-alpha.1 - October 3, 2019
+[Changes](https://github.com/mapbox/mapbox-gl-native/compare/android-v8.4.0...android-v8.5.0-alpha.1) since [Mapbox Maps SDK for Android v8.4.0](https://github.com/mapbox/mapbox-gl-native/releases/tag/android-v8.4.0):
+### Bug fixes
+ - Suppress network requests for expired tiles update, if these tiles are invisible. [#15741](https://github.com/mapbox/mapbox-gl-native/pull/15741)
+ - Fixed opacity interpolation for composition expressions [#15738](https://github.com/mapbox/mapbox-gl-native/pull/15738)
+ - Fixed an issue where `Projection#getMetersPerPixelAtLatitude` returned a value incorrectly divided by the pixel ratio. This also fixes an issue where `LocationComponent` accuracy circle's radius was artificially increased. [#15742](https://github.com/mapbox/mapbox-gl-native/pull/15742)
+
+## 8.4.0 - September 25, 2019
+[Changes](https://github.com/mapbox/mapbox-gl-native/compare/android-v8.4.0-beta.1...android-v8.4.0) since [Mapbox Maps SDK for Android v8.4.0-beta.1](https://github.com/mapbox/mapbox-gl-native/releases/tag/android-v8.4.0-beta.1):
+
+### Bug fixes
+ - Fixing a crash when `CameraPosition` padding is set when using `MapSnapshotter`. [#15699](https://github.com/mapbox/mapbox-gl-native/pull/15699)
+
+### Other Changes
+ - Bumped Java SDK dependency to stable 4.9.0 [#15700](https://github.com/mapbox/mapbox-gl-native/pull/15700)
+ - Migrate map feedback to GL JS–powered feedback form [#15623](https://github.com/mapbox/mapbox-gl-native/pull/15623)
+
+## 8.4.0-beta.1 - September 19, 2019
+[Changes](https://github.com/mapbox/mapbox-gl-native/compare/android-v8.4.0-alpha.2...android-v8.4.0-beta.1) since [Mapbox Maps SDK for Android v8.4.0-alpha.2](https://github.com/mapbox/mapbox-gl-native/releases/tag/android-v8.4.0-alpha.2):
+
+### Bug fixes
+ - Fixed an issue that `maxzoom` in style `Sources` option was ignored when URL resource is provided. It may cause problems such as extra tiles downloading at higher zoom level than `maxzoom`, or problems that wrong setting of `overscaledZ` in `OverscaledTileID` that will be passed to `SymbolLayout`, leading wrong rendering appearance. [#15581](https://github.com/mapbox/mapbox-gl-native/pull/15581)
+ - Fixed constant repainting for the sources with invisible layers, caused by `RenderSource::hasFadingTiles()` returning `true` all the time. [#15600](https://github.com/mapbox/mapbox-gl-native/pull/15600)
+ - Fixed an issue that caused the state of CompassView not up to date when `UiSettings.setCompassEnabled()` is set to true. [#15606](https://github.com/mapbox/mapbox-gl-native/pull/15606)
+ - Ignore location tracking mode based animations when the camera is transitioning. [#15641](https://github.com/mapbox/mapbox-gl-native/pull/15641)
+ - Fixed MapSnapshotter so that `MapSnapshotter.withApiBaseUri` works again. [#15642](https://github.com/mapbox/mapbox-gl-native/pull/15642)
+ - Fixed an assertion hit caused by possibility of adding a layer to an incompatible source. [#15644](https://github.com/mapbox/mapbox-gl-native/pull/15644)
+
+## 8.3.2 - September 19, 2019
+[Changes](https://github.com/mapbox/mapbox-gl-native/compare/android-v8.3.1...android-v8.3.2) since [Mapbox Maps SDK for Android v8.3.1](https://github.com/mapbox/mapbox-gl-native/releases/tag/android-v8.3.1):
+
### Bug fixes
- Fixed an issue of integer overflow when converting `tileCoordinates` to `LatLon`, which caused issues such as `queryRenderedFeatures` and `querySourceFeatures` returning incorrect coordinates at zoom levels 20 and higher. [#15560](https://github.com/mapbox/mapbox-gl-native/pull/15560)
+
+## 8.3.1 - September 18, 2019
+[Changes](https://github.com/mapbox/mapbox-gl-native/compare/android-v8.3.0...android-v8.3.1) since [Mapbox Maps SDK for Android v8.3.0](https://github.com/mapbox/mapbox-gl-native/releases/tag/android-v8.3.0):
+
+### Bug fixes
+ - Updated earcut.hpp submodule file [#15660](https://github.com/mapbox/mapbox-gl-native/pull/15660)
+ - Fixed a wrong variable assignment of `MapSnapshotter.Options.withApiBaseUri`. [#15642](https://github.com/mapbox/mapbox-gl-native/pull/15642)
+
+## 8.4.0-alpha.2 - September 11, 2019
+[Changes](https://github.com/mapbox/mapbox-gl-native/compare/android-v8.4.0-alpha.1...android-v8.4.0-alpha.2) since [Mapbox Maps SDK for Android v8.4.0-alpha.1](https://github.com/mapbox/mapbox-gl-native/releases/tag/android-v8.4.0-alpha.1):
+
+### Performance improvements
+ - Newly loaded labels appear faster on the screen. [#15308](https://github.com/mapbox/mapbox-gl-native/pull/15308)
+
+### Bug fixes
+ - Fixed an issue of integer overflow when converting `tileCoordinates` to `LatLon`, which caused issues such as `queryRenderedFeatures` and `querySourceFeatures` returning incorrect coordinates at zoom levels 20 and higher. [#15560](https://github.com/mapbox/mapbox-gl-native/pull/15560)
+
+### Other Changes
+ - Bumped Java SDK dependency to 4.9.0-alpha.1 [#15570](https://github.com/mapbox/mapbox-gl-native/pull/15570)
## 8.4.0-alpha.1 - September 4, 2019
[Changes](https://github.com/mapbox/mapbox-gl-native/compare/android-v8.3.0...android-v8.4.0-alpha.1) since [Mapbox Maps SDK for Android v8.3.0](https://github.com/mapbox/mapbox-gl-native/releases/tag/android-v8.3.0):
diff --git a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java
index 01c82ddad..35f7a5975 100644
--- a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java
+++ b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java
@@ -2,6 +2,8 @@ package com.mapbox.mapboxsdk;
import android.annotation.SuppressLint;
import android.content.Context;
+import android.content.res.AssetManager;
+import android.support.annotation.Keep;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
@@ -24,6 +26,7 @@ import com.mapbox.mapboxsdk.utils.ThreadUtils;
*/
@UiThread
@SuppressLint("StaticFieldLeak")
+@Keep
public final class Mapbox {
private static final String TAG = "Mbgl-Mapbox";
@@ -222,4 +225,13 @@ public final class Mapbox {
public static boolean hasInstance() {
return INSTANCE != null;
}
+
+ /**
+ * Internal use. Returns AssetManager.
+ *
+ * @return the asset manager
+ */
+ private static AssetManager getAssetManager() {
+ return getApplicationContext().getResources().getAssets();
+ }
}
\ No newline at end of file
diff --git a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java
index 46de3673e..8b014b0e9 100644
--- a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java
+++ b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java
@@ -726,6 +726,10 @@ public final class LocationComponent {
* If you are not using any of {@link CameraMode} modes,
* use one of {@link MapboxMap#moveCamera(CameraUpdate)},
* {@link MapboxMap#easeCamera(CameraUpdate)} or {@link MapboxMap#animateCamera(CameraUpdate)} instead.
+ *
+ * If the camera is transitioning when the zoom change is requested, the call is going to be ignored.
+ * Use {@link CameraTransitionListener} to chain the animations, or provide the zoom as a camera change argument.
+ *
*
* @param zoomLevel The desired zoom level.
* @param animationDuration The zoom animation duration.
@@ -741,6 +745,10 @@ public final class LocationComponent {
"LocationComponent#zoomWhileTracking method can only be used",
" when a camera mode other than CameraMode#NONE is engaged."));
return;
+ } else if (locationCameraController.isTransitioning()) {
+ Logger.e(TAG,
+ "LocationComponent#zoomWhileTracking method call is ignored because the camera mode is transitioning");
+ return;
}
locationAnimatorCoordinator.feedNewZoomLevel(zoomLevel, mapboxMap.getCameraPosition(), animationDuration, callback);
}
@@ -751,6 +759,10 @@ public final class LocationComponent {
* If you are not using any of {@link CameraMode} modes,
* use one of {@link MapboxMap#moveCamera(CameraUpdate)},
* {@link MapboxMap#easeCamera(CameraUpdate)} or {@link MapboxMap#animateCamera(CameraUpdate)} instead.
+ *
+ * If the camera is transitioning when the zoom change is requested, the call is going to be ignored.
+ * Use {@link CameraTransitionListener} to chain the animations, or provide the zoom as a camera change argument.
+ *
*
* @param zoomLevel The desired zoom level.
* @param animationDuration The zoom animation duration.
@@ -766,6 +778,10 @@ public final class LocationComponent {
* If you are not using any of {@link CameraMode} modes,
* use one of {@link MapboxMap#moveCamera(CameraUpdate)},
* {@link MapboxMap#easeCamera(CameraUpdate)} or {@link MapboxMap#animateCamera(CameraUpdate)} instead.
+ *
+ * If the camera is transitioning when the zoom change is requested, the call is going to be ignored.
+ * Use {@link CameraTransitionListener} to chain the animations, or provide the zoom as a camera change argument.
+ *
*
* @param zoomLevel The desired zoom level.
*/
@@ -788,6 +804,10 @@ public final class LocationComponent {
* If you are not using any of {@link CameraMode} modes,
* use one of {@link MapboxMap#moveCamera(CameraUpdate)},
* {@link MapboxMap#easeCamera(CameraUpdate)} or {@link MapboxMap#animateCamera(CameraUpdate)} instead.
+ *
+ * If the camera is transitioning when the tilt change is requested, the call is going to be ignored.
+ * Use {@link CameraTransitionListener} to chain the animations, or provide the tilt as a camera change argument.
+ *
*
* @param tilt The desired camera tilt.
* @param animationDuration The tilt animation duration.
@@ -803,6 +823,10 @@ public final class LocationComponent {
"LocationComponent#tiltWhileTracking method can only be used",
" when a camera mode other than CameraMode#NONE is engaged."));
return;
+ } else if (locationCameraController.isTransitioning()) {
+ Logger.e(TAG,
+ "LocationComponent#tiltWhileTracking method call is ignored because the camera mode is transitioning");
+ return;
}
locationAnimatorCoordinator.feedNewTilt(tilt, mapboxMap.getCameraPosition(), animationDuration, callback);
}
@@ -813,6 +837,10 @@ public final class LocationComponent {
* If you are not using any of {@link CameraMode} modes,
* use one of {@link MapboxMap#moveCamera(CameraUpdate)},
* {@link MapboxMap#easeCamera(CameraUpdate)} or {@link MapboxMap#animateCamera(CameraUpdate)} instead.
+ *
+ * If the camera is transitioning when the tilt change is requested, the call is going to be ignored.
+ * Use {@link CameraTransitionListener} to chain the animations, or provide the tilt as a camera change argument.
+ *
*
* @param tilt The desired camera tilt.
* @param animationDuration The tilt animation duration.
@@ -828,6 +856,10 @@ public final class LocationComponent {
* If you are not using any of {@link CameraMode} modes,
* use one of {@link MapboxMap#moveCamera(CameraUpdate)},
* {@link MapboxMap#easeCamera(CameraUpdate)} or {@link MapboxMap#animateCamera(CameraUpdate)} instead.
+ *
+ * If the camera is transitioning when the tilt change is requested, the call is going to be ignored.
+ * Use {@link CameraTransitionListener} to chain the animations, or provide the tilt as a camera change argument.
+ *
*
* @param tilt The desired camera tilt.
*/
diff --git a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AttributionDialogManager.java b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AttributionDialogManager.java
index 4f523948d..5384a29fc 100644
--- a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AttributionDialogManager.java
+++ b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AttributionDialogManager.java
@@ -26,6 +26,8 @@ import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Responsible for managing attribution interactions on the map.
@@ -36,9 +38,10 @@ import java.util.Set;
*
*/
public class AttributionDialogManager implements View.OnClickListener, DialogInterface.OnClickListener {
-
private static final String MAP_FEEDBACK_URL = "https://apps.mapbox.com/feedback";
- private static final String MAP_FEEDBACK_LOCATION_FORMAT = MAP_FEEDBACK_URL + "/#/%f/%f/%d";
+ private static final String MAP_FEEDBACK_URL_OLD = "https://www.mapbox.com/map-feedback";
+ private static final String MAP_FEEDBACK_URL_LOCATION_FRAGMENT_FORMAT = "/%f/%f/%f/%f/%d";
+ private static final String MAP_FEEDBACK_STYLE_URI_REGEX = "^(.*://[^:^/]*)/(.*)/(.*)";
@NonNull
private final Context context;
@@ -90,7 +93,7 @@ public class AttributionDialogManager implements View.OnClickListener, DialogInt
if (isLatestEntry(which)) {
showTelemetryDialog();
} else {
- showMapFeedbackWebPage(which);
+ showMapAttributionWebPage(which);
}
}
@@ -138,21 +141,54 @@ public class AttributionDialogManager implements View.OnClickListener, DialogInt
builder.show();
}
- private void showMapFeedbackWebPage(int which) {
+ private void showMapAttributionWebPage(int which) {
Attribution[] attributions = attributionSet.toArray(new Attribution[attributionSet.size()]);
String url = attributions[which].getUrl();
- if (url.contains(MAP_FEEDBACK_URL)) {
- url = buildMapFeedbackMapUrl(mapboxMap.getCameraPosition());
+ if (url.contains(MAP_FEEDBACK_URL_OLD) || url.contains(MAP_FEEDBACK_URL)) {
+ url = buildMapFeedbackMapUrl(Mapbox.getAccessToken());
}
showWebPage(url);
}
@NonNull
- private String buildMapFeedbackMapUrl(@Nullable CameraPosition cameraPosition) {
- // appends current location to the map feedback url if available
- return cameraPosition != null ? String.format(Locale.getDefault(),
- MAP_FEEDBACK_LOCATION_FORMAT, cameraPosition.target.getLongitude(), cameraPosition.target.getLatitude(),
- (int) cameraPosition.zoom) : MAP_FEEDBACK_URL;
+ String buildMapFeedbackMapUrl(@Nullable String accessToken) {
+ // TODO Add Android Maps SDK version to the query parameter, currently the version API is not available.
+ // TODO Keep track of this issue at [#15632](https://github.com/mapbox/mapbox-gl-native/issues/15632)
+
+ Uri.Builder builder = Uri.parse(MAP_FEEDBACK_URL).buildUpon();
+
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ if (cameraPosition != null) {
+ builder.encodedFragment(String.format(Locale.getDefault(), MAP_FEEDBACK_URL_LOCATION_FRAGMENT_FORMAT,
+ cameraPosition.target.getLongitude(), cameraPosition.target.getLatitude(),
+ cameraPosition.zoom, cameraPosition.bearing, (int) cameraPosition.tilt));
+ }
+
+ String packageName = context.getApplicationContext().getPackageName();
+ if (packageName != null) {
+ builder.appendQueryParameter("referrer", packageName);
+ }
+
+ if (accessToken != null) {
+ builder.appendQueryParameter("access_token", accessToken);
+ }
+
+ Style style = mapboxMap.getStyle();
+ if (style != null) {
+ String styleUri = style.getUri();
+ Pattern pattern = Pattern.compile(MAP_FEEDBACK_STYLE_URI_REGEX);
+ Matcher matcher = pattern.matcher(styleUri);
+
+ if (matcher.find()) {
+ String styleOwner = matcher.group(2);
+ String styleId = matcher.group(3);
+
+ builder.appendQueryParameter("owner", styleOwner)
+ .appendQueryParameter("id", styleId);
+ }
+ }
+
+ return builder.build().toString();
}
private void showWebPage(@NonNull String url) {
@@ -189,10 +225,10 @@ public class AttributionDialogManager implements View.OnClickListener, DialogInt
Style style = mapboxMap.getStyle();
if (style != null) {
- for (Source source : mapboxMap.getStyle().getSources()) {
+ for (Source source : style.getSources()) {
attribution = source.getAttribution();
if (!attribution.isEmpty()) {
- attributions.add(source.getAttribution());
+ attributions.add(attribution);
}
}
}
diff --git a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
index acd5093da..8f4cb9438 100644
--- a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
+++ b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
@@ -6,6 +6,7 @@ import android.graphics.PointF;
import android.graphics.RectF;
import android.os.Bundle;
import android.support.annotation.FloatRange;
+import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.Size;
@@ -246,12 +247,16 @@ public final class MapboxMap {
// Style
/**
- * Sets tile pre-fetching from MapboxOptions.
+ * Sets tile pre-fetching zoom delta from MapboxOptions.
*
* @param options the options object
*/
private void setPrefetchesTiles(@NonNull MapboxMapOptions options) {
- setPrefetchesTiles(options.getPrefetchesTiles());
+ if (!options.getPrefetchesTiles()) {
+ setPrefetchZoomDelta(0);
+ } else {
+ setPrefetchZoomDelta(options.getPrefetchZoomDelta());
+ }
}
/**
@@ -259,7 +264,9 @@ public final class MapboxMap {
* tile is rendered as soon as possible at the expense of a little bandwidth.
*
* @param enable true to enable
+ * @deprecated Use {@link #setPrefetchZoomDelta(int)} instead.
*/
+ @Deprecated
public void setPrefetchesTiles(boolean enable) {
nativeMapView.setPrefetchTiles(enable);
}
@@ -269,11 +276,38 @@ public final class MapboxMap {
*
* @return true if enabled
* @see MapboxMap#setPrefetchesTiles(boolean)
+ * @deprecated Use {@link #getPrefetchZoomDelta()} instead.
*/
+ @Deprecated
public boolean getPrefetchesTiles() {
return nativeMapView.getPrefetchTiles();
}
+ /**
+ * Set the tile pre-fetching zoom delta. Pre-fetching makes sure that a low-resolution
+ * tile at the (current_zoom_level - delta) is rendered as soon as possible at the
+ * expense of a little bandwidth.
+ * Note: This operation will override the MapboxMapOptions#setPrefetchesTiles(boolean)
+ * Setting zoom delta to 0 will disable pre-fetching.
+ * Default zoom delta is 4.
+ *
+ * @param delta zoom delta
+ */
+ public void setPrefetchZoomDelta(@IntRange(from = 0) int delta) {
+ nativeMapView.setPrefetchZoomDelta(delta);
+ }
+
+ /**
+ * Check current pre-fetching zoom delta.
+ *
+ * @return current zoom delta.
+ * @see MapboxMap#setPrefetchZoomDelta(int)
+ */
+ @IntRange(from = 0)
+ public int getPrefetchZoomDelta() {
+ return nativeMapView.getPrefetchZoomDelta();
+ }
+
//
// MinZoom
//
diff --git a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java
index 6cd3271d1..827756870 100644
--- a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java
+++ b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java
@@ -8,6 +8,7 @@ import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.ColorInt;
+import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
@@ -70,6 +71,7 @@ public class MapboxMapOptions implements Parcelable {
private boolean quickZoomGesturesEnabled = true;
private boolean prefetchesTiles = true;
+ private int prefetchZoomDelta = 4;
private boolean zMediaOverlay = false;
private boolean localIdeographFontFamilyEnabled = true;
@@ -134,6 +136,7 @@ public class MapboxMapOptions implements Parcelable {
textureMode = in.readByte() != 0;
translucentTextureSurface = in.readByte() != 0;
prefetchesTiles = in.readByte() != 0;
+ prefetchZoomDelta = in.readInt();
zMediaOverlay = in.readByte() != 0;
localIdeographFontFamilyEnabled = in.readByte() != 0;
localIdeographFontFamily = in.readString();
@@ -257,6 +260,8 @@ public class MapboxMapOptions implements Parcelable {
typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_renderTextureTranslucentSurface, false));
mapboxMapOptions.setPrefetchesTiles(
typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_enableTilePrefetch, true));
+ mapboxMapOptions.setPrefetchZoomDelta(
+ typedArray.getInt(R.styleable.mapbox_MapView_mapbox_prefetchZoomDelta, 4));
mapboxMapOptions.renderSurfaceOnTop(
typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_enableZMediaOverlay, false));
@@ -633,13 +638,32 @@ public class MapboxMapOptions implements Parcelable {
*
* @param enable true to enable
* @return This
+ * @deprecated Use {@link #setPrefetchZoomDelta(int)} instead.
*/
+ @Deprecated
@NonNull
public MapboxMapOptions setPrefetchesTiles(boolean enable) {
this.prefetchesTiles = enable;
return this;
}
+ /**
+ * Set the tile pre-fetching zoom delta. Pre-fetching makes sure that a low-resolution
+ * tile at the (current_zoom_level - delta) is rendered as soon as possible at the
+ * expense of a little bandwidth.
+ * Note: This operation will override the MapboxMapOptions#setPrefetchesTiles(boolean)
+ * Setting zoom delta to 0 will disable pre-fetching.
+ * Default zoom delta is 4.
+ *
+ * @param delta zoom delta
+ * @return This
+ */
+ @NonNull
+ public MapboxMapOptions setPrefetchZoomDelta(@IntRange(from = 0) int delta) {
+ this.prefetchZoomDelta = delta;
+ return this;
+ }
+
/**
* Enable cross-source symbol collision detection, defaults to true.
*
@@ -721,11 +745,23 @@ public class MapboxMapOptions implements Parcelable {
* Check whether tile pre-fetching is enabled.
*
* @return true if enabled
+ * @deprecated Use {@link #getPrefetchZoomDelta()} instead.
*/
+ @Deprecated
public boolean getPrefetchesTiles() {
return prefetchesTiles;
}
+ /**
+ * Check current pre-fetching zoom delta.
+ *
+ * @return current zoom delta.
+ */
+ @IntRange(from = 0)
+ public int getPrefetchZoomDelta() {
+ return prefetchZoomDelta;
+ }
+
/**
* Check whether cross-source symbol collision detection is enabled.
*
@@ -1081,6 +1117,7 @@ public class MapboxMapOptions implements Parcelable {
dest.writeByte((byte) (textureMode ? 1 : 0));
dest.writeByte((byte) (translucentTextureSurface ? 1 : 0));
dest.writeByte((byte) (prefetchesTiles ? 1 : 0));
+ dest.writeInt(prefetchZoomDelta);
dest.writeByte((byte) (zMediaOverlay ? 1 : 0));
dest.writeByte((byte) (localIdeographFontFamilyEnabled ? 1 : 0));
dest.writeString(localIdeographFontFamily);
@@ -1175,6 +1212,9 @@ public class MapboxMapOptions implements Parcelable {
if (prefetchesTiles != options.prefetchesTiles) {
return false;
}
+ if (prefetchZoomDelta != options.prefetchZoomDelta) {
+ return false;
+ }
if (zMediaOverlay != options.zMediaOverlay) {
return false;
}
@@ -1231,6 +1271,7 @@ public class MapboxMapOptions implements Parcelable {
result = 31 * result + (textureMode ? 1 : 0);
result = 31 * result + (translucentTextureSurface ? 1 : 0);
result = 31 * result + (prefetchesTiles ? 1 : 0);
+ result = 31 * result + prefetchZoomDelta;
result = 31 * result + (zMediaOverlay ? 1 : 0);
result = 31 * result + (localIdeographFontFamilyEnabled ? 1 : 0);
result = 31 * result + (localIdeographFontFamily != null ? localIdeographFontFamily.hashCode() : 0);
diff --git a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMap.java b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMap.java
index 7f3017c7a..c805dcddb 100644
--- a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMap.java
+++ b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMap.java
@@ -6,6 +6,7 @@ import android.graphics.RectF;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+
import com.mapbox.geojson.Feature;
import com.mapbox.geojson.Geometry;
import com.mapbox.mapboxsdk.annotations.Marker;
@@ -214,6 +215,11 @@ interface NativeMap {
boolean getPrefetchTiles();
+ void setPrefetchZoomDelta(@IntRange(from = 0) int delta);
+
+ @IntRange(from = 0)
+ int getPrefetchZoomDelta();
+
void setGestureInProgress(boolean inProgress);
float getPixelRatio();
diff --git a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
index 8496160c7..75ca5edfc 100755
--- a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
+++ b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
@@ -620,7 +620,7 @@ final class NativeMapView implements NativeMap {
if (checkState("getMetersPerPixelAtLatitude")) {
return 0;
}
- return nativeGetMetersPerPixelAtLatitude(lat, getZoom()) / pixelRatio;
+ return nativeGetMetersPerPixelAtLatitude(lat, getZoom());
}
@Override
@@ -724,6 +724,23 @@ final class NativeMapView implements NativeMap {
return nativeGetPrefetchTiles();
}
+ @Override
+ public void setPrefetchZoomDelta(@IntRange(from = 0) int delta) {
+ if (checkState("nativeSetPrefetchZoomDelta")) {
+ return;
+ }
+ nativeSetPrefetchZoomDelta(delta);
+ }
+
+ @Override
+ @IntRange(from = 0)
+ public int getPrefetchZoomDelta() {
+ if (checkState("nativeGetPrefetchZoomDelta")) {
+ return 0;
+ }
+ return nativeGetPrefetchZoomDelta();
+ }
+
// Runtime style Api
@Override
@@ -1383,6 +1400,12 @@ final class NativeMapView implements NativeMap {
@Keep
private native boolean nativeGetPrefetchTiles();
+ @Keep
+ private native void nativeSetPrefetchZoomDelta(int delta);
+
+ @Keep
+ private native int nativeGetPrefetchZoomDelta();
+
@Override
public long getNativePtr() {
return nativePtr;
diff --git a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java
index 9e72be8e9..3fd155837 100644
--- a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java
+++ b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java
@@ -417,10 +417,6 @@ public final class UiSettings {
}
void update(@NonNull CameraPosition cameraPosition) {
- if (!isCompassEnabled()) {
- return;
- }
-
double clockwiseBearing = -cameraPosition.bearing;
compassView.update(clockwiseBearing);
}
@@ -1073,6 +1069,7 @@ public final class UiSettings {
*/
public void invalidate() {
setLogoMargins(getLogoMarginLeft(), getLogoMarginTop(), getLogoMarginRight(), getLogoMarginBottom());
+ setCompassEnabled(isCompassEnabled());
setCompassMargins(getCompassMarginLeft(), getCompassMarginTop(), getCompassMarginRight(), getCompassMarginBottom());
setAttributionMargins(getAttributionMarginLeft(), getAttributionMarginTop(), getAttributionMarginRight(),
getAttributionMarginBottom());
diff --git a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java
index 53c0c1c60..b593076dc 100644
--- a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java
+++ b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java
@@ -91,6 +91,7 @@ public final class CompassView extends ImageView implements Runnable {
resetAnimation();
setAlpha(1.0f);
setVisibility(View.VISIBLE);
+ update(rotation);
} else {
resetAnimation();
setAlpha(0.0f);
diff --git a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java
index 1e0069c25..990bd3226 100644
--- a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java
+++ b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java
@@ -235,7 +235,7 @@ public class MapSnapshotter {
*/
@NonNull
public Options withApiBaseUri(String apiBaseUri) {
- this.apiBaseUrl = apiBaseUrl;
+ this.apiBaseUrl = apiBaseUri;
return this;
}
diff --git a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java
index 763c97cca..07e5b7e16 100644
--- a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java
+++ b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java
@@ -4,7 +4,6 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.res.AssetManager;
import android.os.AsyncTask;
import android.os.Environment;
import android.support.annotation.Keep;
@@ -90,7 +89,7 @@ public class FileSource {
@UiThread
public static synchronized FileSource getInstance(@NonNull Context context) {
if (INSTANCE == null) {
- INSTANCE = new FileSource(getResourcesCachePath(context), context.getResources().getAssets());
+ INSTANCE = new FileSource(getResourcesCachePath(context));
}
return INSTANCE;
@@ -366,8 +365,8 @@ public class FileSource {
@Keep
private long nativePtr;
- private FileSource(String cachePath, AssetManager assetManager) {
- initialize(Mapbox.getAccessToken(), cachePath, assetManager);
+ private FileSource(String cachePath) {
+ initialize(Mapbox.getAccessToken(), cachePath);
}
@Keep
@@ -404,7 +403,7 @@ public class FileSource {
private native void setResourceCachePath(String path, ResourcesCachePathChangeCallback callback);
@Keep
- private native void initialize(String accessToken, String cachePath, AssetManager assetManager);
+ private native void initialize(String accessToken, String cachePath);
@Override
@Keep
diff --git a/MapboxGLAndroidSDK/src/main/res-public/values/public.xml b/MapboxGLAndroidSDK/src/main/res-public/values/public.xml
index 60a1efc77..36071cc2a 100644
--- a/MapboxGLAndroidSDK/src/main/res-public/values/public.xml
+++ b/MapboxGLAndroidSDK/src/main/res-public/values/public.xml
@@ -69,6 +69,7 @@
+
diff --git a/MapboxGLAndroidSDK/src/main/res/values/attrs.xml b/MapboxGLAndroidSDK/src/main/res/values/attrs.xml
index ff8a32ac6..137f72f8d 100644
--- a/MapboxGLAndroidSDK/src/main/res/values/attrs.xml
+++ b/MapboxGLAndroidSDK/src/main/res/values/attrs.xml
@@ -109,6 +109,7 @@
+
diff --git a/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/AttributionDialogManagerTest.java b/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/AttributionDialogManagerTest.java
new file mode 100644
index 000000000..9b4eeb27a
--- /dev/null
+++ b/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/AttributionDialogManagerTest.java
@@ -0,0 +1,99 @@
+package com.mapbox.mapboxsdk.maps;
+
+import android.content.Context;
+
+import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.robolectric.RobolectricTestRunner;
+
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(RobolectricTestRunner.class)
+public class AttributionDialogManagerTest {
+ @InjectMocks
+ Context context = mock(Context.class);
+
+ @InjectMocks
+ MapboxMap mapboxMap = mock(MapboxMap.class);
+
+ @InjectMocks
+ Style style = mock(Style.class);
+
+ private AttributionDialogManager attributionDialogManager;
+ private CameraPosition cameraPosition;
+
+ private static final String ASSERT_MAPBOX_TOKEN = "TestAccessToken";
+
+ private static final String ASSERT_MAPBOX_STYLE_URI = "mapbox://styles/mapbox/streets-v11";
+ private static final String ASSERT_MAPBOX_LOCAL_STYLE_URI = "asset://style.json";
+
+ private static final String ASSERT_MAPBOX_PACKAGE_NAME = "com.mapbox.attributionmanagertest";
+
+ private static final String ASSERT_MAPBOX_FEEDBACK_FINAL_URL =
+ "https://apps.mapbox.com/feedback?referrer=com.mapbox.attributionmanagertest&"
+ + "access_token=TestAccessToken&owner=mapbox&id=streets-v11"
+ + "#/22.200001/11.100000/12.000000/24.000000/5";
+ private static final String ASSERT_MAPBOX_FEEDHACK_FINAL_URL_LOCAL_STYLE =
+ "https://apps.mapbox.com/feedback?referrer=com.mapbox.attributionmanagertest&"
+ + "access_token=TestAccessToken#/22.200001/11.100000/12.000000/24.000000/5";
+ private static final String ASSERT_MAPBOX_FEEDBACL_FINAL_URL_NULL_CAMERA_POSITION =
+ "https://apps.mapbox.com/feedback?referrer=com.mapbox.attributionmanagertest&access_token=TestAccessToken";
+
+ @Before
+ public void beforeTest() {
+ attributionDialogManager = new AttributionDialogManager(context, mapboxMap);
+ cameraPosition = new CameraPosition.Builder(CameraPosition.DEFAULT)
+ .tilt(5.0f).zoom(12).bearing(24.0f).target(new LatLng(11.1f, 22.2f)).build();
+ }
+
+ @Test
+ public void testSanity() {
+ assertNotNull("AttributionDialogManager should not be null", attributionDialogManager);
+ }
+
+ @Test
+ public void testBuildMapFeedbackMapUrl() {
+ when(context.getApplicationContext()).thenReturn(context);
+ when(context.getPackageName()).thenReturn(ASSERT_MAPBOX_PACKAGE_NAME);
+ when(style.getUri()).thenReturn(ASSERT_MAPBOX_STYLE_URI);
+ when(mapboxMap.getCameraPosition()).thenReturn(cameraPosition);
+ when(mapboxMap.getStyle()).thenReturn(style);
+
+ Assert.assertEquals(ASSERT_MAPBOX_FEEDBACK_FINAL_URL,
+ attributionDialogManager.buildMapFeedbackMapUrl(ASSERT_MAPBOX_TOKEN));
+ }
+
+ @Test
+ public void testBuildMapFeedbackMapUrlWithLocalStyleJson() {
+ when(context.getApplicationContext()).thenReturn(context);
+ when(context.getPackageName()).thenReturn(ASSERT_MAPBOX_PACKAGE_NAME);
+ when(style.getUri()).thenReturn(ASSERT_MAPBOX_LOCAL_STYLE_URI);
+ when(mapboxMap.getCameraPosition()).thenReturn(cameraPosition);
+ when(mapboxMap.getStyle()).thenReturn(style);
+
+ Assert.assertEquals(ASSERT_MAPBOX_FEEDHACK_FINAL_URL_LOCAL_STYLE,
+ attributionDialogManager.buildMapFeedbackMapUrl(ASSERT_MAPBOX_TOKEN));
+ }
+
+ @Test
+ public void testBuildMapFeedbackMapUrlWithNullCameraPosition() {
+ when(context.getApplicationContext()).thenReturn(context);
+ when(context.getPackageName()).thenReturn(ASSERT_MAPBOX_PACKAGE_NAME);
+ when(style.getUri()).thenReturn(ASSERT_MAPBOX_LOCAL_STYLE_URI);
+ when(mapboxMap.getCameraPosition()).thenReturn(null);
+ when(mapboxMap.getStyle()).thenReturn(style);
+
+ Assert.assertEquals(ASSERT_MAPBOX_FEEDBACL_FINAL_URL_NULL_CAMERA_POSITION,
+ attributionDialogManager.buildMapFeedbackMapUrl(ASSERT_MAPBOX_TOKEN));
+ }
+
+
+}
diff --git a/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapOptionsTest.java b/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapOptionsTest.java
index 6978afcf1..c46e6e319 100644
--- a/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapOptionsTest.java
+++ b/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapOptionsTest.java
@@ -167,6 +167,16 @@ public class MapboxMapOptionsTest {
assertFalse(new MapboxMapOptions().setPrefetchesTiles(false).getPrefetchesTiles());
}
+ @Test
+ public void testPrefetchZoomDelta() {
+ // Default value
+ assertEquals(4, new MapboxMapOptions().getPrefetchZoomDelta());
+
+ // Check mutations
+ assertEquals(5, new MapboxMapOptions().setPrefetchZoomDelta(5).getPrefetchZoomDelta());
+ }
+
+
@Test
public void testCrossSourceCollisions() {
// Default value
diff --git a/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.kt b/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.kt
index deb5f603c..6647fe559 100644
--- a/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.kt
+++ b/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.kt
@@ -126,6 +126,18 @@ class MapboxMapTest {
verify { nativeMapView.prefetchTiles = true }
}
+ @Test
+ fun testGetPrefetchZoomDelta() {
+ every { nativeMapView.prefetchZoomDelta } answers { 3 }
+ assertEquals(3, mapboxMap.prefetchZoomDelta)
+ }
+
+ @Test
+ fun testSetPrefetchZoomDelta() {
+ mapboxMap.prefetchZoomDelta = 2
+ verify { nativeMapView.prefetchZoomDelta = 2 }
+ }
+
@Test
fun testCameraForLatLngBounds() {
val bounds = LatLngBounds.Builder().include(LatLng()).include(LatLng(1.0, 1.0)).build()
diff --git a/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/UiSettingsTest.java b/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/UiSettingsTest.java
index cfcf0a048..a84e93cd7 100644
--- a/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/UiSettingsTest.java
+++ b/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/UiSettingsTest.java
@@ -5,6 +5,7 @@ import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
+import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.maps.widgets.CompassView;
import org.junit.Before;
@@ -17,6 +18,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
public class UiSettingsTest {
@@ -412,4 +414,20 @@ public class UiSettingsTest {
assertEquals("Zoom rate should be 0.83f", 0.83f,
uiSettings.getZoomRate(), 0);
}
+
+ @Test
+ public void testUpdateWhenCompassViewNotHidden() {
+ CameraPosition cameraPosition = new CameraPosition.Builder(CameraPosition.DEFAULT).bearing(24.0f).build();
+ when(compassView.isHidden()).thenReturn(false);
+ uiSettings.update(cameraPosition);
+ verify(compassView).update(-24.0f);
+ }
+
+ @Test
+ public void testUpdateWhenCompassViewHidden() {
+ CameraPosition cameraPosition = new CameraPosition.Builder(CameraPosition.DEFAULT).bearing(24.0f).build();
+ when(compassView.isHidden()).thenReturn(true);
+ uiSettings.update(cameraPosition);
+ verify(compassView).update(-24.0f);
+ }
}
diff --git a/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt b/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt
index fb113502e..51c9e1c10 100644
--- a/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt
+++ b/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt
@@ -1288,6 +1288,36 @@ class LocationComponentTest : EspressoTest() {
executeComponentTest(componentAction)
}
+ @Test
+ fun animators_dontZoomWhileTransitioning() {
+ val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction {
+ override fun onLocationComponentAction(
+ component: LocationComponent,
+ mapboxMap: MapboxMap,
+ style: Style,
+ uiController: UiController,
+ context: Context
+ ) {
+ component.activateLocationComponent(LocationComponentActivationOptions
+ .builder(context, style)
+ .useDefaultLocationEngine(false)
+ .build())
+ component.isLocationComponentEnabled = true
+ component.forceLocationUpdate(location)
+
+ val zoom = mapboxMap.cameraPosition.zoom
+ component.setCameraMode(CameraMode.TRACKING_GPS, 500L, null, null, null, null)
+ component.zoomWhileTracking(16.0, 1000)
+ uiController.loopMainThreadForAtLeast(1000)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
+
+ assertEquals(zoom, mapboxMap.cameraPosition.zoom, 0.0001)
+ }
+ }
+
+ executeComponentTest(componentAction)
+ }
+
@Test
@Ignore
fun animators_cancelZoomWhileTracking() {
@@ -1433,6 +1463,36 @@ class LocationComponentTest : EspressoTest() {
executeComponentTest(componentAction)
}
+ @Test
+ fun animators_dontTiltWhileTransitioning() {
+ val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction {
+ override fun onLocationComponentAction(
+ component: LocationComponent,
+ mapboxMap: MapboxMap,
+ style: Style,
+ uiController: UiController,
+ context: Context
+ ) {
+ component.activateLocationComponent(LocationComponentActivationOptions
+ .builder(context, style)
+ .useDefaultLocationEngine(false)
+ .build())
+ component.isLocationComponentEnabled = true
+ component.forceLocationUpdate(location)
+
+ val tilt = mapboxMap.cameraPosition.tilt
+ component.setCameraMode(CameraMode.TRACKING_GPS, 500L, null, null, null, null)
+ component.tiltWhileTracking(30.0, 1000)
+ uiController.loopMainThreadForAtLeast(1000)
+ TestingAsyncUtils.waitForLayer(uiController, mapView)
+
+ assertEquals(tilt, mapboxMap.cameraPosition.tilt, 0.0001)
+ }
+ }
+
+ executeComponentTest(componentAction)
+ }
+
@Test
@Ignore
fun animators_cancelTiltWhileTracking() {
diff --git a/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/NativeMapViewTest.kt b/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/NativeMapViewTest.kt
index b13bb6b79..dc313b5f6 100644
--- a/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/NativeMapViewTest.kt
+++ b/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/NativeMapViewTest.kt
@@ -221,6 +221,23 @@ class NativeMapViewTest : AppCenter() {
assertEquals("Flag should match", expected, actual)
}
+ @Test
+ @UiThreadTest
+ fun testPrefetchZoomDelta() {
+ val expected = 2
+ nativeMapView.prefetchZoomDelta = 2
+ val actual = nativeMapView.prefetchZoomDelta
+ assertEquals("Prefetch zoom delta should match", expected, actual)
+ }
+
+ @Test
+ @UiThreadTest
+ fun testPrefetchZoomDeltaDefault() {
+ val expected = 4
+ val actual = nativeMapView.prefetchZoomDelta
+ assertEquals("Prefetch zoom delta should match", expected, actual)
+ }
+
@Test
@UiThreadTest
fun testSetContentPadding() {
@@ -254,7 +271,7 @@ class NativeMapViewTest : AppCenter() {
@Test
@UiThreadTest
fun testGetProjectedMetersAtLatitude() {
- val expected = 38986.83510557766
+ val expected = 77973.67021115532
val actual = nativeMapView.getMetersPerPixelAtLatitude(5.0)
assertEquals("Get projected meters should match", expected, actual)
}
diff --git a/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseTest.java b/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseTest.java
index 45dac2361..b6c16c814 100644
--- a/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseTest.java
+++ b/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseTest.java
@@ -4,6 +4,7 @@ import android.content.Context;
import android.support.annotation.CallSuper;
import android.support.annotation.UiThread;
import android.support.test.rule.ActivityTestRule;
+import android.support.test.rule.GrantPermissionRule;
import com.mapbox.mapboxsdk.AppCenter;
import com.mapbox.mapboxsdk.Mapbox;
@@ -35,6 +36,10 @@ public abstract class BaseTest extends AppCenter {
@Rule
public TestName testName = new TestName();
+ @Rule
+ public GrantPermissionRule grantLocationPermissionRule = GrantPermissionRule
+ .grant(android.Manifest.permission.ACCESS_FINE_LOCATION);
+
protected MapboxMap mapboxMap;
protected MapView mapView;
private final CountDownLatch latch = new CountDownLatch(1);
@@ -75,7 +80,12 @@ public abstract class BaseTest extends AppCenter {
try {
rule.runOnUiThread(() -> {
mapView = rule.getActivity().findViewById(R.id.mapView);
- mapView.getMapAsync(this::initMap);
+ if (mapView != null) {
+ mapView.getMapAsync(this::initMap);
+ } else {
+ Timber.w("Skipping map load test since mapView is not found.");
+ latch.countDown();
+ }
});
} catch (Throwable throwable) {
throwable.printStackTrace();
diff --git a/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java b/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java
index 05337081d..d8fd42876 100644
--- a/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java
+++ b/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java
@@ -151,6 +151,9 @@ public class BulkMarkerActivity extends AppCompatActivity implements AdapterView
@Override
protected void onDestroy() {
super.onDestroy();
+ if (progressDialog != null) {
+ progressDialog.dismiss();
+ }
mapView.onDestroy();
}
diff --git a/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java b/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java
index 40ea7509b..a0e8b31fc 100644
--- a/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java
+++ b/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java
@@ -81,7 +81,9 @@ public class MapFragmentActivity extends AppCompatActivity implements MapFragmen
@Override
protected void onDestroy() {
super.onDestroy();
- mapView.removeOnDidFinishRenderingFrameListener(this);
+ if (mapView != null) {
+ mapView.removeOnDidFinishRenderingFrameListener(this);
+ }
}
@Override
diff --git a/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/LocationFragmentActivity.kt b/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/LocationFragmentActivity.kt
index ff2afb50c..7e18cbfa2 100644
--- a/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/LocationFragmentActivity.kt
+++ b/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/LocationFragmentActivity.kt
@@ -116,7 +116,7 @@ class LocationFragmentActivity : AppCompatActivity() {
}
override fun onSuccess(result: LocationEngineResult?) {
- mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(result?.lastLocation), 12.0))
+ if (!mapView.isDestroyed) mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(result?.lastLocation), 12.0))
}
override fun onFailure(exception: Exception) {
diff --git a/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/snapshot/MapSnapshotterActivity.java b/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/snapshot/MapSnapshotterActivity.java
index 59c708266..ab7ffed83 100644
--- a/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/snapshot/MapSnapshotterActivity.java
+++ b/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/snapshot/MapSnapshotterActivity.java
@@ -89,6 +89,7 @@ public class MapSnapshotterActivity extends AppCompatActivity {
.bearing(randomInRange(0, 360))
.tilt(randomInRange(0, 60))
.zoom(randomInRange(0, 20))
+ .padding(1, 1, 1, 1)
.build()
);
}
diff --git a/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolGeneratorActivity.java b/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolGeneratorActivity.java
index 24bfe62e7..e80d6fe3e 100644
--- a/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolGeneratorActivity.java
+++ b/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolGeneratorActivity.java
@@ -362,7 +362,12 @@ public class SymbolGeneratorActivity extends AppCompatActivity implements OnMapR
@Override
protected void onPostExecute(HashMap bitmapHashMap) {
super.onPostExecute(bitmapHashMap);
- mapboxMap.getStyle().addImagesAsync(bitmapHashMap);
+ mapboxMap.getStyle(new Style.OnStyleLoaded() {
+ @Override
+ public void onStyleLoaded(@NonNull Style style) {
+ style.addImagesAsync(bitmapHashMap);
+ }
+ });
}
}
}
\ No newline at end of file
diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle
index c1c489472..31633488e 100644
--- a/gradle/dependencies.gradle
+++ b/gradle/dependencies.gradle
@@ -7,7 +7,7 @@ ext {
]
versions = [
- mapboxServices : '4.9.0-alpha.1',
+ mapboxServices : '4.9.0',
mapboxTelemetry : '4.5.1',
mapboxCore : '1.3.0',
mapboxGestures : '0.5.1',
diff --git a/gradle/jacoco-report.gradle b/gradle/jacoco-report.gradle
index c4e0bb913..64c99e09f 100644
--- a/gradle/jacoco-report.gradle
+++ b/gradle/jacoco-report.gradle
@@ -15,7 +15,7 @@ task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest']) {
}
def fileExcludes = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*']
- def debugTree = fileTree(dir: "${project.buildDir}/intermediates/javac/debug/compileDebugJavaWithJavac/classes", excludes: fileExcludes)
+ def debugTree = fileTree(dir: "${project.buildDir}/intermediates/javac/debug/classes", excludes: fileExcludes)
def mainSrc = "${project.projectDir}/src/main/java"
println(mainSrc)
def ecSrc = fileTree(dir: "$project.buildDir", include: "**/*.ec")
diff --git a/scripts/exclude-activity-gen.json b/scripts/exclude-activity-gen.json
index 0f5bb81b5..ab84957e3 100644
--- a/scripts/exclude-activity-gen.json
+++ b/scripts/exclude-activity-gen.json
@@ -5,7 +5,6 @@
"MapSnapshotterLocalStyleActivity",
"LatLngBoundsActivity",
"BottomSheetActivity",
- "MapSnapshotterActivity",
"MockLocationEngine",
"DeleteRegionActivity",
"RealTimeGeoJsonActivity",
@@ -50,7 +49,5 @@
"EspressoTestActivity",
"FragmentBackStackActivity",
"ChildFragmentMapInDialogActivity",
- "PerformanceMeasurementActivity",
- "DownloadRegionActivity",
- "CacheManagementActivity"
+ "PerformanceMeasurementActivity"
]
diff --git a/src/file_source.cpp b/src/file_source.cpp
index 05b57e5d1..a002d6616 100644
--- a/src/file_source.cpp
+++ b/src/file_source.cpp
@@ -1,5 +1,7 @@
#include "file_source.hpp"
+
#include "attach_env.hpp"
+#include "mapbox.hpp"
#include
#include
@@ -14,8 +16,15 @@
namespace mbgl {
std::shared_ptr FileSource::createPlatformFileSource(const ResourceOptions& options) {
- auto* assetFileSource = reinterpret_cast(options.platformContext());
- auto fileSource = std::make_shared(options.cachePath(), std::unique_ptr(assetFileSource));
+ auto env{android::AttachEnv()};
+ std::shared_ptr fileSource;
+ if (android::Mapbox::hasInstance(*env)) {
+ auto assetManager = android::Mapbox::getAssetManager(*env);
+ fileSource = std::make_shared(options.cachePath(),
+ std::make_unique(*env, assetManager));
+ } else {
+ fileSource = std::make_shared(options.cachePath(), options.assetPath());
+ }
fileSource->setAccessToken(options.accessToken());
return fileSource;
}
@@ -24,17 +33,12 @@ namespace android {
// FileSource //
-FileSource::FileSource(jni::JNIEnv& _env,
- const jni::String& accessToken,
- const jni::String& _cachePath,
- const jni::Object& assetManager) {
+FileSource::FileSource(jni::JNIEnv& _env, const jni::String& accessToken, const jni::String& _cachePath) {
std::string path = jni::Make(_env, _cachePath);
mapbox::sqlite::setTempPath(path);
- resourceOptions
- .withAccessToken(accessToken ? jni::Make(_env, accessToken) : "")
- .withCachePath(path + DATABASE_FILE)
- .withPlatformContext(reinterpret_cast(new AssetManagerFileSource(_env, assetManager)));
+ resourceOptions.withAccessToken(accessToken ? jni::Make(_env, accessToken) : "")
+ .withCachePath(path + DATABASE_FILE);
// Create a core default file source
fileSource = std::static_pointer_cast(mbgl::FileSource::getSharedFileSource(resourceOptions));
@@ -58,14 +62,15 @@ void FileSource::setAPIBaseUrl(jni::JNIEnv& env, const jni::String& url) {
void FileSource::setResourceTransform(jni::JNIEnv& env, const jni::Object& transformCallback) {
if (transformCallback) {
auto global = jni::NewGlobal(env, transformCallback);
- resourceTransform = std::make_unique>(*Scheduler::GetCurrent(),
+ resourceTransform = std::make_unique>(
+ *Scheduler::GetCurrent(),
// Capture the ResourceTransformCallback object as a managed global into
// the lambda. It is released automatically when we're setting a new ResourceTransform in
// a subsequent call.
// Note: we're converting it to shared_ptr because this lambda is converted to a std::function,
// which requires copyability of its captured variables.
- [callback = std::make_shared(std::move(global))]
- (mbgl::Resource::Kind kind, const std::string&& url_) {
+ [callback = std::make_shared(std::move(global))](mbgl::Resource::Kind kind,
+ const std::string& url_) {
android::UniqueEnv _env = android::AttachEnv();
return FileSource::ResourceTransformCallback::onURL(*_env, *callback, int(kind), url_);
});
@@ -170,20 +175,20 @@ void FileSource::registerNative(jni::JNIEnv& env) {
#define METHOD(MethodPtr, name) jni::MakeNativePeerMethod(name)
// Register the peer
- jni::RegisterNativePeer(
- env, javaClass, "nativePtr",
- jni::MakePeer&>,
- "initialize",
- "finalize",
- METHOD(&FileSource::getAccessToken, "getAccessToken"),
- METHOD(&FileSource::setAccessToken, "setAccessToken"),
- METHOD(&FileSource::setAPIBaseUrl, "setApiBaseUrl"),
- METHOD(&FileSource::setResourceTransform, "setResourceTransform"),
- METHOD(&FileSource::setResourceCachePath, "setResourceCachePath"),
- METHOD(&FileSource::resume, "activate"),
- METHOD(&FileSource::pause, "deactivate"),
- METHOD(&FileSource::isResumed, "isActivated")
- );
+ jni::RegisterNativePeer(env,
+ javaClass,
+ "nativePtr",
+ jni::MakePeer,
+ "initialize",
+ "finalize",
+ METHOD(&FileSource::getAccessToken, "getAccessToken"),
+ METHOD(&FileSource::setAccessToken, "setAccessToken"),
+ METHOD(&FileSource::setAPIBaseUrl, "setApiBaseUrl"),
+ METHOD(&FileSource::setResourceTransform, "setResourceTransform"),
+ METHOD(&FileSource::setResourceCachePath, "setResourceCachePath"),
+ METHOD(&FileSource::resume, "activate"),
+ METHOD(&FileSource::pause, "deactivate"),
+ METHOD(&FileSource::isResumed, "isActivated"));
}
diff --git a/src/file_source.hpp b/src/file_source.hpp
index f3ad33eb3..6a9190fa0 100644
--- a/src/file_source.hpp
+++ b/src/file_source.hpp
@@ -41,7 +41,7 @@ public:
const jni::String&);
};
- FileSource(jni::JNIEnv&, const jni::String&, const jni::String&, const jni::Object&);
+ FileSource(jni::JNIEnv&, const jni::String&, const jni::String&);
~FileSource();
diff --git a/src/i18n/collator.cpp b/src/i18n/collator.cpp
new file mode 100644
index 000000000..b3dd8e21b
--- /dev/null
+++ b/src/i18n/collator.cpp
@@ -0,0 +1,194 @@
+#include
+#include
+
+#include
+
+#include "../attach_env.hpp"
+#include "collator_jni.hpp"
+
+namespace mbgl {
+namespace android {
+
+void Collator::registerNative(jni::JNIEnv& env) {
+ jni::Class::Singleton(env);
+}
+
+jni::Local> Collator::getInstance(jni::JNIEnv& env, const jni::Object& locale) {
+ static auto& javaClass = jni::Class::Singleton(env);
+ static auto method = javaClass.GetStaticMethod (jni::Object)>(env, "getInstance");
+ return javaClass.Call(env, method, locale);
+}
+
+void Collator::setStrength(jni::JNIEnv& env, const jni::Object& collator, jni::jint strength) {
+ static auto& javaClass = jni::Class::Singleton(env);
+ static auto method = javaClass.GetMethod(env, "setStrength");
+ collator.Call(env, method, strength);
+}
+
+jni::jint Collator::compare(jni::JNIEnv& env, const jni::Object& collator, const jni::String& lhs, const jni::String& rhs) {
+ static auto& javaClass = jni::Class::Singleton(env);
+ static auto method = javaClass.GetMethod(env, "compare");
+ return collator.Call(env, method, lhs, rhs);
+}
+
+void StringUtils::registerNative(jni::JNIEnv& env) {
+ jni::Class::Singleton(env);
+}
+
+jni::Local StringUtils::unaccent(jni::JNIEnv& env, const jni::String& value) {
+ static auto& javaClass = jni::Class::Singleton(env);
+ static auto method = javaClass.GetStaticMethod(env, "unaccent");
+ return javaClass.Call(env, method, value);
+}
+
+void Locale::registerNative(jni::JNIEnv& env) {
+ jni::Class::Singleton(env);
+}
+
+/*
+We would prefer to use for/toLanguageTag, but they're only available in API level 21+
+
+jni::Object Locale::forLanguageTag(jni::JNIEnv& env, jni::String languageTag) {
+ using Signature = jni::Object(jni::String);
+ auto method = javaClass.GetStaticMethod(env, "forLanguageTag");
+ return javaClass.Call(env, method, languageTag);
+}
+
+jni::String Locale::toLanguageTag(jni::JNIEnv& env, jni::Object locale) {
+ using Signature = jni::String();
+ auto static method = javaClass.GetMethod(env, "toLanguageTag");
+ return locale.Call(env, method);
+}
+*/
+
+jni::Local Locale::getLanguage(jni::JNIEnv& env, const jni::Object& locale) {
+ static auto& javaClass = jni::Class::Singleton(env);
+ static auto method = javaClass.GetMethod(env, "getLanguage");
+ return locale.Call(env, method);
+}
+
+jni::Local Locale::getCountry(jni::JNIEnv& env, const jni::Object& locale) {
+ static auto& javaClass = jni::Class::Singleton(env);
+ static auto method = javaClass.GetMethod(env, "getCountry");
+ return locale.Call(env, method);
+}
+
+jni::Local> Locale::getDefault(jni::JNIEnv& env) {
+ static auto& javaClass = jni::Class::Singleton(env);
+ static auto method = javaClass.GetStaticMethod ()>(env, "getDefault");
+ return javaClass.Call(env, method);
+}
+
+jni::Local> Locale::New(jni::JNIEnv& env, const jni::String& language) {
+ static auto& javaClass = jni::Class::Singleton(env);
+ static auto constructor = javaClass.GetConstructor(env);
+ return javaClass.New(env, constructor, language);
+}
+
+jni::Local> Locale::New(jni::JNIEnv& env, const jni::String& language, const jni::String& region) {
+ static auto& javaClass = jni::Class::Singleton(env);
+ static auto constructor = javaClass.GetConstructor(env);
+ return javaClass.New(env, constructor, language, region);
+}
+
+} // namespace android
+
+namespace platform {
+
+class Collator::Impl {
+public:
+ Impl(bool caseSensitive_, bool diacriticSensitive_, optional locale_)
+ : caseSensitive(caseSensitive_)
+ , diacriticSensitive(diacriticSensitive_)
+ , env(android::AttachEnv())
+ {
+ LanguageTag languageTag = locale_ ? LanguageTag::fromBCP47(*locale_) : LanguageTag();
+ if (!languageTag.language) {
+ locale = jni::NewGlobal(*env,
+ android::Locale::getDefault(*env));
+ } else if (!languageTag.region) {
+ locale = jni::NewGlobal(*env,
+ android::Locale::New(*env, jni::Make(*env, *languageTag.language)));
+ } else {
+ locale = jni::NewGlobal(*env,
+ android::Locale::New(*env, jni::Make(*env, *languageTag.language),
+ jni::Make(*env, *languageTag.region)));
+ }
+ collator = jni::NewGlobal(*env, android::Collator::getInstance(*env, locale));
+ if (!diacriticSensitive && !caseSensitive) {
+ android::Collator::setStrength(*env, collator, 0 /*PRIMARY*/);
+ } else if (diacriticSensitive && !caseSensitive) {
+ android::Collator::setStrength(*env, collator, 1 /*SECONDARY*/);
+ } else if (caseSensitive) {
+ // If we're case-sensitive and diacritic-sensitive, we use a case-sensitive collator
+ // and a fallback implementation of diacritic-insensitivity.
+ android::Collator::setStrength(*env, collator, 2 /*TERTIARY*/);
+ }
+ }
+
+ bool operator==(const Impl& other) const {
+ return caseSensitive == other.caseSensitive &&
+ diacriticSensitive == other.diacriticSensitive &&
+ resolvedLocale() == other.resolvedLocale();
+ }
+
+ int compare(const std::string& lhs, const std::string& rhs) const {
+ bool useUnaccent = !diacriticSensitive && caseSensitive;
+ // java.text.Collator doesn't support a diacritic-insensitive/case-sensitive collation
+ // order, so we have to compromise here. We use Android's case-sensitive Collator
+ // against strings that have been "unaccented" using non-locale-aware nunicode logic.
+ // Because of the difference in locale-awareness, this means turning on case-sensitivity
+ // can _potentially_ change compare results for strings that don't actually have any case
+ // differences.
+ jni::Local jlhs = useUnaccent
+ ? android::StringUtils::unaccent(*env, jni::Make(*env, lhs))
+ : jni::Make(*env, lhs);
+ jni::Local jrhs = useUnaccent
+ ? android::StringUtils::unaccent(*env, jni::Make(*env, rhs))
+ : jni::Make(*env, rhs);
+
+ jni::jint result = android::Collator::compare(*env, collator, jlhs, jrhs);
+
+ return result;
+ }
+
+ std::string resolvedLocale() const {
+ std::string language = jni::Make(*env, android::Locale::getLanguage(*env, locale));
+ std::string region = jni::Make(*env, android::Locale::getCountry(*env, locale));
+
+ optional resultLanguage;
+ if (!language.empty()) resultLanguage = language;
+ optional resultRegion;
+ if (!region.empty()) resultRegion = region;
+
+ return LanguageTag(resultLanguage, {}, resultRegion).toBCP47();
+ }
+
+private:
+ bool caseSensitive;
+ bool diacriticSensitive;
+
+ android::UniqueEnv env;
+ jni::Global> collator;
+ jni::Global> locale;
+};
+
+
+Collator::Collator(bool caseSensitive, bool diacriticSensitive, optional locale_)
+ : impl(std::make_shared(caseSensitive, diacriticSensitive, std::move(locale_)))
+{}
+
+bool Collator::operator==(const Collator& other) const {
+ return *impl == *(other.impl);
+}
+
+int Collator::compare(const std::string& lhs, const std::string& rhs) const {
+ return impl->compare(lhs, rhs);
+}
+
+std::string Collator::resolvedLocale() const {
+ return impl->resolvedLocale();
+}
+
+} // namespace platform
+} // namespace mbgl
diff --git a/src/i18n/collator_jni.hpp b/src/i18n/collator_jni.hpp
new file mode 100644
index 000000000..612f9b49f
--- /dev/null
+++ b/src/i18n/collator_jni.hpp
@@ -0,0 +1,62 @@
+#pragma once
+
+#include
+
+/*
+ android::Collator and android::Locale are
+ the JNI wrappers of
+ java/text/Collator and java/util/Locale
+
+ mbgl::Collator is the portable interface
+ Both implementations are in collator.cpp
+ */
+
+namespace mbgl {
+namespace android {
+
+class Locale {
+public:
+ static constexpr auto Name() { return "java/util/Locale"; };
+
+ /* Requires API level 21+ in order to support script/variant
+ static jni::Object forLanguageTag(jni::JNIEnv&, jni::String);
+ static jni::String toLanguageTag(jni::JNIEnv&, jni::Object);
+ */
+ static jni::Local> getDefault(jni::JNIEnv&);
+ static jni::Local getLanguage(jni::JNIEnv&, const jni::Object&);
+ static jni::Local getCountry(jni::JNIEnv&, const jni::Object&);
+
+ static jni::Local> New(jni::JNIEnv&, const jni::String&);
+ static jni::Local> New(jni::JNIEnv&, const jni::String&, const jni::String&);
+
+
+ static void registerNative(jni::JNIEnv&);
+};
+
+class Collator {
+public:
+ static constexpr auto Name() { return "java/text/Collator"; };
+
+ static jni::Local> getInstance(jni::JNIEnv&, const jni::Object&);
+
+ static void setStrength(jni::JNIEnv&, const jni::Object&, jni::jint);
+
+ static jni::jint compare(jni::JNIEnv&, const jni::Object&, const jni::String&, const jni::String&);
+
+
+ static void registerNative(jni::JNIEnv&);
+};
+
+
+class StringUtils {
+public:
+ static constexpr auto Name() { return "com/mapbox/mapboxsdk/utils/StringUtils"; };
+
+ static jni::Local unaccent(jni::JNIEnv&, const jni::String&);
+
+
+ static void registerNative(jni::JNIEnv&);
+};
+
+} // namespace android
+} // namespace mbgl
diff --git a/src/i18n/number_format.cpp b/src/i18n/number_format.cpp
new file mode 100644
index 000000000..c8e0b7056
--- /dev/null
+++ b/src/i18n/number_format.cpp
@@ -0,0 +1,80 @@
+#include
+#include
+
+#include
+
+#include "../attach_env.hpp"
+#include "number_format_jni.hpp"
+
+namespace mbgl {
+namespace android {
+
+void NumberFormat::registerNative(jni::JNIEnv& env) {
+ jni::Class::Singleton(env);
+}
+
+jni::Local> NumberFormat::getInstance(jni::JNIEnv& env, const jni::Object& locale) {
+ static auto& javaClass = jni::Class::Singleton(env);
+ static auto method = javaClass.GetStaticMethod (jni::Object)>(env, "getInstance");
+ return javaClass.Call(env, method, locale);
+}
+
+jni::Local> NumberFormat::getCurrencyInstance(jni::JNIEnv& env, const jni::Object& locale) {
+ static auto& javaClass = jni::Class::Singleton(env);
+ static auto method = javaClass.GetStaticMethod (jni::Object)>(env, "getCurrencyInstance");
+ return javaClass.Call(env, method, locale);
+}
+
+jni::Local NumberFormat::format(jni::JNIEnv& env, const jni::Object& nf, jni::jdouble number) {
+ static auto& javaClass = jni::Class::Singleton(env);
+ static auto method = javaClass.GetMethod(env, "format");
+ return nf.Call(env, method, number);
+}
+
+void NumberFormat::setMinimumFractionDigits(jni::JNIEnv& env, const jni::Object& nf, jni::jint value) {
+ static auto& javaClass = jni::Class::Singleton(env);
+ static auto method = javaClass.GetMethod(env, "setMinimumFractionDigits");
+ return nf.Call(env, method, value);
+}
+
+void NumberFormat::setMaximumFractionDigits(jni::JNIEnv& env, const jni::Object& nf, jni::jint value) {
+ static auto& javaClass = jni::Class::Singleton(env);
+ static auto method = javaClass.GetMethod(env, "setMaximumFractionDigits");
+ return nf.Call(env, method, value);
+}
+
+} // namespace android
+
+namespace platform {
+
+std::string formatNumber(double number, const std::string& localeId, const std::string& currency,
+ uint8_t minFractionDigits, uint8_t maxFractionDigits) {
+
+ auto env{ android::AttachEnv() };
+
+ jni::Global> locale;
+ LanguageTag languageTag = !localeId.empty() ? LanguageTag::fromBCP47(localeId) : LanguageTag();
+ if (!languageTag.language) {
+ locale = jni::NewGlobal(*env, android::Locale::getDefault(*env));
+ } else if (!languageTag.region) {
+ locale = jni::NewGlobal(*env, android::Locale::New(*env, jni::Make(*env, *languageTag.language)));
+ } else {
+ locale = jni::NewGlobal(*env, android::Locale::New(*env, jni::Make(*env, *languageTag.language),
+ jni::Make(*env, *languageTag.region)));
+ }
+
+ jni::Global> formatter;
+ if (currency.empty()) {
+ formatter = jni::NewGlobal(*env, android::NumberFormat::getInstance(*env, locale));
+ android::NumberFormat::setMinimumFractionDigits(*env, formatter, static_cast(minFractionDigits));
+ android::NumberFormat::setMaximumFractionDigits(*env, formatter, static_cast(maxFractionDigits));
+ } else {
+ formatter = jni::NewGlobal(*env, android::NumberFormat::getCurrencyInstance(*env, locale));
+ }
+
+ auto result = android::NumberFormat::format(*env, formatter, static_cast(number));
+ return jni::Make(*env, result);
+}
+
+} // namespace platform
+} // namespace mbgl
diff --git a/src/i18n/number_format_jni.hpp b/src/i18n/number_format_jni.hpp
new file mode 100644
index 000000000..172003892
--- /dev/null
+++ b/src/i18n/number_format_jni.hpp
@@ -0,0 +1,29 @@
+#pragma once
+
+#include
+
+#include "collator_jni.hpp"
+
+/*
+ android::NumberFormat is the JNI wrapper
+ of java/text/NumberFormat.
+ */
+
+namespace mbgl {
+namespace android {
+
+class NumberFormat {
+public:
+ static constexpr auto Name() { return "java/text/NumberFormat"; };
+
+ static jni::Local> getInstance(jni::JNIEnv&, const jni::Object&);
+ static jni::Local> getCurrencyInstance(jni::JNIEnv&, const jni::Object&);
+ static jni::Local format(jni::JNIEnv&, const jni::Object&, jni::jdouble);
+ static void setMinimumFractionDigits(jni::JNIEnv&, const jni::Object&, jni::jint);
+ static void setMaximumFractionDigits(jni::JNIEnv&, const jni::Object&, jni::jint);
+
+ static void registerNative(jni::JNIEnv&);
+};
+
+} // namespace android
+} // namespace mbgl
diff --git a/src/jni_native.cpp b/src/jni_native.cpp
old mode 100755
new mode 100644
index df96ba975..bcbdfcf48
--- a/src/jni_native.cpp
+++ b/src/jni_native.cpp
@@ -6,8 +6,8 @@
#include "bitmap.hpp"
#include "bitmap_factory.hpp"
#include "connectivity_listener.hpp"
-#include "conversion/conversion.hpp"
#include "conversion/collection.hpp"
+#include "conversion/conversion.hpp"
#include "file_source.hpp"
#include "geojson/feature.hpp"
#include "geojson/feature_collection.hpp"
@@ -32,6 +32,7 @@
#include "java_types.hpp"
#include "map_renderer.hpp"
#include "map_renderer_runnable.hpp"
+#include "mapbox.hpp"
#include "native_map_view.hpp"
#ifndef MBGL_MODULE_OFFLINE_DISABLE
#include "offline/offline_manager.hpp"
@@ -50,10 +51,10 @@
#include "snapshotter/map_snapshotter.hpp"
#include "snapshotter/map_snapshot.hpp"
#endif
-#include "text/collator_jni.hpp"
-#include "text/local_glyph_rasterizer_jni.hpp"
-#include "text/format_number_jni.hpp"
+#include "i18n/collator_jni.hpp"
+#include "i18n/number_format_jni.hpp"
#include "logger.hpp"
+#include "text/local_glyph_rasterizer_jni.hpp"
namespace mbgl {
namespace android {
@@ -158,6 +159,9 @@ void registerNatives(JavaVM *vm) {
// Logger
Logger::registerNative(env);
+
+ // AssetManager
+ Mapbox::registerNative(env);
}
} // namespace android
diff --git a/src/jni_native.hpp b/src/jni_native.hpp
index c8e284a52..1cc9a7e81 100644
--- a/src/jni_native.hpp
+++ b/src/jni_native.hpp
@@ -7,7 +7,7 @@
namespace mbgl {
namespace android {
-MBGL_PUBLIC void registerNatives(JavaVM* vm);
+MBGL_EXPORT void registerNatives(JavaVM* vm);
} // namespace android
} // namespace mbgl
diff --git a/src/map/camera_position.cpp b/src/map/camera_position.cpp
index 03aca79bd..4266b64fd 100644
--- a/src/map/camera_position.cpp
+++ b/src/map/camera_position.cpp
@@ -44,19 +44,20 @@ mbgl::CameraOptions CameraPosition::getCameraOptions(jni::JNIEnv& env, const jni
static auto tilt = javaClass.GetField(env, "tilt");
static auto zoom = javaClass.GetField(env, "zoom");
static auto paddingField = javaClass.GetField>(env, "padding");
- static auto padding = position.Get(env, paddingField);
+ auto padding = position.Get(env, paddingField);
auto center = LatLng::getLatLng(env, position.Get(env, target));
- return mbgl::CameraOptions {
- center,
- EdgeInsets {padding.Get(env, 1) * pixelRatio, padding.Get(env, 0) * pixelRatio,
- padding.Get(env, 3) * pixelRatio, padding.Get(env, 2) * pixelRatio},
- {},
- position.Get(env, zoom),
- position.Get(env, bearing),
- position.Get(env, tilt)
- };
+ return mbgl::CameraOptions{center,
+ padding && padding.Length(env) == 4 ? EdgeInsets{padding.Get(env, 1) * pixelRatio,
+ padding.Get(env, 0) * pixelRatio,
+ padding.Get(env, 3) * pixelRatio,
+ padding.Get(env, 2) * pixelRatio}
+ : (EdgeInsets){},
+ {},
+ position.Get(env, zoom),
+ position.Get(env, bearing),
+ position.Get(env, tilt)};
}
void CameraPosition::registerNative(jni::JNIEnv &env) {
diff --git a/src/map_renderer.cpp b/src/map_renderer.cpp
index 6be708b99..0c0e907f1 100644
--- a/src/map_renderer.cpp
+++ b/src/map_renderer.cpp
@@ -43,7 +43,7 @@ ActorRef MapRenderer::actor() const {
return *rendererRef;
}
-void MapRenderer::schedule(std::weak_ptr scheduled) {
+void MapRenderer::schedule(std::function scheduled) {
// Create a runnable
android::UniqueEnv _env = android::AttachEnv();
auto runnable = std::make_unique(*_env, std::move(scheduled));
diff --git a/src/map_renderer.hpp b/src/map_renderer.hpp
index 5a8ddeeb9..664da20a9 100644
--- a/src/map_renderer.hpp
+++ b/src/map_renderer.hpp
@@ -67,7 +67,7 @@ public:
// From Scheduler. Schedules by using callbacks to the
// JVM to process the mailbox on the right thread.
- void schedule(std::weak_ptr scheduled) override;
+ void schedule(std::function scheduled) override;
void requestRender();
diff --git a/src/map_renderer_runnable.cpp b/src/map_renderer_runnable.cpp
index 77c3aa301..227f49ee3 100644
--- a/src/map_renderer_runnable.cpp
+++ b/src/map_renderer_runnable.cpp
@@ -5,9 +5,8 @@
namespace mbgl {
namespace android {
-MapRendererRunnable::MapRendererRunnable(jni::JNIEnv& env, std::weak_ptr mailbox_)
- : mailbox(std::move(mailbox_)) {
-
+MapRendererRunnable::MapRendererRunnable(jni::JNIEnv& env, std::function function_)
+ : function(std::move(function_)) {
// Create the Java peer and hold on to a global reference
// Not using a weak reference here as this might oerflow
// the weak reference table on some devices
@@ -21,7 +20,7 @@ MapRendererRunnable::MapRendererRunnable(jni::JNIEnv& env, std::weak_ptr> MapRendererRunnable::peer() {
diff --git a/src/map_renderer_runnable.hpp b/src/map_renderer_runnable.hpp
index 21c4369b6..24d0f2af4 100644
--- a/src/map_renderer_runnable.hpp
+++ b/src/map_renderer_runnable.hpp
@@ -24,7 +24,7 @@ public:
static void registerNative(jni::JNIEnv&);
- MapRendererRunnable(jni::JNIEnv&, std::weak_ptr);
+ MapRendererRunnable(jni::JNIEnv&, std::function);
// Only for jni registration, unused
MapRendererRunnable(jni::JNIEnv&) {
@@ -40,7 +40,7 @@ public:
private:
jni::Global> javaPeer;
- std::weak_ptr mailbox;
+ std::function function;
};
} // namespace android
diff --git a/src/mapbox.cpp b/src/mapbox.cpp
new file mode 100644
index 000000000..5246739cf
--- /dev/null
+++ b/src/mapbox.cpp
@@ -0,0 +1,23 @@
+#include "mapbox.hpp"
+
+namespace mbgl {
+namespace android {
+
+jni::Local> Mapbox::getAssetManager(jni::JNIEnv& env) {
+ static auto& javaClass = jni::Class::Singleton(env);
+ auto method = javaClass.GetStaticMethod()>(env, "getAssetManager");
+ return javaClass.Call(env, method);
+}
+
+jboolean Mapbox::hasInstance(jni::JNIEnv& env) {
+ static auto& javaClass = jni::Class::Singleton(env);
+ auto method = javaClass.GetStaticMethod(env, "hasInstance");
+ return javaClass.Call(env, method);
+}
+
+void Mapbox::registerNative(jni::JNIEnv& env) {
+ jni::Class::Singleton(env);
+}
+
+} // namespace android
+} // namespace mbgl
diff --git a/src/mapbox.hpp b/src/mapbox.hpp
new file mode 100644
index 000000000..813f5bf17
--- /dev/null
+++ b/src/mapbox.hpp
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "asset_manager.hpp"
+
+#include
+
+namespace mbgl {
+namespace android {
+
+class Mapbox {
+public:
+ static constexpr auto Name() { return "com/mapbox/mapboxsdk/Mapbox"; };
+ static jboolean hasInstance(jni::JNIEnv&);
+ static jni::Local> getAssetManager(jni::JNIEnv&);
+ static void registerNative(jni::JNIEnv&);
+};
+
+} // namespace android
+} // namespace mbgl
diff --git a/src/native_map_view.cpp b/src/native_map_view.cpp
old mode 100755
new mode 100644
index 8ef757de1..8cb637fa3
--- a/src/native_map_view.cpp
+++ b/src/native_map_view.cpp
@@ -40,19 +40,19 @@
#include "style/conversion/filter.hpp"
#include "geojson/feature.hpp"
-#include "jni.hpp"
-#include "attach_env.hpp"
-#include "map_renderer.hpp"
#include "android_renderer_frontend.hpp"
-#include "file_source.hpp"
+#include "attach_env.hpp"
#include "bitmap.hpp"
-#include "run_loop_impl.hpp"
-#include "java/util.hpp"
-#include "geometry/lat_lng_bounds.hpp"
-#include "map/camera_position.hpp"
-#include "map/image.hpp"
-#include "style/light.hpp"
#include "bitmap_factory.hpp"
+#include "file_source.hpp"
+#include "geometry/lat_lng_bounds.hpp"
+#include "java/util.hpp"
+#include "jni.hpp"
+#include "map/camera_position.hpp"
+#include "map/image.hpp"
+#include "map_renderer.hpp"
+#include "run_loop_impl.hpp"
+#include "style/light.hpp"
namespace mbgl {
namespace android {
@@ -185,7 +185,7 @@ void NativeMapView::onWillStartRenderingFrame() {
}
}
-void NativeMapView::onDidFinishRenderingFrame(MapObserver::RenderMode mode, bool) {
+void NativeMapView::onDidFinishRenderingFrame(MapObserver::RenderFrameStatus status) {
assert(vm != nullptr);
android::UniqueEnv _env = android::AttachEnv();
@@ -193,7 +193,7 @@ void NativeMapView::onDidFinishRenderingFrame(MapObserver::RenderMode mode, bool
static auto onDidFinishRenderingFrame = javaClass.GetMethod(*_env, "onDidFinishRenderingFrame");
auto weakReference = javaPeer.get(*_env);
if (weakReference) {
- weakReference.Call(*_env, onDidFinishRenderingFrame, (jboolean) (mode != MapObserver::RenderMode::Partial));
+ weakReference.Call(*_env, onDidFinishRenderingFrame, (jboolean) (status.mode != MapObserver::RenderMode::Partial));
}
}
@@ -1050,6 +1050,14 @@ jni::jboolean NativeMapView::getPrefetchTiles(JNIEnv&) {
return jni::jboolean(map->getPrefetchZoomDelta() > 0);
}
+void NativeMapView::setPrefetchZoomDelta(JNIEnv&, jni::jint delta) {
+ map->setPrefetchZoomDelta(uint8_t(delta));
+}
+
+jni::jint NativeMapView::getPrefetchZoomDelta(JNIEnv&) {
+ return jni::jint(map->getPrefetchZoomDelta());
+}
+
mbgl::Map& NativeMapView::getMap() {
return *map;
}
@@ -1063,90 +1071,99 @@ void NativeMapView::registerNative(jni::JNIEnv& env) {
#define METHOD(MethodPtr, name) jni::MakeNativePeerMethod(name)
// Register the peer
- jni::RegisterNativePeer(env, javaClass, "nativePtr",
- jni::MakePeer&, const jni::Object&, const jni::Object&, jni::jfloat, jni::jboolean>,
- "nativeInitialize",
- "nativeDestroy",
- METHOD(&NativeMapView::resizeView, "nativeResizeView"),
- METHOD(&NativeMapView::getStyleUrl, "nativeGetStyleUrl"),
- METHOD(&NativeMapView::setStyleUrl, "nativeSetStyleUrl"),
- METHOD(&NativeMapView::getStyleJson, "nativeGetStyleJson"),
- METHOD(&NativeMapView::setStyleJson, "nativeSetStyleJson"),
- METHOD(&NativeMapView::cancelTransitions, "nativeCancelTransitions"),
- METHOD(&NativeMapView::setGestureInProgress, "nativeSetGestureInProgress"),
- METHOD(&NativeMapView::moveBy, "nativeMoveBy"),
- METHOD(&NativeMapView::jumpTo, "nativeJumpTo"),
- METHOD(&NativeMapView::easeTo, "nativeEaseTo"),
- METHOD(&NativeMapView::flyTo, "nativeFlyTo"),
- METHOD(&NativeMapView::getLatLng, "nativeGetLatLng"),
- METHOD(&NativeMapView::setLatLng, "nativeSetLatLng"),
- METHOD(&NativeMapView::getCameraForLatLngBounds, "nativeGetCameraForLatLngBounds"),
- METHOD(&NativeMapView::getCameraForGeometry, "nativeGetCameraForGeometry"),
- METHOD(&NativeMapView::setReachability, "nativeSetReachability"),
- METHOD(&NativeMapView::resetPosition, "nativeResetPosition"),
- METHOD(&NativeMapView::getPitch, "nativeGetPitch"),
- METHOD(&NativeMapView::setPitch, "nativeSetPitch"),
- METHOD(&NativeMapView::getZoom, "nativeGetZoom"),
- METHOD(&NativeMapView::setZoom, "nativeSetZoom"),
- METHOD(&NativeMapView::resetZoom, "nativeResetZoom"),
- METHOD(&NativeMapView::setMinZoom, "nativeSetMinZoom"),
- METHOD(&NativeMapView::getMinZoom, "nativeGetMinZoom"),
- METHOD(&NativeMapView::setMaxZoom, "nativeSetMaxZoom"),
- METHOD(&NativeMapView::getMaxZoom, "nativeGetMaxZoom"),
- METHOD(&NativeMapView::rotateBy, "nativeRotateBy"),
- METHOD(&NativeMapView::setBearing, "nativeSetBearing"),
- METHOD(&NativeMapView::setBearingXY, "nativeSetBearingXY"),
- METHOD(&NativeMapView::getBearing, "nativeGetBearing"),
- METHOD(&NativeMapView::resetNorth, "nativeResetNorth"),
- METHOD(&NativeMapView::setVisibleCoordinateBounds, "nativeSetVisibleCoordinateBounds"),
- METHOD(&NativeMapView::scheduleSnapshot, "nativeTakeSnapshot"),
- METHOD(&NativeMapView::getCameraPosition, "nativeGetCameraPosition"),
- METHOD(&NativeMapView::updateMarker, "nativeUpdateMarker"),
- METHOD(&NativeMapView::addMarkers, "nativeAddMarkers"),
- METHOD(&NativeMapView::setDebug, "nativeSetDebug"),
- METHOD(&NativeMapView::cycleDebugOptions, "nativeCycleDebugOptions"),
- METHOD(&NativeMapView::getDebug, "nativeGetDebug"),
- METHOD(&NativeMapView::isFullyLoaded, "nativeIsFullyLoaded"),
- METHOD(&NativeMapView::onLowMemory, "nativeOnLowMemory"),
- METHOD(&NativeMapView::getMetersPerPixelAtLatitude, "nativeGetMetersPerPixelAtLatitude"),
- METHOD(&NativeMapView::projectedMetersForLatLng, "nativeProjectedMetersForLatLng"),
- METHOD(&NativeMapView::pixelForLatLng, "nativePixelForLatLng"),
- METHOD(&NativeMapView::latLngForProjectedMeters, "nativeLatLngForProjectedMeters"),
- METHOD(&NativeMapView::latLngForPixel, "nativeLatLngForPixel"),
- METHOD(&NativeMapView::addPolylines, "nativeAddPolylines"),
- METHOD(&NativeMapView::addPolygons, "nativeAddPolygons"),
- METHOD(&NativeMapView::updatePolyline, "nativeUpdatePolyline"),
- METHOD(&NativeMapView::updatePolygon, "nativeUpdatePolygon"),
- METHOD(&NativeMapView::removeAnnotations, "nativeRemoveAnnotations"),
- METHOD(&NativeMapView::addAnnotationIcon, "nativeAddAnnotationIcon"),
- METHOD(&NativeMapView::removeAnnotationIcon, "nativeRemoveAnnotationIcon"),
- METHOD(&NativeMapView::getTopOffsetPixelsForAnnotationSymbol, "nativeGetTopOffsetPixelsForAnnotationSymbol"),
- METHOD(&NativeMapView::getTransitionOptions, "nativeGetTransitionOptions"),
- METHOD(&NativeMapView::setTransitionOptions, "nativeSetTransitionOptions"),
- METHOD(&NativeMapView::queryPointAnnotations, "nativeQueryPointAnnotations"),
- METHOD(&NativeMapView::queryShapeAnnotations, "nativeQueryShapeAnnotations"),
- METHOD(&NativeMapView::queryRenderedFeaturesForPoint, "nativeQueryRenderedFeaturesForPoint"),
- METHOD(&NativeMapView::queryRenderedFeaturesForBox, "nativeQueryRenderedFeaturesForBox"),
- METHOD(&NativeMapView::getLight, "nativeGetLight"),
- METHOD(&NativeMapView::getLayers, "nativeGetLayers"),
- METHOD(&NativeMapView::getLayer, "nativeGetLayer"),
- METHOD(&NativeMapView::addLayer, "nativeAddLayer"),
- METHOD(&NativeMapView::addLayerAbove, "nativeAddLayerAbove"),
- METHOD(&NativeMapView::addLayerAt, "nativeAddLayerAt"),
- METHOD(&NativeMapView::removeLayerAt, "nativeRemoveLayerAt"),
- METHOD(&NativeMapView::removeLayer, "nativeRemoveLayer"),
- METHOD(&NativeMapView::getSources, "nativeGetSources"),
- METHOD(&NativeMapView::getSource, "nativeGetSource"),
- METHOD(&NativeMapView::addSource, "nativeAddSource"),
- METHOD(&NativeMapView::removeSource, "nativeRemoveSource"),
- METHOD(&NativeMapView::addImage, "nativeAddImage"),
- METHOD(&NativeMapView::addImages, "nativeAddImages"),
- METHOD(&NativeMapView::removeImage, "nativeRemoveImage"),
- METHOD(&NativeMapView::getImage, "nativeGetImage"),
- METHOD(&NativeMapView::setLatLngBounds, "nativeSetLatLngBounds"),
- METHOD(&NativeMapView::setPrefetchTiles, "nativeSetPrefetchTiles"),
- METHOD(&NativeMapView::getPrefetchTiles, "nativeGetPrefetchTiles")
- );
+ jni::RegisterNativePeer(
+ env,
+ javaClass,
+ "nativePtr",
+ jni::MakePeer&,
+ const jni::Object&,
+ const jni::Object&,
+ jni::jfloat,
+ jni::jboolean>,
+ "nativeInitialize",
+ "nativeDestroy",
+ METHOD(&NativeMapView::resizeView, "nativeResizeView"),
+ METHOD(&NativeMapView::getStyleUrl, "nativeGetStyleUrl"),
+ METHOD(&NativeMapView::setStyleUrl, "nativeSetStyleUrl"),
+ METHOD(&NativeMapView::getStyleJson, "nativeGetStyleJson"),
+ METHOD(&NativeMapView::setStyleJson, "nativeSetStyleJson"),
+ METHOD(&NativeMapView::cancelTransitions, "nativeCancelTransitions"),
+ METHOD(&NativeMapView::setGestureInProgress, "nativeSetGestureInProgress"),
+ METHOD(&NativeMapView::moveBy, "nativeMoveBy"),
+ METHOD(&NativeMapView::jumpTo, "nativeJumpTo"),
+ METHOD(&NativeMapView::easeTo, "nativeEaseTo"),
+ METHOD(&NativeMapView::flyTo, "nativeFlyTo"),
+ METHOD(&NativeMapView::getLatLng, "nativeGetLatLng"),
+ METHOD(&NativeMapView::setLatLng, "nativeSetLatLng"),
+ METHOD(&NativeMapView::getCameraForLatLngBounds, "nativeGetCameraForLatLngBounds"),
+ METHOD(&NativeMapView::getCameraForGeometry, "nativeGetCameraForGeometry"),
+ METHOD(&NativeMapView::setReachability, "nativeSetReachability"),
+ METHOD(&NativeMapView::resetPosition, "nativeResetPosition"),
+ METHOD(&NativeMapView::getPitch, "nativeGetPitch"),
+ METHOD(&NativeMapView::setPitch, "nativeSetPitch"),
+ METHOD(&NativeMapView::getZoom, "nativeGetZoom"),
+ METHOD(&NativeMapView::setZoom, "nativeSetZoom"),
+ METHOD(&NativeMapView::resetZoom, "nativeResetZoom"),
+ METHOD(&NativeMapView::setMinZoom, "nativeSetMinZoom"),
+ METHOD(&NativeMapView::getMinZoom, "nativeGetMinZoom"),
+ METHOD(&NativeMapView::setMaxZoom, "nativeSetMaxZoom"),
+ METHOD(&NativeMapView::getMaxZoom, "nativeGetMaxZoom"),
+ METHOD(&NativeMapView::rotateBy, "nativeRotateBy"),
+ METHOD(&NativeMapView::setBearing, "nativeSetBearing"),
+ METHOD(&NativeMapView::setBearingXY, "nativeSetBearingXY"),
+ METHOD(&NativeMapView::getBearing, "nativeGetBearing"),
+ METHOD(&NativeMapView::resetNorth, "nativeResetNorth"),
+ METHOD(&NativeMapView::setVisibleCoordinateBounds, "nativeSetVisibleCoordinateBounds"),
+ METHOD(&NativeMapView::scheduleSnapshot, "nativeTakeSnapshot"),
+ METHOD(&NativeMapView::getCameraPosition, "nativeGetCameraPosition"),
+ METHOD(&NativeMapView::updateMarker, "nativeUpdateMarker"),
+ METHOD(&NativeMapView::addMarkers, "nativeAddMarkers"),
+ METHOD(&NativeMapView::setDebug, "nativeSetDebug"),
+ METHOD(&NativeMapView::cycleDebugOptions, "nativeCycleDebugOptions"),
+ METHOD(&NativeMapView::getDebug, "nativeGetDebug"),
+ METHOD(&NativeMapView::isFullyLoaded, "nativeIsFullyLoaded"),
+ METHOD(&NativeMapView::onLowMemory, "nativeOnLowMemory"),
+ METHOD(&NativeMapView::getMetersPerPixelAtLatitude, "nativeGetMetersPerPixelAtLatitude"),
+ METHOD(&NativeMapView::projectedMetersForLatLng, "nativeProjectedMetersForLatLng"),
+ METHOD(&NativeMapView::pixelForLatLng, "nativePixelForLatLng"),
+ METHOD(&NativeMapView::latLngForProjectedMeters, "nativeLatLngForProjectedMeters"),
+ METHOD(&NativeMapView::latLngForPixel, "nativeLatLngForPixel"),
+ METHOD(&NativeMapView::addPolylines, "nativeAddPolylines"),
+ METHOD(&NativeMapView::addPolygons, "nativeAddPolygons"),
+ METHOD(&NativeMapView::updatePolyline, "nativeUpdatePolyline"),
+ METHOD(&NativeMapView::updatePolygon, "nativeUpdatePolygon"),
+ METHOD(&NativeMapView::removeAnnotations, "nativeRemoveAnnotations"),
+ METHOD(&NativeMapView::addAnnotationIcon, "nativeAddAnnotationIcon"),
+ METHOD(&NativeMapView::removeAnnotationIcon, "nativeRemoveAnnotationIcon"),
+ METHOD(&NativeMapView::getTopOffsetPixelsForAnnotationSymbol, "nativeGetTopOffsetPixelsForAnnotationSymbol"),
+ METHOD(&NativeMapView::getTransitionOptions, "nativeGetTransitionOptions"),
+ METHOD(&NativeMapView::setTransitionOptions, "nativeSetTransitionOptions"),
+ METHOD(&NativeMapView::queryPointAnnotations, "nativeQueryPointAnnotations"),
+ METHOD(&NativeMapView::queryShapeAnnotations, "nativeQueryShapeAnnotations"),
+ METHOD(&NativeMapView::queryRenderedFeaturesForPoint, "nativeQueryRenderedFeaturesForPoint"),
+ METHOD(&NativeMapView::queryRenderedFeaturesForBox, "nativeQueryRenderedFeaturesForBox"),
+ METHOD(&NativeMapView::getLight, "nativeGetLight"),
+ METHOD(&NativeMapView::getLayers, "nativeGetLayers"),
+ METHOD(&NativeMapView::getLayer, "nativeGetLayer"),
+ METHOD(&NativeMapView::addLayer, "nativeAddLayer"),
+ METHOD(&NativeMapView::addLayerAbove, "nativeAddLayerAbove"),
+ METHOD(&NativeMapView::addLayerAt, "nativeAddLayerAt"),
+ METHOD(&NativeMapView::removeLayerAt, "nativeRemoveLayerAt"),
+ METHOD(&NativeMapView::removeLayer, "nativeRemoveLayer"),
+ METHOD(&NativeMapView::getSources, "nativeGetSources"),
+ METHOD(&NativeMapView::getSource, "nativeGetSource"),
+ METHOD(&NativeMapView::addSource, "nativeAddSource"),
+ METHOD(&NativeMapView::removeSource, "nativeRemoveSource"),
+ METHOD(&NativeMapView::addImage, "nativeAddImage"),
+ METHOD(&NativeMapView::addImages, "nativeAddImages"),
+ METHOD(&NativeMapView::removeImage, "nativeRemoveImage"),
+ METHOD(&NativeMapView::getImage, "nativeGetImage"),
+ METHOD(&NativeMapView::setLatLngBounds, "nativeSetLatLngBounds"),
+ METHOD(&NativeMapView::setPrefetchTiles, "nativeSetPrefetchTiles"),
+ METHOD(&NativeMapView::getPrefetchTiles, "nativeGetPrefetchTiles"),
+ METHOD(&NativeMapView::setPrefetchZoomDelta, "nativeSetPrefetchZoomDelta"),
+ METHOD(&NativeMapView::getPrefetchZoomDelta, "nativeGetPrefetchZoomDelta"));
}
} // namespace android
diff --git a/src/native_map_view.hpp b/src/native_map_view.hpp
index 26567a003..5a340d128 100755
--- a/src/native_map_view.hpp
+++ b/src/native_map_view.hpp
@@ -62,7 +62,7 @@ public:
void onDidFinishLoadingMap() override;
void onDidFailLoadingMap(MapLoadError, const std::string&) override;
void onWillStartRenderingFrame() override;
- void onDidFinishRenderingFrame(MapObserver::RenderMode, bool) override;
+ void onDidFinishRenderingFrame(MapObserver::RenderFrameStatus) override;
void onWillStartRenderingMap() override;
void onDidFinishRenderingMap(MapObserver::RenderMode) override;
void onDidBecomeIdle() override;
@@ -235,6 +235,10 @@ public:
jni::jboolean getPrefetchTiles(JNIEnv&);
+ void setPrefetchZoomDelta(JNIEnv&, jni::jint);
+
+ jni::jint getPrefetchZoomDelta(JNIEnv&);
+
mbgl::Map& getMap();
private:
diff --git a/src/style/sources/source.cpp b/src/style/sources/source.cpp
index be4c0367f..786e5cb58 100644
--- a/src/style/sources/source.cpp
+++ b/src/style/sources/source.cpp
@@ -133,7 +133,7 @@ namespace android {
// Release the peer relationships. These will be re-established when the source is added to a map
assert(ownedSource->peer.has_value());
ownedSource->peer.get>().release();
- ownedSource->peer = util::peer();
+ ownedSource->peer = mapbox::base::TypeWrapper();
// Release the strong reference to the java peer
assert(javaPeer);
diff --git a/src/test/version-script b/src/test/version-script
new file mode 100644
index 000000000..ebc2c1701
--- /dev/null
+++ b/src/test/version-script
@@ -0,0 +1,8 @@
+{
+global:
+ EnsureFrontOfChain;
+ AddSpecialSignalHandlerFn;
+ RemoveSpecialSignalHandlerFn;
+local:
+ *;
+};
diff --git a/vendor/mapbox-gl-native b/vendor/mapbox-gl-native
index 89eaac05e..b4e0224a5 160000
--- a/vendor/mapbox-gl-native
+++ b/vendor/mapbox-gl-native
@@ -1 +1 @@
-Subproject commit 89eaac05ebc2928e59d3f0404f7b92bdb42b92bb
+Subproject commit b4e0224a5786f1d362b2b6b7e7f536be8bb98981