[update] pull in latest for gl-native

This commit is contained in:
tobrun
2019-10-09 16:05:15 +02:00
committed by Tobrun
parent 2bd59ddc81
commit daf0430a24
49 changed files with 1103 additions and 187 deletions

View File

@@ -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):

View File

@@ -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();
}
}

View File

@@ -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.
* <p>
* 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.
* </p>
*
* @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.
* <p>
* 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.
* </p>
*
* @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.
* <p>
* 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.
* </p>
*
* @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.
* <p>
* 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.
* </p>
*
* @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.
* <p>
* 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.
* </p>
*
* @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.
* <p>
* 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.
* </p>
*
* @param tilt The desired camera tilt.
*/

View File

@@ -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;
* </p>
*/
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);
}
}
}

View File

@@ -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
//

View File

@@ -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.
* <p>
@@ -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);

View File

@@ -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();

View File

@@ -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;

View File

@@ -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());

View File

@@ -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);

View File

@@ -235,7 +235,7 @@ public class MapSnapshotter {
*/
@NonNull
public Options withApiBaseUri(String apiBaseUri) {
this.apiBaseUrl = apiBaseUrl;
this.apiBaseUrl = apiBaseUri;
return this;
}

View File

@@ -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

View File

@@ -69,6 +69,7 @@
<public name="mapbox_foregroundLoadColor" type="attr" />
<public name="mapbox_enableTilePrefetch" type="attr" />
<public name="mapbox_prefetchZoomDelta" type="attr"/>
<public name="mapbox_enableZMediaOverlay" type="attr" />
<!-- Exposed content descriptions -->

View File

@@ -109,6 +109,7 @@
<attr name="mapbox_foregroundLoadColor" format="color"/>
<attr name="mapbox_enableTilePrefetch" format="boolean"/>
<attr name="mapbox_prefetchZoomDelta" format="integer"/>
<attr name="mapbox_enableZMediaOverlay" format="boolean"/>
<attr name="mapbox_pixelRatio" format="float"/>

View File

@@ -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));
}
}

View File

@@ -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

View File

@@ -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()

View File

@@ -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);
}
}

View File

@@ -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() {

View File

@@ -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)
}

View File

@@ -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();

View File

@@ -151,6 +151,9 @@ public class BulkMarkerActivity extends AppCompatActivity implements AdapterView
@Override
protected void onDestroy() {
super.onDestroy();
if (progressDialog != null) {
progressDialog.dismiss();
}
mapView.onDestroy();
}

View File

@@ -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

View File

@@ -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) {

View File

@@ -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()
);
}

View File

@@ -362,7 +362,12 @@ public class SymbolGeneratorActivity extends AppCompatActivity implements OnMapR
@Override
protected void onPostExecute(HashMap<String, Bitmap> bitmapHashMap) {
super.onPostExecute(bitmapHashMap);
mapboxMap.getStyle().addImagesAsync(bitmapHashMap);
mapboxMap.getStyle(new Style.OnStyleLoaded() {
@Override
public void onStyleLoaded(@NonNull Style style) {
style.addImagesAsync(bitmapHashMap);
}
});
}
}
}

View File

@@ -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',

View File

@@ -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")

View File

@@ -5,7 +5,6 @@
"MapSnapshotterLocalStyleActivity",
"LatLngBoundsActivity",
"BottomSheetActivity",
"MapSnapshotterActivity",
"MockLocationEngine",
"DeleteRegionActivity",
"RealTimeGeoJsonActivity",
@@ -50,7 +49,5 @@
"EspressoTestActivity",
"FragmentBackStackActivity",
"ChildFragmentMapInDialogActivity",
"PerformanceMeasurementActivity",
"DownloadRegionActivity",
"CacheManagementActivity"
"PerformanceMeasurementActivity"
]

View File

@@ -1,5 +1,7 @@
#include "file_source.hpp"
#include "attach_env.hpp"
#include "mapbox.hpp"
#include <mbgl/actor/actor.hpp>
#include <mbgl/actor/scheduler.hpp>
@@ -14,8 +16,15 @@
namespace mbgl {
std::shared_ptr<FileSource> FileSource::createPlatformFileSource(const ResourceOptions& options) {
auto* assetFileSource = reinterpret_cast<AssetManagerFileSource*>(options.platformContext());
auto fileSource = std::make_shared<DefaultFileSource>(options.cachePath(), std::unique_ptr<AssetManagerFileSource>(assetFileSource));
auto env{android::AttachEnv()};
std::shared_ptr<DefaultFileSource> fileSource;
if (android::Mapbox::hasInstance(*env)) {
auto assetManager = android::Mapbox::getAssetManager(*env);
fileSource = std::make_shared<DefaultFileSource>(options.cachePath(),
std::make_unique<AssetManagerFileSource>(*env, assetManager));
} else {
fileSource = std::make_shared<DefaultFileSource>(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>& assetManager) {
FileSource::FileSource(jni::JNIEnv& _env, const jni::String& accessToken, const jni::String& _cachePath) {
std::string path = jni::Make<std::string>(_env, _cachePath);
mapbox::sqlite::setTempPath(path);
resourceOptions
.withAccessToken(accessToken ? jni::Make<std::string>(_env, accessToken) : "")
.withCachePath(path + DATABASE_FILE)
.withPlatformContext(reinterpret_cast<void*>(new AssetManagerFileSource(_env, assetManager)));
resourceOptions.withAccessToken(accessToken ? jni::Make<std::string>(_env, accessToken) : "")
.withCachePath(path + DATABASE_FILE);
// Create a core default file source
fileSource = std::static_pointer_cast<mbgl::DefaultFileSource>(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<FileSource::ResourceTransformCallback>& transformCallback) {
if (transformCallback) {
auto global = jni::NewGlobal<jni::EnvAttachingDeleter>(env, transformCallback);
resourceTransform = std::make_unique<Actor<ResourceTransform>>(*Scheduler::GetCurrent(),
resourceTransform = std::make_unique<Actor<ResourceTransform>>(
*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<decltype(global)>(std::move(global))]
(mbgl::Resource::Kind kind, const std::string&& url_) {
[callback = std::make_shared<decltype(global)>(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<decltype(MethodPtr), (MethodPtr)>(name)
// Register the peer
jni::RegisterNativePeer<FileSource>(
env, javaClass, "nativePtr",
jni::MakePeer<FileSource, const jni::String&, const jni::String&, const jni::Object<AssetManager>&>,
"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<FileSource>(env,
javaClass,
"nativePtr",
jni::MakePeer<FileSource, const jni::String&, const jni::String&>,
"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"));
}

View File

@@ -41,7 +41,7 @@ public:
const jni::String&);
};
FileSource(jni::JNIEnv&, const jni::String&, const jni::String&, const jni::Object<AssetManager>&);
FileSource(jni::JNIEnv&, const jni::String&, const jni::String&);
~FileSource();

194
src/i18n/collator.cpp Normal file
View File

@@ -0,0 +1,194 @@
#include <mbgl/i18n/collator.hpp>
#include <mbgl/text/language_tag.hpp>
#include <jni/jni.hpp>
#include "../attach_env.hpp"
#include "collator_jni.hpp"
namespace mbgl {
namespace android {
void Collator::registerNative(jni::JNIEnv& env) {
jni::Class<Collator>::Singleton(env);
}
jni::Local<jni::Object<Collator>> Collator::getInstance(jni::JNIEnv& env, const jni::Object<Locale>& locale) {
static auto& javaClass = jni::Class<Collator>::Singleton(env);
static auto method = javaClass.GetStaticMethod<jni::Object<Collator> (jni::Object<Locale>)>(env, "getInstance");
return javaClass.Call(env, method, locale);
}
void Collator::setStrength(jni::JNIEnv& env, const jni::Object<Collator>& collator, jni::jint strength) {
static auto& javaClass = jni::Class<Collator>::Singleton(env);
static auto method = javaClass.GetMethod<void (jni::jint)>(env, "setStrength");
collator.Call(env, method, strength);
}
jni::jint Collator::compare(jni::JNIEnv& env, const jni::Object<Collator>& collator, const jni::String& lhs, const jni::String& rhs) {
static auto& javaClass = jni::Class<Collator>::Singleton(env);
static auto method = javaClass.GetMethod<jni::jint (jni::String, jni::String)>(env, "compare");
return collator.Call(env, method, lhs, rhs);
}
void StringUtils::registerNative(jni::JNIEnv& env) {
jni::Class<StringUtils>::Singleton(env);
}
jni::Local<jni::String> StringUtils::unaccent(jni::JNIEnv& env, const jni::String& value) {
static auto& javaClass = jni::Class<StringUtils>::Singleton(env);
static auto method = javaClass.GetStaticMethod<jni::String (jni::String)>(env, "unaccent");
return javaClass.Call(env, method, value);
}
void Locale::registerNative(jni::JNIEnv& env) {
jni::Class<Locale>::Singleton(env);
}
/*
We would prefer to use for/toLanguageTag, but they're only available in API level 21+
jni::Object<Locale> Locale::forLanguageTag(jni::JNIEnv& env, jni::String languageTag) {
using Signature = jni::Object<Locale>(jni::String);
auto method = javaClass.GetStaticMethod<Signature>(env, "forLanguageTag");
return javaClass.Call(env, method, languageTag);
}
jni::String Locale::toLanguageTag(jni::JNIEnv& env, jni::Object<Locale> locale) {
using Signature = jni::String();
auto static method = javaClass.GetMethod<Signature>(env, "toLanguageTag");
return locale.Call(env, method);
}
*/
jni::Local<jni::String> Locale::getLanguage(jni::JNIEnv& env, const jni::Object<Locale>& locale) {
static auto& javaClass = jni::Class<Locale>::Singleton(env);
static auto method = javaClass.GetMethod<jni::String ()>(env, "getLanguage");
return locale.Call(env, method);
}
jni::Local<jni::String> Locale::getCountry(jni::JNIEnv& env, const jni::Object<Locale>& locale) {
static auto& javaClass = jni::Class<Locale>::Singleton(env);
static auto method = javaClass.GetMethod<jni::String ()>(env, "getCountry");
return locale.Call(env, method);
}
jni::Local<jni::Object<Locale>> Locale::getDefault(jni::JNIEnv& env) {
static auto& javaClass = jni::Class<Locale>::Singleton(env);
static auto method = javaClass.GetStaticMethod<jni::Object<Locale> ()>(env, "getDefault");
return javaClass.Call(env, method);
}
jni::Local<jni::Object<Locale>> Locale::New(jni::JNIEnv& env, const jni::String& language) {
static auto& javaClass = jni::Class<Locale>::Singleton(env);
static auto constructor = javaClass.GetConstructor<jni::String>(env);
return javaClass.New(env, constructor, language);
}
jni::Local<jni::Object<Locale>> Locale::New(jni::JNIEnv& env, const jni::String& language, const jni::String& region) {
static auto& javaClass = jni::Class<Locale>::Singleton(env);
static auto constructor = javaClass.GetConstructor<jni::String, jni::String>(env);
return javaClass.New(env, constructor, language, region);
}
} // namespace android
namespace platform {
class Collator::Impl {
public:
Impl(bool caseSensitive_, bool diacriticSensitive_, optional<std::string> 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<jni::String>(*env, *languageTag.language)));
} else {
locale = jni::NewGlobal(*env,
android::Locale::New(*env, jni::Make<jni::String>(*env, *languageTag.language),
jni::Make<jni::String>(*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<jni::String> jlhs = useUnaccent
? android::StringUtils::unaccent(*env, jni::Make<jni::String>(*env, lhs))
: jni::Make<jni::String>(*env, lhs);
jni::Local<jni::String> jrhs = useUnaccent
? android::StringUtils::unaccent(*env, jni::Make<jni::String>(*env, rhs))
: jni::Make<jni::String>(*env, rhs);
jni::jint result = android::Collator::compare(*env, collator, jlhs, jrhs);
return result;
}
std::string resolvedLocale() const {
std::string language = jni::Make<std::string>(*env, android::Locale::getLanguage(*env, locale));
std::string region = jni::Make<std::string>(*env, android::Locale::getCountry(*env, locale));
optional<std::string> resultLanguage;
if (!language.empty()) resultLanguage = language;
optional<std::string> resultRegion;
if (!region.empty()) resultRegion = region;
return LanguageTag(resultLanguage, {}, resultRegion).toBCP47();
}
private:
bool caseSensitive;
bool diacriticSensitive;
android::UniqueEnv env;
jni::Global<jni::Object<android::Collator>> collator;
jni::Global<jni::Object<android::Locale>> locale;
};
Collator::Collator(bool caseSensitive, bool diacriticSensitive, optional<std::string> locale_)
: impl(std::make_shared<Impl>(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

62
src/i18n/collator_jni.hpp Normal file
View File

@@ -0,0 +1,62 @@
#pragma once
#include <jni/jni.hpp>
/*
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<Locale> forLanguageTag(jni::JNIEnv&, jni::String);
static jni::String toLanguageTag(jni::JNIEnv&, jni::Object<Locale>);
*/
static jni::Local<jni::Object<Locale>> getDefault(jni::JNIEnv&);
static jni::Local<jni::String> getLanguage(jni::JNIEnv&, const jni::Object<Locale>&);
static jni::Local<jni::String> getCountry(jni::JNIEnv&, const jni::Object<Locale>&);
static jni::Local<jni::Object<Locale>> New(jni::JNIEnv&, const jni::String&);
static jni::Local<jni::Object<Locale>> 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<jni::Object<Collator>> getInstance(jni::JNIEnv&, const jni::Object<Locale>&);
static void setStrength(jni::JNIEnv&, const jni::Object<Collator>&, jni::jint);
static jni::jint compare(jni::JNIEnv&, const jni::Object<Collator>&, 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<jni::String> unaccent(jni::JNIEnv&, const jni::String&);
static void registerNative(jni::JNIEnv&);
};
} // namespace android
} // namespace mbgl

View File

@@ -0,0 +1,80 @@
#include <mbgl/i18n/number_format.hpp>
#include <mbgl/text/language_tag.hpp>
#include <jni/jni.hpp>
#include "../attach_env.hpp"
#include "number_format_jni.hpp"
namespace mbgl {
namespace android {
void NumberFormat::registerNative(jni::JNIEnv& env) {
jni::Class<NumberFormat>::Singleton(env);
}
jni::Local<jni::Object<NumberFormat>> NumberFormat::getInstance(jni::JNIEnv& env, const jni::Object<Locale>& locale) {
static auto& javaClass = jni::Class<NumberFormat>::Singleton(env);
static auto method = javaClass.GetStaticMethod<jni::Object<NumberFormat> (jni::Object<Locale>)>(env, "getInstance");
return javaClass.Call(env, method, locale);
}
jni::Local<jni::Object<NumberFormat>> NumberFormat::getCurrencyInstance(jni::JNIEnv& env, const jni::Object<Locale>& locale) {
static auto& javaClass = jni::Class<NumberFormat>::Singleton(env);
static auto method = javaClass.GetStaticMethod<jni::Object<NumberFormat> (jni::Object<Locale>)>(env, "getCurrencyInstance");
return javaClass.Call(env, method, locale);
}
jni::Local<jni::String> NumberFormat::format(jni::JNIEnv& env, const jni::Object<NumberFormat>& nf, jni::jdouble number) {
static auto& javaClass = jni::Class<NumberFormat>::Singleton(env);
static auto method = javaClass.GetMethod<jni::String (jni::jdouble)>(env, "format");
return nf.Call(env, method, number);
}
void NumberFormat::setMinimumFractionDigits(jni::JNIEnv& env, const jni::Object<NumberFormat>& nf, jni::jint value) {
static auto& javaClass = jni::Class<NumberFormat>::Singleton(env);
static auto method = javaClass.GetMethod<void (jni::jint)>(env, "setMinimumFractionDigits");
return nf.Call(env, method, value);
}
void NumberFormat::setMaximumFractionDigits(jni::JNIEnv& env, const jni::Object<NumberFormat>& nf, jni::jint value) {
static auto& javaClass = jni::Class<NumberFormat>::Singleton(env);
static auto method = javaClass.GetMethod<void (jni::jint)>(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<jni::Object<android::Locale>> 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<jni::String>(*env, *languageTag.language)));
} else {
locale = jni::NewGlobal(*env, android::Locale::New(*env, jni::Make<jni::String>(*env, *languageTag.language),
jni::Make<jni::String>(*env, *languageTag.region)));
}
jni::Global<jni::Object<android::NumberFormat>> formatter;
if (currency.empty()) {
formatter = jni::NewGlobal(*env, android::NumberFormat::getInstance(*env, locale));
android::NumberFormat::setMinimumFractionDigits(*env, formatter, static_cast<jni::jint>(minFractionDigits));
android::NumberFormat::setMaximumFractionDigits(*env, formatter, static_cast<jni::jint>(maxFractionDigits));
} else {
formatter = jni::NewGlobal(*env, android::NumberFormat::getCurrencyInstance(*env, locale));
}
auto result = android::NumberFormat::format(*env, formatter, static_cast<jni::jdouble>(number));
return jni::Make<std::string>(*env, result);
}
} // namespace platform
} // namespace mbgl

View File

@@ -0,0 +1,29 @@
#pragma once
#include <jni/jni.hpp>
#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<jni::Object<NumberFormat>> getInstance(jni::JNIEnv&, const jni::Object<Locale>&);
static jni::Local<jni::Object<NumberFormat>> getCurrencyInstance(jni::JNIEnv&, const jni::Object<Locale>&);
static jni::Local<jni::String> format(jni::JNIEnv&, const jni::Object<NumberFormat>&, jni::jdouble);
static void setMinimumFractionDigits(jni::JNIEnv&, const jni::Object<NumberFormat>&, jni::jint);
static void setMaximumFractionDigits(jni::JNIEnv&, const jni::Object<NumberFormat>&, jni::jint);
static void registerNative(jni::JNIEnv&);
};
} // namespace android
} // namespace mbgl

12
src/jni_native.cpp Executable file → Normal file
View File

@@ -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

View File

@@ -7,7 +7,7 @@
namespace mbgl {
namespace android {
MBGL_PUBLIC void registerNatives(JavaVM* vm);
MBGL_EXPORT void registerNatives(JavaVM* vm);
} // namespace android
} // namespace mbgl

View File

@@ -44,19 +44,20 @@ mbgl::CameraOptions CameraPosition::getCameraOptions(jni::JNIEnv& env, const jni
static auto tilt = javaClass.GetField<jni::jdouble>(env, "tilt");
static auto zoom = javaClass.GetField<jni::jdouble>(env, "zoom");
static auto paddingField = javaClass.GetField<jni::Array<jni::jdouble>>(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) {

View File

@@ -43,7 +43,7 @@ ActorRef<Renderer> MapRenderer::actor() const {
return *rendererRef;
}
void MapRenderer::schedule(std::weak_ptr<Mailbox> scheduled) {
void MapRenderer::schedule(std::function<void()> scheduled) {
// Create a runnable
android::UniqueEnv _env = android::AttachEnv();
auto runnable = std::make_unique<MapRendererRunnable>(*_env, std::move(scheduled));

View File

@@ -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<Mailbox> scheduled) override;
void schedule(std::function<void()> scheduled) override;
void requestRender();

View File

@@ -5,9 +5,8 @@
namespace mbgl {
namespace android {
MapRendererRunnable::MapRendererRunnable(jni::JNIEnv& env, std::weak_ptr<Mailbox> mailbox_)
: mailbox(std::move(mailbox_)) {
MapRendererRunnable::MapRendererRunnable(jni::JNIEnv& env, std::function<void()> 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<Mailbox
MapRendererRunnable::~MapRendererRunnable() = default;
void MapRendererRunnable::run(jni::JNIEnv&) {
Mailbox::maybeReceive(mailbox);
if (function) function();
}
jni::Global<jni::Object<MapRendererRunnable>> MapRendererRunnable::peer() {

View File

@@ -24,7 +24,7 @@ public:
static void registerNative(jni::JNIEnv&);
MapRendererRunnable(jni::JNIEnv&, std::weak_ptr<Mailbox>);
MapRendererRunnable(jni::JNIEnv&, std::function<void()>);
// Only for jni registration, unused
MapRendererRunnable(jni::JNIEnv&) {
@@ -40,7 +40,7 @@ public:
private:
jni::Global<jni::Object<MapRendererRunnable>> javaPeer;
std::weak_ptr<Mailbox> mailbox;
std::function<void()> function;
};
} // namespace android

23
src/mapbox.cpp Normal file
View File

@@ -0,0 +1,23 @@
#include "mapbox.hpp"
namespace mbgl {
namespace android {
jni::Local<jni::Object<AssetManager>> Mapbox::getAssetManager(jni::JNIEnv& env) {
static auto& javaClass = jni::Class<Mapbox>::Singleton(env);
auto method = javaClass.GetStaticMethod<jni::Object<AssetManager>()>(env, "getAssetManager");
return javaClass.Call(env, method);
}
jboolean Mapbox::hasInstance(jni::JNIEnv& env) {
static auto& javaClass = jni::Class<Mapbox>::Singleton(env);
auto method = javaClass.GetStaticMethod<jboolean()>(env, "hasInstance");
return javaClass.Call(env, method);
}
void Mapbox::registerNative(jni::JNIEnv& env) {
jni::Class<Mapbox>::Singleton(env);
}
} // namespace android
} // namespace mbgl

19
src/mapbox.hpp Normal file
View File

@@ -0,0 +1,19 @@
#pragma once
#include "asset_manager.hpp"
#include <jni/jni.hpp>
namespace mbgl {
namespace android {
class Mapbox {
public:
static constexpr auto Name() { return "com/mapbox/mapboxsdk/Mapbox"; };
static jboolean hasInstance(jni::JNIEnv&);
static jni::Local<jni::Object<AssetManager>> getAssetManager(jni::JNIEnv&);
static void registerNative(jni::JNIEnv&);
};
} // namespace android
} // namespace mbgl

209
src/native_map_view.cpp Executable file → Normal file
View File

@@ -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<void (jboolean)>(*_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<decltype(MethodPtr), (MethodPtr)>(name)
// Register the peer
jni::RegisterNativePeer<NativeMapView>(env, javaClass, "nativePtr",
jni::MakePeer<NativeMapView, const jni::Object<NativeMapView>&, const jni::Object<FileSource>&, const jni::Object<MapRenderer>&, 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<NativeMapView>(
env,
javaClass,
"nativePtr",
jni::MakePeer<NativeMapView,
const jni::Object<NativeMapView>&,
const jni::Object<FileSource>&,
const jni::Object<MapRenderer>&,
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

View File

@@ -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:

View File

@@ -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<std::unique_ptr<Source>>().release();
ownedSource->peer = util::peer();
ownedSource->peer = mapbox::base::TypeWrapper();
// Release the strong reference to the java peer
assert(javaPeer);

8
src/test/version-script Normal file
View File

@@ -0,0 +1,8 @@
{
global:
EnsureFrontOfChain;
AddSpecialSignalHandlerFn;
RemoveSpecialSignalHandlerFn;
local:
*;
};