[android] jni high level binding refactor
This commit is contained in:
committed by
Ivo van Dongen
parent
7d9018093a
commit
465c949153
@@ -30,6 +30,8 @@ public class Marker extends Annotation {
|
||||
private LatLng position;
|
||||
private String snippet;
|
||||
private Icon icon;
|
||||
//Redundantly stored for JNI access
|
||||
private String iconId;
|
||||
private String title;
|
||||
|
||||
private InfoWindow infoWindow;
|
||||
@@ -51,24 +53,19 @@ public class Marker extends Annotation {
|
||||
* @param baseMarkerOptions The builder used to construct the Marker.
|
||||
*/
|
||||
public Marker(BaseMarkerOptions baseMarkerOptions) {
|
||||
position = baseMarkerOptions.position;
|
||||
snippet = baseMarkerOptions.snippet;
|
||||
icon = baseMarkerOptions.icon;
|
||||
title = baseMarkerOptions.title;
|
||||
this(baseMarkerOptions.position, baseMarkerOptions.icon, baseMarkerOptions.title, baseMarkerOptions.snippet);
|
||||
}
|
||||
|
||||
Marker(BaseMarkerViewOptions baseMarkerViewOptions) {
|
||||
position = baseMarkerViewOptions.position;
|
||||
snippet = baseMarkerViewOptions.snippet;
|
||||
icon = baseMarkerViewOptions.icon;
|
||||
title = baseMarkerViewOptions.title;
|
||||
this(baseMarkerViewOptions.position, baseMarkerViewOptions.icon,
|
||||
baseMarkerViewOptions.title, baseMarkerViewOptions.snippet);
|
||||
}
|
||||
|
||||
Marker(LatLng position, Icon icon, String title, String snippet) {
|
||||
this.position = position;
|
||||
this.icon = icon;
|
||||
this.title = title;
|
||||
this.snippet = snippet;
|
||||
setIcon(icon);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,6 +145,7 @@ public class Marker extends Annotation {
|
||||
*/
|
||||
public void setIcon(@Nullable Icon icon) {
|
||||
this.icon = icon;
|
||||
this.iconId = icon != null ? icon.getId() : null;
|
||||
MapboxMap map = getMapboxMap();
|
||||
if (map != null) {
|
||||
map.updateMarker(this);
|
||||
|
||||
@@ -22,7 +22,6 @@ import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -203,8 +202,6 @@ public class MapView extends FrameLayout {
|
||||
*/
|
||||
@UiThread
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
nativeMapView.setAccessToken(Mapbox.getAccessToken());
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapLoadEvent());
|
||||
} else if (savedInstanceState.getBoolean(MapboxConstants.STATE_HAS_SAVED_STATE)) {
|
||||
@@ -409,11 +406,6 @@ public class MapView extends FrameLayout {
|
||||
return;
|
||||
}
|
||||
|
||||
// stopgap for https://github.com/mapbox/mapbox-gl-native/issues/6242
|
||||
if (TextUtils.isEmpty(nativeMapView.getAccessToken())) {
|
||||
nativeMapView.setAccessToken(Mapbox.getAccessToken());
|
||||
}
|
||||
|
||||
nativeMapView.setStyleUrl(url);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.mapbox.mapboxsdk.Mapbox;
|
||||
import com.mapbox.mapboxsdk.annotations.Annotation;
|
||||
import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions;
|
||||
import com.mapbox.mapboxsdk.annotations.BaseMarkerViewOptions;
|
||||
@@ -866,10 +865,6 @@ public final class MapboxMap {
|
||||
private void setStyleUrl(@NonNull MapboxMapOptions options) {
|
||||
String style = options.getStyle();
|
||||
if (!TextUtils.isEmpty(style)) {
|
||||
// stopgap for https://github.com/mapbox/mapbox-gl-native/issues/6242
|
||||
if (TextUtils.isEmpty(nativeMapView.getAccessToken())) {
|
||||
nativeMapView.setAccessToken(Mapbox.getAccessToken());
|
||||
}
|
||||
setStyleUrl(style);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,16 +1,11 @@
|
||||
package com.mapbox.mapboxsdk.offline;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.mapbox.mapboxsdk.Mapbox;
|
||||
import com.mapbox.mapboxsdk.constants.MapboxConstants;
|
||||
import com.mapbox.mapboxsdk.storage.Resource;
|
||||
import com.mapbox.mapboxsdk.storage.FileSource;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@@ -30,11 +25,13 @@ public class OfflineManager {
|
||||
System.loadLibrary("mapbox-gl");
|
||||
}
|
||||
|
||||
// Default database name
|
||||
private static final String DATABASE_NAME = "mbgl-offline.db";
|
||||
|
||||
// Holds the pointer to JNI DefaultFileSource
|
||||
private long mDefaultFileSourcePtr = 0;
|
||||
// Native peer pointer
|
||||
private long nativePtr;
|
||||
|
||||
// Reference to the file source to keep it alive for the
|
||||
// lifetime of this object
|
||||
private final FileSource fileSource;
|
||||
|
||||
// Makes sure callbacks come back to the main thread
|
||||
private Handler handler;
|
||||
@@ -82,94 +79,17 @@ public class OfflineManager {
|
||||
void onError(String error);
|
||||
}
|
||||
|
||||
/**
|
||||
* This callback allows implementors to transform URLs before they are requested
|
||||
* from the internet. This can be used add or remove custom parameters, or reroute
|
||||
* certain requests to other servers or endpoints.
|
||||
*/
|
||||
public interface ResourceTransformCallback {
|
||||
/**
|
||||
* Called whenever a URL needs to be transformed.
|
||||
*
|
||||
* @param kind The kind of URL to be transformed.
|
||||
* @param offlineRegions The original URL to be transformed.
|
||||
* @return A URL that will now be downloaded.
|
||||
*/
|
||||
String onURL(@Resource.Kind int kind, String url);
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructors
|
||||
* Constructor
|
||||
*/
|
||||
private OfflineManager(Context context) {
|
||||
// Get a pointer to the DefaultFileSource instance
|
||||
String cachePath = getDatabasePath(context) + File.separator + DATABASE_NAME;
|
||||
String apkPath = context.getPackageCodePath();
|
||||
mDefaultFileSourcePtr = sharedDefaultFileSource(cachePath, apkPath);
|
||||
setAccessToken(mDefaultFileSourcePtr, Mapbox.getAccessToken());
|
||||
this.fileSource = FileSource.getInstance(context);
|
||||
initialize(fileSource);
|
||||
|
||||
// Delete any existing previous ambient cache database
|
||||
deleteAmbientDatabase(context);
|
||||
}
|
||||
|
||||
public static String getDatabasePath(Context context) {
|
||||
// Default value
|
||||
boolean setStorageExternal = MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL;
|
||||
|
||||
try {
|
||||
// Try getting a custom value from the app Manifest
|
||||
ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(
|
||||
context.getPackageName(), PackageManager.GET_META_DATA);
|
||||
setStorageExternal = appInfo.metaData.getBoolean(
|
||||
MapboxConstants.KEY_META_DATA_SET_STORAGE_EXTERNAL,
|
||||
MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL);
|
||||
} catch (PackageManager.NameNotFoundException exception) {
|
||||
Timber.e("Failed to read the package metadata: ", exception);
|
||||
} catch (Exception exception) {
|
||||
Timber.e("Failed to read the storage key: ", exception);
|
||||
}
|
||||
|
||||
String databasePath = null;
|
||||
if (setStorageExternal && isExternalStorageReadable()) {
|
||||
try {
|
||||
// Try getting the external storage path
|
||||
databasePath = context.getExternalFilesDir(null).getAbsolutePath();
|
||||
} catch (NullPointerException exception) {
|
||||
Timber.e("Failed to obtain the external storage path: ", exception);
|
||||
}
|
||||
}
|
||||
|
||||
if (databasePath == null) {
|
||||
// Default to internal storage
|
||||
databasePath = context.getFilesDir().getAbsolutePath();
|
||||
}
|
||||
|
||||
return databasePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if external storage is available to at least read. In order for this to work, make
|
||||
* sure you include <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
* (or WRITE_EXTERNAL_STORAGE) for API level < 18 in your app Manifest.
|
||||
* <p>
|
||||
* Code from https://developer.android.com/guide/topics/data/data-storage.html#filesExternal
|
||||
* </p>
|
||||
*
|
||||
* @return true if external storage is readable
|
||||
*/
|
||||
public static boolean isExternalStorageReadable() {
|
||||
String state = Environment.getExternalStorageState();
|
||||
if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Timber.w("External storage was requested but it isn't readable. For API level < 18"
|
||||
+ " make sure you've requested READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE"
|
||||
+ " permissions in your app Manifest (defaulting to internal storage).");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void deleteAmbientDatabase(final Context context) {
|
||||
// Delete the file in a separate thread to avoid affecting the UI
|
||||
new Thread(new Runnable() {
|
||||
@@ -215,7 +135,8 @@ public class OfflineManager {
|
||||
* @param callback the callback to be invoked
|
||||
*/
|
||||
public void listOfflineRegions(@NonNull final ListOfflineRegionsCallback callback) {
|
||||
listOfflineRegions(mDefaultFileSourcePtr, new ListOfflineRegionsCallback() {
|
||||
listOfflineRegions(fileSource, new ListOfflineRegionsCallback() {
|
||||
|
||||
@Override
|
||||
public void onList(final OfflineRegion[] offlineRegions) {
|
||||
getHandler().post(new Runnable() {
|
||||
@@ -259,7 +180,8 @@ public class OfflineManager {
|
||||
@NonNull byte[] metadata,
|
||||
@NonNull final CreateOfflineRegionCallback callback) {
|
||||
|
||||
createOfflineRegion(mDefaultFileSourcePtr, definition, metadata, new CreateOfflineRegionCallback() {
|
||||
createOfflineRegion(fileSource, definition, metadata, new CreateOfflineRegionCallback() {
|
||||
|
||||
@Override
|
||||
public void onCreate(final OfflineRegion offlineRegion) {
|
||||
getHandler().post(new Runnable() {
|
||||
@@ -282,48 +204,20 @@ public class OfflineManager {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a callback for transforming URLs requested from the internet
|
||||
* <p>
|
||||
* The callback will be executed on the main thread once for every requested URL.
|
||||
* </p>
|
||||
*
|
||||
* @param callback the callback to be invoked
|
||||
*/
|
||||
public void setResourceTransform(@NonNull final ResourceTransformCallback callback) {
|
||||
setResourceTransform(mDefaultFileSourcePtr, callback);
|
||||
}
|
||||
|
||||
/*
|
||||
* Changing or bypassing this limit without permission from Mapbox is prohibited
|
||||
* by the Mapbox Terms of Service.
|
||||
*/
|
||||
public void setOfflineMapboxTileCountLimit(long limit) {
|
||||
setOfflineMapboxTileCountLimit(mDefaultFileSourcePtr, limit);
|
||||
}
|
||||
public native void setOfflineMapboxTileCountLimit(long limit);
|
||||
|
||||
private native void initialize(FileSource fileSource);
|
||||
|
||||
/*
|
||||
* Native methods
|
||||
*/
|
||||
private native long sharedDefaultFileSource(
|
||||
String cachePath, String assetRoot);
|
||||
@Override
|
||||
protected native void finalize() throws Throwable;
|
||||
|
||||
private native void setAccessToken(long defaultFileSourcePtr, String accessToken);
|
||||
private native void listOfflineRegions(FileSource fileSource, ListOfflineRegionsCallback callback);
|
||||
|
||||
private native String getAccessToken(long defaultFileSourcePtr);
|
||||
|
||||
private native void listOfflineRegions(
|
||||
long defaultFileSourcePtr, ListOfflineRegionsCallback callback);
|
||||
|
||||
private native void createOfflineRegion(
|
||||
long defaultFileSourcePtr, OfflineRegionDefinition definition,
|
||||
byte[] metadata, CreateOfflineRegionCallback callback);
|
||||
|
||||
private native void setResourceTransform(
|
||||
long defaultFileSourcePtr, ResourceTransformCallback callback);
|
||||
|
||||
private native void setOfflineMapboxTileCountLimit(
|
||||
long defaultFileSourcePtr, long limit);
|
||||
private native void createOfflineRegion(FileSource fileSource, OfflineRegionDefinition definition,
|
||||
byte[] metadata, CreateOfflineRegionCallback callback);
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import android.os.Looper;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import timber.log.Timber;
|
||||
import com.mapbox.mapboxsdk.storage.FileSource;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -25,22 +25,25 @@ public class OfflineRegion {
|
||||
System.loadLibrary("mapbox-gl");
|
||||
}
|
||||
|
||||
// Parent OfflineManager
|
||||
private OfflineManager offlineManager;
|
||||
|
||||
// Members
|
||||
private long mId = 0;
|
||||
private OfflineRegionDefinition mDefinition = null;
|
||||
|
||||
// Holds the pointer to JNI OfflineRegion
|
||||
private long nativePtr;
|
||||
|
||||
// Holds a reference to the FileSource to keep it alive
|
||||
private FileSource fileSource;
|
||||
|
||||
//Region id
|
||||
private long id;
|
||||
|
||||
private OfflineRegionDefinition definition;
|
||||
|
||||
/**
|
||||
* Arbitrary binary region metadata. The contents are opaque to the SDK implementation;
|
||||
* it just stores and retrieves a byte[]. Check the `OfflineActivity` in the TestApp
|
||||
* for a sample implementation that uses JSON to store an offline region name.
|
||||
*/
|
||||
private byte[] mMetadata = null;
|
||||
|
||||
// Holds the pointer to JNI OfflineRegion
|
||||
private long mOfflineRegionPtr = 0;
|
||||
private byte[] metadata;
|
||||
|
||||
// Makes sure callbacks come back to the main thread
|
||||
private Handler handler;
|
||||
@@ -197,19 +200,22 @@ public class OfflineRegion {
|
||||
if (state == STATE_ACTIVE) {
|
||||
return true;
|
||||
}
|
||||
if (isDeliveringInactiveMessages()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return isDeliveringInactiveMessages();
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* For JNI use only, to create a new offline region, use
|
||||
* {@link OfflineManager#createOfflineRegion} instead.
|
||||
*/
|
||||
|
||||
private OfflineRegion() {
|
||||
// For JNI use only, to create a new offline region, use
|
||||
// OfflineManager.createOfflineRegion() instead.
|
||||
private OfflineRegion(long offlineRegionPtr, FileSource fileSource, long id,
|
||||
OfflineRegionDefinition definition, byte[] metadata) {
|
||||
this.fileSource = fileSource;
|
||||
this.id = id;
|
||||
this.definition = definition;
|
||||
this.metadata = metadata;
|
||||
initialize(offlineRegionPtr, fileSource);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -217,15 +223,15 @@ public class OfflineRegion {
|
||||
*/
|
||||
|
||||
public long getID() {
|
||||
return mId;
|
||||
return id;
|
||||
}
|
||||
|
||||
public OfflineRegionDefinition getDefinition() {
|
||||
return mDefinition;
|
||||
return definition;
|
||||
}
|
||||
|
||||
public byte[] getMetadata() {
|
||||
return mMetadata;
|
||||
return metadata;
|
||||
}
|
||||
|
||||
private Handler getHandler() {
|
||||
@@ -383,7 +389,7 @@ public class OfflineRegion {
|
||||
getHandler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mMetadata = metadata;
|
||||
OfflineRegion.this.metadata = metadata;
|
||||
callback.onUpdate(metadata);
|
||||
}
|
||||
});
|
||||
@@ -401,33 +407,18 @@ public class OfflineRegion {
|
||||
});
|
||||
}
|
||||
|
||||
private native void initialize(long offlineRegionPtr, FileSource fileSource);
|
||||
|
||||
@Override
|
||||
protected void finalize() {
|
||||
try {
|
||||
super.finalize();
|
||||
destroyOfflineRegion();
|
||||
} catch (Throwable throwable) {
|
||||
Timber.e("Failed to finalize OfflineRegion: " + throwable.getMessage());
|
||||
}
|
||||
}
|
||||
protected native void finalize();
|
||||
|
||||
/*
|
||||
* Native methods
|
||||
*/
|
||||
private native void setOfflineRegionObserver(OfflineRegionObserver callback);
|
||||
|
||||
private native void destroyOfflineRegion();
|
||||
private native void setOfflineRegionDownloadState(@DownloadState int offlineRegionDownloadState);
|
||||
|
||||
private native void setOfflineRegionObserver(
|
||||
OfflineRegionObserver observerCallback);
|
||||
private native void getOfflineRegionStatus(OfflineRegionStatusCallback callback);
|
||||
|
||||
private native void setOfflineRegionDownloadState(
|
||||
@DownloadState int offlineRegionDownloadState);
|
||||
|
||||
private native void getOfflineRegionStatus(
|
||||
OfflineRegionStatusCallback statusCallback);
|
||||
|
||||
private native void deleteOfflineRegion(
|
||||
OfflineRegionDeleteCallback deleteCallback);
|
||||
private native void deleteOfflineRegion(OfflineRegionDeleteCallback callback);
|
||||
|
||||
private native void updateOfflineRegionMetadata(byte[] metadata, OfflineRegionUpdateMetadataCallback callback);
|
||||
|
||||
|
||||
@@ -25,25 +25,23 @@ public class OfflineRegionError {
|
||||
public static final String REASON_OTHER = "REASON_OTHER";
|
||||
|
||||
@ErrorReason
|
||||
private String reason;
|
||||
private final String reason;
|
||||
|
||||
/**
|
||||
* /* An error message from the request handler, e.g. a server message or a system message
|
||||
* /* informing the user about the reason for the failure.
|
||||
*/
|
||||
private String message;
|
||||
private final String message;
|
||||
|
||||
/*
|
||||
* Constructors
|
||||
*/
|
||||
// Constructors
|
||||
|
||||
private OfflineRegionError() {
|
||||
private OfflineRegionError(String reason, String message) {
|
||||
// For JNI use only
|
||||
this.reason = reason;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
// Getters
|
||||
|
||||
@ErrorReason
|
||||
public String getReason() {
|
||||
|
||||
@@ -56,24 +56,29 @@ public class OfflineRegionStatus {
|
||||
|
||||
/*
|
||||
* Use setObserver(OfflineRegionObserver observer) to obtain a OfflineRegionStatus object.
|
||||
*
|
||||
* For JNI use only
|
||||
*/
|
||||
|
||||
private OfflineRegionStatus() {
|
||||
// For JNI use only
|
||||
private OfflineRegionStatus(int downloadState, long completedResourceCount,
|
||||
long completedResourceSize, long completedTileCount,
|
||||
long completedTileSize, long requiredResourceCount,
|
||||
boolean requiredResourceCountIsPrecise) {
|
||||
this.downloadState = downloadState;
|
||||
this.completedResourceCount = completedResourceCount;
|
||||
this.completedResourceSize = completedResourceSize;
|
||||
this.completedTileCount = completedTileCount;
|
||||
this.completedTileSize = completedTileSize;
|
||||
this.requiredResourceCount = requiredResourceCount;
|
||||
this.requiredResourceCountIsPrecise = requiredResourceCountIsPrecise;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Is the region complete?
|
||||
*/
|
||||
|
||||
public boolean isComplete() {
|
||||
return (completedResourceCount == requiredResourceCount);
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
|
||||
@OfflineRegion.DownloadState
|
||||
public int getDownloadState() {
|
||||
return downloadState;
|
||||
|
||||
@@ -21,16 +21,18 @@ public class OfflineTilePyramidRegionDefinition implements OfflineRegionDefiniti
|
||||
private double maxZoom;
|
||||
private float pixelRatio;
|
||||
|
||||
/*
|
||||
* Constructors
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param styleURL the style
|
||||
* @param bounds the bounds
|
||||
* @param minZoom min zoom
|
||||
* @param maxZoom max zoom
|
||||
* @param pixelRatio pixel ratio of the device
|
||||
*/
|
||||
|
||||
private OfflineTilePyramidRegionDefinition() {
|
||||
// For JNI use only
|
||||
}
|
||||
|
||||
public OfflineTilePyramidRegionDefinition(
|
||||
String styleURL, LatLngBounds bounds, double minZoom, double maxZoom, float pixelRatio) {
|
||||
// Note: Also used in JNI
|
||||
this.styleURL = styleURL;
|
||||
this.bounds = bounds;
|
||||
this.minZoom = minZoom;
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
package com.mapbox.mapboxsdk.storage;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Environment;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.mapbox.mapboxsdk.Mapbox;
|
||||
import com.mapbox.mapboxsdk.constants.MapboxConstants;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* Holds a central reference to the core's DefaultFileSource for as long as
|
||||
* there are active mapviews / offline managers
|
||||
*/
|
||||
public class FileSource {
|
||||
|
||||
/**
|
||||
* This callback allows implementors to transform URLs before they are requested
|
||||
* from the internet. This can be used add or remove custom parameters, or reroute
|
||||
* certain requests to other servers or endpoints.
|
||||
*/
|
||||
public interface ResourceTransformCallback {
|
||||
|
||||
/**
|
||||
* Called whenever a URL needs to be transformed.
|
||||
*
|
||||
* @param kind The kind of URL to be transformed.
|
||||
* @return A URL that will now be downloaded.
|
||||
*/
|
||||
String onURL(@Resource.Kind int kind, String url);
|
||||
|
||||
}
|
||||
|
||||
// Use weak reference to avoid blocking GC on this reference.
|
||||
// Should only block when mapview / Offline manager instances
|
||||
// are alive
|
||||
private static WeakReference<FileSource> INSTANCE;
|
||||
|
||||
public static synchronized FileSource getInstance(Context context) {
|
||||
if (INSTANCE == null || INSTANCE.get() == null) {
|
||||
String cachePath = getCachePath(context);
|
||||
String apkPath = context.getPackageCodePath();
|
||||
INSTANCE = new WeakReference<>(new FileSource(cachePath, apkPath));
|
||||
}
|
||||
|
||||
return INSTANCE.get();
|
||||
}
|
||||
|
||||
public static String getCachePath(Context context) {
|
||||
// Default value
|
||||
boolean setStorageExternal = MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL;
|
||||
|
||||
try {
|
||||
// Try getting a custom value from the app Manifest
|
||||
ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(),
|
||||
PackageManager.GET_META_DATA);
|
||||
setStorageExternal = appInfo.metaData.getBoolean(
|
||||
MapboxConstants.KEY_META_DATA_SET_STORAGE_EXTERNAL,
|
||||
MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL);
|
||||
} catch (PackageManager.NameNotFoundException exception) {
|
||||
Timber.e("Failed to read the package metadata: ", exception);
|
||||
} catch (Exception exception) {
|
||||
Timber.e("Failed to read the storage key: ", exception);
|
||||
}
|
||||
|
||||
String cachePath = null;
|
||||
if (setStorageExternal && isExternalStorageReadable()) {
|
||||
try {
|
||||
// Try getting the external storage path
|
||||
cachePath = context.getExternalFilesDir(null).getAbsolutePath();
|
||||
} catch (NullPointerException exception) {
|
||||
Timber.e("Failed to obtain the external storage path: ", exception);
|
||||
}
|
||||
}
|
||||
|
||||
if (cachePath == null) {
|
||||
// Default to internal storage
|
||||
cachePath = context.getFilesDir().getAbsolutePath();
|
||||
}
|
||||
|
||||
return cachePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if external storage is available to at least read. In order for this to work, make
|
||||
* sure you include <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
* (or WRITE_EXTERNAL_STORAGE) for API level < 18 in your app Manifest.
|
||||
* <p>
|
||||
* Code from https://developer.android.com/guide/topics/data/data-storage.html#filesExternal
|
||||
* </p>
|
||||
*
|
||||
* @return true if external storage is readable
|
||||
*/
|
||||
public static boolean isExternalStorageReadable() {
|
||||
String state = Environment.getExternalStorageState();
|
||||
if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Timber.w("External storage was requested but it isn't readable. For API level < 18"
|
||||
+ " make sure you've requested READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE"
|
||||
+ " permissions in your app Manifest (defaulting to internal storage).");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private long nativePtr;
|
||||
|
||||
private FileSource(String cachePath, String apkPath) {
|
||||
initialize(Mapbox.getAccessToken(), cachePath, apkPath);
|
||||
}
|
||||
|
||||
public native void setAccessToken(@NonNull String accessToken);
|
||||
|
||||
public native String getAccessToken();
|
||||
|
||||
public native void setApiBaseUrl(String baseUrl);
|
||||
|
||||
/**
|
||||
* Sets a callback for transforming URLs requested from the internet
|
||||
* <p>
|
||||
* The callback will be executed on the main thread once for every requested URL.
|
||||
* </p>
|
||||
*
|
||||
* @param callback the callback to be invoked
|
||||
*/
|
||||
public native void setResourceTransform(@NonNull final ResourceTransformCallback callback);
|
||||
|
||||
private native void initialize(String accessToken, String cachePath, String apkPath);
|
||||
|
||||
@Override
|
||||
protected native void finalize() throws Throwable;
|
||||
|
||||
}
|
||||
@@ -328,6 +328,17 @@
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".activity.FeatureOverviewActivity"/>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.offline.DeleteRegionActivity"
|
||||
android:description="@string/description_offline_region_delete"
|
||||
android:label="@string/activity_offline_region_delete">
|
||||
<meta-data
|
||||
android:name="@string/category"
|
||||
android:value="@string/category_offline"/>
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".activity.FeatureOverviewActivity"/>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.imagegenerator.SnapshotActivity"
|
||||
android:description="@string/description_snapshot"
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.offline;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.mapbox.mapboxsdk.offline.OfflineManager;
|
||||
import com.mapbox.mapboxsdk.offline.OfflineRegion;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.testapp.utils.OfflineUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Test activity showing integration of deleting an OfflineRegion.
|
||||
*/
|
||||
public class DeleteRegionActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
|
||||
|
||||
private OfflineRegionAdapter adapter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_offline_region_delete);
|
||||
|
||||
ListView listView = (ListView) findViewById(R.id.listView);
|
||||
listView.setAdapter(adapter = new OfflineRegionAdapter(this));
|
||||
listView.setEmptyView(findViewById(android.R.id.empty));
|
||||
listView.setOnItemClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
final OfflineRegion region = adapter.getItem(position);
|
||||
String metadata = OfflineUtils.convertRegionName(region.getMetadata());
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle("Delete region");
|
||||
|
||||
final TextView input = new TextView(this);
|
||||
input.setText(metadata);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
delete(region);
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.cancel();
|
||||
}
|
||||
});
|
||||
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private void delete(OfflineRegion region) {
|
||||
region.delete(new OfflineRegion.OfflineRegionDeleteCallback() {
|
||||
@Override
|
||||
public void onDelete() {
|
||||
Toast.makeText(
|
||||
DeleteRegionActivity.this,
|
||||
"Region deleted",
|
||||
Toast.LENGTH_SHORT
|
||||
).show();
|
||||
loadOfflineRegions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String error) {
|
||||
Toast.makeText(
|
||||
DeleteRegionActivity.this,
|
||||
"Region deletion failed with " + error,
|
||||
Toast.LENGTH_LONG
|
||||
).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
loadOfflineRegions();
|
||||
}
|
||||
|
||||
private void loadOfflineRegions() {
|
||||
OfflineManager.getInstance(this).listOfflineRegions(new OfflineManager.ListOfflineRegionsCallback() {
|
||||
@Override
|
||||
public void onList(OfflineRegion[] offlineRegions) {
|
||||
if (offlineRegions != null && offlineRegions.length > 0) {
|
||||
adapter.setOfflineRegions(Arrays.asList(offlineRegions));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String error) {
|
||||
Toast.makeText(DeleteRegionActivity.this, "Error loading regions " + error, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static class OfflineRegionAdapter extends BaseAdapter {
|
||||
|
||||
private Context context;
|
||||
private List<OfflineRegion> offlineRegions;
|
||||
|
||||
OfflineRegionAdapter(Context ctx) {
|
||||
context = ctx;
|
||||
offlineRegions = new ArrayList<>();
|
||||
}
|
||||
|
||||
void setOfflineRegions(List<OfflineRegion> offlineRegions) {
|
||||
this.offlineRegions = offlineRegions;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return offlineRegions.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OfflineRegion getItem(int position) {
|
||||
return offlineRegions.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
ViewHolder holder;
|
||||
|
||||
if (convertView == null) {
|
||||
holder = new ViewHolder();
|
||||
convertView = LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_1, parent, false);
|
||||
holder.text = (TextView) convertView.findViewById(android.R.id.text1);
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
holder.text.setText(OfflineUtils.convertRegionName(getItem(position).getMetadata()));
|
||||
return convertView;
|
||||
}
|
||||
|
||||
static class ViewHolder {
|
||||
TextView text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -260,6 +260,7 @@ public class OfflineActivity extends AppCompatActivity
|
||||
if (status.isComplete()) {
|
||||
// Download complete
|
||||
endProgress("Region downloaded successfully.");
|
||||
offlineRegion.setObserver(null);
|
||||
return;
|
||||
} else if (status.isRequiredResourceCountPrecise()) {
|
||||
// Switch to determinate state
|
||||
@@ -277,6 +278,7 @@ public class OfflineActivity extends AppCompatActivity
|
||||
public void onError(OfflineRegionError error) {
|
||||
Timber.e("onError reason: " + error.getReason());
|
||||
Timber.e("onError message: " + error.getMessage());
|
||||
offlineRegion.setObserver(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ListView
|
||||
android:id="@+id/listView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/empty"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:text="No Results"
|
||||
android:textSize="24sp"/>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -33,6 +33,7 @@
|
||||
<string name="activity_debug_mode">Debug Mode</string>
|
||||
<string name="activity_offline">Offline Map</string>
|
||||
<string name="activity_update_metadata">Update metadata Map</string>
|
||||
<string name="activity_offline_region_delete">Delete region</string>
|
||||
<string name="activity_minmax_zoom">Min/Max Zoom</string>
|
||||
<string name="activity_viewpager">ViewPager</string>
|
||||
<string name="activity_runtime_style">Runtime Style</string>
|
||||
@@ -76,6 +77,7 @@
|
||||
<string name="description_debug_mode">Debug Mode</string>
|
||||
<string name="description_offline">Offline Map example</string>
|
||||
<string name="description_update_metadata">Update metadata example</string>
|
||||
<string name="description_offline_region_delete">Delete region example</string>
|
||||
<string name="description_animated_marker">Animate the position change of a marker</string>
|
||||
<string name="description_polyline">Add a polyline to a map</string>
|
||||
<string name="description_polygon">Add a polygon to a map</string>
|
||||
|
||||
@@ -15,7 +15,7 @@ if ((ANDROID_ABI STREQUAL "armeabi") OR (ANDROID_ABI STREQUAL "armeabi-v7a") OR
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "-fuse-ld=gold -Wl,--icf=safe ${CMAKE_SHARED_LINKER_FLAGS}")
|
||||
endif()
|
||||
|
||||
mason_use(jni.hpp VERSION 2.0.0-1 HEADER_ONLY)
|
||||
mason_use(jni.hpp VERSION 3.0.0 HEADER_ONLY)
|
||||
mason_use(libzip VERSION 1.1.3)
|
||||
mason_use(nunicode VERSION 1.7.1)
|
||||
mason_use(sqlite VERSION 3.14.2)
|
||||
@@ -49,8 +49,6 @@ macro(mbgl_platform_core)
|
||||
PRIVATE platform/default/default_file_source.cpp
|
||||
PRIVATE platform/default/local_file_source.cpp
|
||||
PRIVATE platform/default/online_file_source.cpp
|
||||
PRIVATE platform/android/src/default_file_source.cpp
|
||||
PRIVATE platform/android/src/default_file_source.hpp
|
||||
|
||||
# Offline
|
||||
# PRIVATE include/mbgl/storage/offline.hpp
|
||||
@@ -137,6 +135,10 @@ macro(mbgl_platform_core)
|
||||
platform/android/src/style/functions/interval_stops.cpp
|
||||
platform/android/src/style/functions/interval_stops.hpp
|
||||
|
||||
# FileSource holder
|
||||
platform/android/src/file_source.cpp
|
||||
platform/android/src/file_source.hpp
|
||||
|
||||
# Connectivity
|
||||
platform/android/src/connectivity_listener.cpp
|
||||
platform/android/src/connectivity_listener.hpp
|
||||
@@ -145,6 +147,46 @@ macro(mbgl_platform_core)
|
||||
platform/android/src/native_map_view.cpp
|
||||
platform/android/src/native_map_view.hpp
|
||||
|
||||
# Java core classes
|
||||
platform/android/src/java/util.cpp
|
||||
platform/android/src/java/util.hpp
|
||||
|
||||
# Graphics
|
||||
platform/android/src/graphics/pointf.cpp
|
||||
platform/android/src/graphics/pointf.hpp
|
||||
platform/android/src/graphics/rectf.cpp
|
||||
platform/android/src/graphics/rectf.hpp
|
||||
|
||||
# Geometry
|
||||
platform/android/src/geometry/feature.cpp
|
||||
platform/android/src/geometry/feature.hpp
|
||||
platform/android/src/geometry/lat_lng.cpp
|
||||
platform/android/src/geometry/lat_lng.hpp
|
||||
platform/android/src/geometry/lat_lng_bounds.cpp
|
||||
platform/android/src/geometry/lat_lng_bounds.hpp
|
||||
platform/android/src/geometry/projected_meters.cpp
|
||||
platform/android/src/geometry/projected_meters.hpp
|
||||
|
||||
# Annotation
|
||||
platform/android/src/annotation/marker.cpp
|
||||
platform/android/src/annotation/marker.hpp
|
||||
platform/android/src/annotation/polygon.cpp
|
||||
platform/android/src/annotation/polygon.hpp
|
||||
platform/android/src/annotation/polyline.cpp
|
||||
platform/android/src/annotation/polyline.hpp
|
||||
|
||||
# Offline
|
||||
platform/android/src/offline/offline_manager.cpp
|
||||
platform/android/src/offline/offline_manager.hpp
|
||||
platform/android/src/offline/offline_region.cpp
|
||||
platform/android/src/offline/offline_region.hpp
|
||||
platform/android/src/offline/offline_region_definition.cpp
|
||||
platform/android/src/offline/offline_region_definition.hpp
|
||||
platform/android/src/offline/offline_region_error.cpp
|
||||
platform/android/src/offline/offline_region_error.hpp
|
||||
platform/android/src/offline/offline_region_status.cpp
|
||||
platform/android/src/offline/offline_region_status.hpp
|
||||
|
||||
# Main jni bindings
|
||||
platform/android/src/attach_env.cpp
|
||||
platform/android/src/attach_env.hpp
|
||||
|
||||
31
platform/android/src/annotation/marker.cpp
Normal file
31
platform/android/src/annotation/marker.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "marker.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
jni::Class<Marker> Marker::javaClass;
|
||||
|
||||
mbgl::Point<double> Marker::getPosition(jni::JNIEnv& env, jni::Object<Marker> marker) {
|
||||
static auto positionField = Marker::javaClass.GetField<jni::Object<LatLng>>(env, "position");
|
||||
auto jPosition = marker.Get(env, positionField);
|
||||
auto position = LatLng::getGeometry(env, jPosition);
|
||||
jni::DeleteLocalRef(env, jPosition);
|
||||
return position;
|
||||
}
|
||||
|
||||
std::string Marker::getIconId(jni::JNIEnv& env, jni::Object<Marker> marker) {
|
||||
static auto iconIdField = Marker::javaClass.GetField<jni::String>(env, "iconId");
|
||||
auto jIconId = marker.Get(env, iconIdField);
|
||||
auto iconId = jni::Make<std::string>(env, jIconId);
|
||||
jni::DeleteLocalRef(env, jIconId);
|
||||
return iconId;
|
||||
}
|
||||
|
||||
void Marker::registerNative(jni::JNIEnv& env) {
|
||||
// Lookup the class
|
||||
Marker::javaClass = *jni::Class<Marker>::Find(env).NewGlobalRef(env).release();
|
||||
}
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
30
platform/android/src/annotation/marker.hpp
Normal file
30
platform/android/src/annotation/marker.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "../geometry/lat_lng.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class Marker : private mbgl::util::noncopyable {
|
||||
public:
|
||||
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/annotations/Marker"; };
|
||||
|
||||
static jni::Class<Marker> javaClass;
|
||||
|
||||
static mbgl::Point<double> getPosition(jni::JNIEnv&, jni::Object<Marker>);
|
||||
|
||||
static std::string getIconId(jni::JNIEnv&, jni::Object<Marker>);
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
42
platform/android/src/annotation/multi_point.hpp
Normal file
42
platform/android/src/annotation/multi_point.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
#include "../geometry/lat_lng.hpp"
|
||||
#include "../java/util.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class MultiPoint : protected mbgl::util::noncopyable {
|
||||
|
||||
protected:
|
||||
|
||||
template <class Geometry>
|
||||
static Geometry toGeometry(JNIEnv& env, jni::Object<java::util::List> pointsList) {
|
||||
NullCheck(env, &pointsList);
|
||||
auto jarray = java::util::List::toArray<LatLng>(env, pointsList);
|
||||
NullCheck(env, &jarray);
|
||||
|
||||
std::size_t size = jarray.Length(env);
|
||||
|
||||
Geometry geometry;
|
||||
geometry.reserve(size);
|
||||
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
auto latLng = jarray.Get(env, i);
|
||||
NullCheck(env, &latLng);
|
||||
|
||||
geometry.push_back(LatLng::getGeometry(env, latLng));
|
||||
|
||||
jni::DeleteLocalRef(env, latLng);
|
||||
}
|
||||
|
||||
jni::DeleteLocalRef(env, jarray);
|
||||
return geometry;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
49
platform/android/src/annotation/polygon.cpp
Normal file
49
platform/android/src/annotation/polygon.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include "polygon.hpp"
|
||||
|
||||
#include "../conversion/color.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
jni::Class<Polygon> Polygon::javaClass;
|
||||
|
||||
mbgl::FillAnnotation Polygon::toAnnotation(jni::JNIEnv& env, jni::Object<Polygon> polygon) {
|
||||
auto points = Polygon::getPoints(env, polygon);
|
||||
|
||||
mbgl::FillAnnotation annotation { mbgl::Polygon<double> { MultiPoint::toGeometry<mbgl::LinearRing<double>>(env, points) } };
|
||||
annotation.opacity = { Polygon::getOpacity(env, polygon) };
|
||||
annotation.color = { Polygon::getFillColor(env, polygon) };
|
||||
annotation.outlineColor = { Polygon::getOutlineColor(env, polygon) };
|
||||
|
||||
jni::DeleteLocalRef(env, points);
|
||||
|
||||
return annotation;
|
||||
}
|
||||
|
||||
jni::Object<java::util::List> Polygon::getPoints(jni::JNIEnv& env, jni::Object<Polygon> polygon) {
|
||||
static auto field = Polygon::javaClass.GetField<jni::Object<java::util::List>>(env, "points");
|
||||
return polygon.Get(env, field);
|
||||
}
|
||||
|
||||
float Polygon::getOpacity(jni::JNIEnv& env, jni::Object<Polygon> polygon) {
|
||||
static auto field = Polygon::javaClass.GetField<float>(env, "alpha");
|
||||
return polygon.Get(env, field);
|
||||
}
|
||||
|
||||
mbgl::Color Polygon::getFillColor(jni::JNIEnv& env, jni::Object<Polygon> polygon) {
|
||||
static auto field = Polygon::javaClass.GetField<int>(env, "fillColor");
|
||||
return *conversion::convert<mbgl::Color, int>(env, polygon.Get(env, field));
|
||||
}
|
||||
|
||||
mbgl::Color Polygon::getOutlineColor(jni::JNIEnv& env, jni::Object<Polygon> polygon) {
|
||||
static auto field = Polygon::javaClass.GetField<int>(env, "strokeColor");
|
||||
return *conversion::convert<mbgl::Color, int>(env, polygon.Get(env, field));
|
||||
}
|
||||
|
||||
void Polygon::registerNative(jni::JNIEnv& env) {
|
||||
Polygon::javaClass = *jni::Class<Polygon>::Find(env).NewGlobalRef(env).release();
|
||||
}
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
40
platform/android/src/annotation/polygon.hpp
Normal file
40
platform/android/src/annotation/polygon.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/annotation/annotation.hpp>
|
||||
#include <mbgl/util/color.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "multi_point.hpp"
|
||||
|
||||
#include "../geometry/lat_lng.hpp"
|
||||
#include "../java/util.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class Polygon : private MultiPoint {
|
||||
public:
|
||||
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/annotations/Polygon"; };
|
||||
|
||||
static jni::Class<Polygon> javaClass;
|
||||
|
||||
static mbgl::FillAnnotation toAnnotation(jni::JNIEnv&, jni::Object<Polygon>);
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
|
||||
private:
|
||||
|
||||
static jni::Object<java::util::List> getPoints(jni::JNIEnv&, jni::Object<Polygon>);
|
||||
|
||||
static float getOpacity(jni::JNIEnv&, jni::Object<Polygon>);
|
||||
|
||||
static mbgl::Color getFillColor(jni::JNIEnv&, jni::Object<Polygon>);
|
||||
|
||||
static mbgl::Color getOutlineColor(jni::JNIEnv&, jni::Object<Polygon>);
|
||||
};
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
49
platform/android/src/annotation/polyline.cpp
Normal file
49
platform/android/src/annotation/polyline.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include "polyline.hpp"
|
||||
|
||||
#include "../conversion/color.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
jni::Class<Polyline> Polyline::javaClass;
|
||||
|
||||
mbgl::LineAnnotation Polyline::toAnnotation(jni::JNIEnv& env, jni::Object<Polyline> polyline) {
|
||||
auto points = Polyline::getPoints(env, polyline);
|
||||
|
||||
mbgl::LineAnnotation annotation { MultiPoint::toGeometry<mbgl::LineString<double>>(env, points) };
|
||||
annotation.opacity = { Polyline::getOpacity(env, polyline) };
|
||||
annotation.color = { Polyline::getColor(env, polyline) };
|
||||
annotation.width = { Polyline::getWidth(env, polyline) };
|
||||
|
||||
jni::DeleteLocalRef(env, points);
|
||||
|
||||
return annotation;
|
||||
}
|
||||
|
||||
jni::Object<java::util::List> Polyline::getPoints(jni::JNIEnv& env, jni::Object<Polyline> polyline) {
|
||||
static auto field = Polyline::javaClass.GetField<jni::Object<java::util::List>>(env, "points");
|
||||
return polyline.Get(env, field);
|
||||
}
|
||||
|
||||
float Polyline::getOpacity(jni::JNIEnv& env, jni::Object<Polyline> polyline) {
|
||||
static auto field = Polyline::javaClass.GetField<float>(env, "alpha");
|
||||
return polyline.Get(env, field);
|
||||
}
|
||||
|
||||
mbgl::Color Polyline::getColor(jni::JNIEnv& env, jni::Object<Polyline> polyline) {
|
||||
static auto field = Polyline::javaClass.GetField<int>(env, "color");
|
||||
return *conversion::convert<mbgl::Color, int>(env, polyline.Get(env, field));
|
||||
}
|
||||
|
||||
float Polyline::getWidth(jni::JNIEnv& env, jni::Object<Polyline> polyline) {
|
||||
static auto field = Polyline::javaClass.GetField<float>(env, "width");
|
||||
return polyline.Get(env, field);
|
||||
}
|
||||
|
||||
void Polyline::registerNative(jni::JNIEnv& env) {
|
||||
Polyline::javaClass = *jni::Class<Polyline>::Find(env).NewGlobalRef(env).release();
|
||||
}
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
40
platform/android/src/annotation/polyline.hpp
Normal file
40
platform/android/src/annotation/polyline.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/annotation/annotation.hpp>
|
||||
#include <mbgl/util/color.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "multi_point.hpp"
|
||||
|
||||
#include "../geometry/lat_lng.hpp"
|
||||
#include "../java/util.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class Polyline : private MultiPoint {
|
||||
public:
|
||||
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/annotations/Polyline"; };
|
||||
|
||||
static jni::Class<Polyline> javaClass;
|
||||
|
||||
static mbgl::LineAnnotation toAnnotation(jni::JNIEnv&, jni::Object<Polyline>);
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
|
||||
private:
|
||||
|
||||
static jni::Object<java::util::List> getPoints(jni::JNIEnv&, jni::Object<Polyline>);
|
||||
|
||||
static float getOpacity(jni::JNIEnv&, jni::Object<Polyline>);
|
||||
|
||||
static mbgl::Color getColor(jni::JNIEnv&, jni::Object<Polyline>);
|
||||
|
||||
static float getWidth(jni::JNIEnv&, jni::Object<Polyline>);
|
||||
};
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
@@ -38,6 +38,19 @@ inline std::vector<std::string> toVector(JNIEnv& env, jni::jarray<jni::jobject>&
|
||||
return vector;
|
||||
}
|
||||
|
||||
inline std::vector<std::string> toVector(JNIEnv& env, jni::Array<jni::String> array) {
|
||||
std::vector<std::string> vector;
|
||||
std::size_t len = array.Length(env);
|
||||
|
||||
for (std::size_t i = 0; i < len; i++) {
|
||||
jni::String jstr = array.Get(env, i);
|
||||
vector.push_back(*convert<std::string, jni::String>(env, jstr));
|
||||
jni::DeleteLocalRef(env, jstr);
|
||||
}
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
24
platform/android/src/conversion/color.hpp
Normal file
24
platform/android/src/conversion/color.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include "conversion.hpp"
|
||||
|
||||
#include <mbgl/util/color.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
namespace conversion {
|
||||
|
||||
template <>
|
||||
struct Converter<mbgl::Color, int> {
|
||||
Result<mbgl::Color> operator()(jni::JNIEnv&, const int& color) const {
|
||||
float r = (color >> 16) & 0xFF;
|
||||
float g = (color >> 8) & 0xFF;
|
||||
float b = (color) & 0xFF;
|
||||
float a = (color >> 24) & 0xFF;
|
||||
return { mbgl::Color( r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f ) };
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
@@ -1,20 +0,0 @@
|
||||
#include "default_file_source.hpp"
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
DefaultFileSource& defaultFileSource(const std::string& cachePath_, const std::string& assetRoot_) {
|
||||
static auto cachePath = cachePath_;
|
||||
assert(cachePath == cachePath_);
|
||||
static auto assetRoot = assetRoot_;
|
||||
assert(assetRoot == assetRoot_);
|
||||
|
||||
static DefaultFileSource defaultFileSource{ cachePath, assetRoot };
|
||||
return defaultFileSource;
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
@@ -1,12 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/storage/default_file_source.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
DefaultFileSource& defaultFileSource(const std::string& cachePath = ":memory:",
|
||||
const std::string& assetRoot = ".");
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
106
platform/android/src/file_source.cpp
Normal file
106
platform/android/src/file_source.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
#include "file_source.hpp"
|
||||
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "jni/generic_global_ref_deleter.hpp"
|
||||
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
// FileSource //
|
||||
|
||||
FileSource::FileSource(jni::JNIEnv& _env, jni::String accessToken, jni::String _cachePath, jni::String _apkPath) {
|
||||
// Create a core default file source
|
||||
fileSource = std::make_unique<mbgl::DefaultFileSource>(
|
||||
jni::Make<std::string>(_env, _cachePath) + "/mbgl-offline.db",
|
||||
jni::Make<std::string>(_env, _apkPath));
|
||||
|
||||
// Set access token
|
||||
fileSource->setAccessToken(jni::Make<std::string>(_env, accessToken));
|
||||
}
|
||||
|
||||
FileSource::~FileSource() {
|
||||
}
|
||||
|
||||
jni::String FileSource::getAccessToken(jni::JNIEnv& env) {
|
||||
return jni::Make<jni::String>(env, fileSource->getAccessToken());
|
||||
}
|
||||
|
||||
void FileSource::setAccessToken(jni::JNIEnv& env, jni::String token) {
|
||||
fileSource->setAccessToken(jni::Make<std::string>(env, token));
|
||||
}
|
||||
|
||||
void FileSource::setAPIBaseUrl(jni::JNIEnv& env, jni::String url) {
|
||||
fileSource->setAPIBaseURL(jni::Make<std::string>(env, url));
|
||||
}
|
||||
|
||||
void FileSource::setResourceTransform(jni::JNIEnv& env, jni::Object<FileSource::ResourceTransformCallback> transformCallback) {
|
||||
if (transformCallback) {
|
||||
// Launch transformCallback
|
||||
fileSource->setResourceTransform([
|
||||
// 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::shared_ptr<jni::jobject>(transformCallback.NewGlobalRef(env).release()->Get(), GenericGlobalRefDeleter()),
|
||||
env
|
||||
](mbgl::Resource::Kind kind, std::string&& url_) {
|
||||
return FileSource::ResourceTransformCallback::onURL(const_cast<jni::JNIEnv&>(env), jni::Object<FileSource::ResourceTransformCallback>(*callback), int(kind), url_);
|
||||
});
|
||||
} else {
|
||||
// Reset the callback
|
||||
fileSource->setResourceTransform(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
jni::Class<FileSource> FileSource::javaClass;
|
||||
|
||||
FileSource* FileSource::getNativePeer(jni::JNIEnv& env, jni::Object<FileSource> jFileSource) {
|
||||
static auto field = FileSource::javaClass.GetField<jlong>(env, "nativePtr");
|
||||
return reinterpret_cast<FileSource *>(jFileSource.Get(env, field));
|
||||
}
|
||||
|
||||
mbgl::DefaultFileSource& FileSource::getDefaultFileSource(jni::JNIEnv& env, jni::Object<FileSource> jFileSource) {
|
||||
FileSource* fileSource = FileSource::getNativePeer(env, jFileSource);
|
||||
assert(fileSource != nullptr);
|
||||
return *fileSource->fileSource;
|
||||
}
|
||||
|
||||
void FileSource::registerNative(jni::JNIEnv& env) {
|
||||
//Register classes
|
||||
FileSource::javaClass = *jni::Class<FileSource>::Find(env).NewGlobalRef(env).release();
|
||||
FileSource::ResourceTransformCallback::javaClass = *jni::Class<FileSource::ResourceTransformCallback>::Find(env).NewGlobalRef(env).release();
|
||||
|
||||
#define METHOD(MethodPtr, name) jni::MakeNativePeerMethod<decltype(MethodPtr), (MethodPtr)>(name)
|
||||
|
||||
// Register the peer
|
||||
jni::RegisterNativePeer<FileSource>(
|
||||
env, FileSource::javaClass, "nativePtr",
|
||||
std::make_unique<FileSource, JNIEnv&, jni::String, jni::String, jni::String>,
|
||||
"initialize",
|
||||
"finalize",
|
||||
METHOD(&FileSource::getAccessToken, "getAccessToken"),
|
||||
METHOD(&FileSource::setAccessToken, "setAccessToken"),
|
||||
METHOD(&FileSource::setAPIBaseUrl, "setApiBaseUrl"),
|
||||
METHOD(&FileSource::setResourceTransform, "setResourceTransform")
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// FileSource::ResourceTransformCallback //
|
||||
|
||||
jni::Class<FileSource::ResourceTransformCallback> FileSource::ResourceTransformCallback::javaClass;
|
||||
|
||||
std::string FileSource::ResourceTransformCallback::onURL(jni::JNIEnv& env, jni::Object<FileSource::ResourceTransformCallback> callback, int kind, std::string url_) {
|
||||
static auto method = FileSource::ResourceTransformCallback::javaClass.GetMethod<jni::String (jni::jint, jni::String)>(env, "onURL");
|
||||
auto url = jni::Make<jni::String>(env, url_);
|
||||
url = callback.Call(env, method, kind, url);
|
||||
return jni::Make<std::string>(env, url);
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
53
platform/android/src/file_source.hpp
Normal file
53
platform/android/src/file_source.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/storage/default_file_source.hpp>
|
||||
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
/**
|
||||
* Peer class for the Android FileSource holder. Ensures that a single DefaultFileSource is used
|
||||
*/
|
||||
class FileSource {
|
||||
public:
|
||||
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/storage/FileSource"; };
|
||||
|
||||
struct ResourceTransformCallback {
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/storage/FileSource$ResourceTransformCallback"; }
|
||||
|
||||
static std::string onURL(jni::JNIEnv&, jni::Object<FileSource::ResourceTransformCallback>, int, std::string);
|
||||
|
||||
static jni::Class<ResourceTransformCallback> javaClass;
|
||||
};
|
||||
|
||||
FileSource(jni::JNIEnv&, jni::String, jni::String, jni::String);
|
||||
|
||||
~FileSource();
|
||||
|
||||
jni::String getAccessToken(jni::JNIEnv&);
|
||||
|
||||
void setAccessToken(jni::JNIEnv&, jni::String);
|
||||
|
||||
void setAPIBaseUrl(jni::JNIEnv&, jni::String);
|
||||
|
||||
void setResourceTransform(jni::JNIEnv&, jni::Object<FileSource::ResourceTransformCallback>);
|
||||
|
||||
static jni::Class<FileSource> javaClass;
|
||||
|
||||
static FileSource* getNativePeer(jni::JNIEnv&, jni::Object<FileSource>);
|
||||
|
||||
static mbgl::DefaultFileSource& getDefaultFileSource(jni::JNIEnv&, jni::Object<FileSource>);
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
|
||||
private:
|
||||
|
||||
std::unique_ptr<mbgl::DefaultFileSource> fileSource;
|
||||
};
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "../../conversion/constant.hpp"
|
||||
#include "../../conversion/conversion.hpp"
|
||||
#include "geometry.hpp"
|
||||
#include "../../gson/json_object.hpp"
|
||||
|
||||
#include <mbgl/util/feature.hpp>
|
||||
#include <mapbox/variant.hpp>
|
||||
@@ -10,6 +11,7 @@
|
||||
|
||||
#include <jni/jni.hpp>
|
||||
#include "../../jni/local_object.hpp"
|
||||
#include "../feature.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <array>
|
||||
@@ -168,39 +170,45 @@ struct Converter<jni::jobject*, std::unordered_map<std::string, mbgl::Value>> {
|
||||
|
||||
|
||||
template <>
|
||||
struct Converter<jni::jobject*, mbgl::Feature> {
|
||||
Result<jni::jobject*> operator()(jni::JNIEnv& env, const mbgl::Feature& value) const {
|
||||
static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/services/commons/geojson/Feature")).release();
|
||||
static jni::jmethodID* fromGeometry = &jni::GetStaticMethodID(env, *javaClass, "fromGeometry", "(Lcom/mapbox/services/commons/geojson/Geometry;Lcom/google/gson/JsonObject;Ljava/lang/String;)Lcom/mapbox/services/commons/geojson/Feature;");
|
||||
struct Converter<jni::Object<Feature>, mbgl::Feature> {
|
||||
Result<jni::Object<Feature>> operator()(jni::JNIEnv& env, const mbgl::Feature& value) const {
|
||||
|
||||
// Convert Id
|
||||
FeatureIdVisitor idEvaluator;
|
||||
std::string id = (value.id) ? mapbox::geometry::identifier::visit(value.id.value(), idEvaluator) : "";
|
||||
jni::LocalObject<jni::jobject> jid = jni::NewLocalObject(env, *convert<jni::jobject*>(env, id));
|
||||
auto jid = jni::Make<jni::String>(env, id);
|
||||
|
||||
// Convert properties
|
||||
jni::LocalObject<jni::jobject> properties = jni::NewLocalObject(env, *convert<jni::jobject*>(env, value.properties));
|
||||
auto properties = jni::Object<JsonObject>(*convert<jni::jobject*>(env, value.properties));
|
||||
|
||||
// Convert geometry
|
||||
jni::LocalObject<jni::jobject> geometry = jni::NewLocalObject(env, *convert<jni::jobject*>(env, value.geometry));
|
||||
auto geometry = jni::Object<Geometry>(*convert<jni::jobject*>(env, value.geometry));
|
||||
|
||||
// Create feature
|
||||
return {reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromGeometry, geometry.get(), properties.get(), jid.get()))};
|
||||
auto feature = Feature::fromGeometry(env, geometry, properties, jid);
|
||||
|
||||
//Cleanup
|
||||
jni::DeleteLocalRef(env, jid);
|
||||
jni::DeleteLocalRef(env, geometry);
|
||||
jni::DeleteLocalRef(env, properties);
|
||||
|
||||
return feature;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<jni::jarray<jni::jobject>*, std::vector<mbgl::Feature>> {
|
||||
Result<jni::jarray<jni::jobject>*> operator()(jni::JNIEnv& env, const std::vector<mbgl::Feature>& value) const {
|
||||
static jni::jclass* featureClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/services/commons/geojson/Feature")).release();
|
||||
jni::jarray<jni::jobject>& jarray = jni::NewObjectArray(env, value.size(), *featureClass);
|
||||
struct Converter<jni::Array<jni::Object<Feature>>, std::vector<mbgl::Feature>> {
|
||||
Result<jni::Array<jni::Object<Feature>>> operator()(jni::JNIEnv& env, const std::vector<mbgl::Feature>& value) const {
|
||||
|
||||
auto features = jni::Array<jni::Object<Feature>>::New(env, value.size(), Feature::javaClass);
|
||||
|
||||
for(size_t i = 0; i < value.size(); i = i + 1) {
|
||||
jni::LocalObject<jni::jobject> converted = jni::NewLocalObject(env, *convert<jni::jobject*, mbgl::Feature>(env, value.at(i)));
|
||||
jni::SetObjectArrayElement(env, jarray, i, converted.get());
|
||||
auto converted = *convert<jni::Object<Feature>, mbgl::Feature>(env, value.at(i));
|
||||
features.Set(env, i, converted);
|
||||
jni::DeleteLocalRef(env, converted);
|
||||
}
|
||||
|
||||
return {&jarray};
|
||||
return {features};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
20
platform/android/src/geometry/feature.cpp
Normal file
20
platform/android/src/geometry/feature.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "feature.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
jni::Object<Feature> Feature::fromGeometry(jni::JNIEnv& env, jni::Object<Geometry> geometry, jni::Object<JsonObject> properties, jni::String id) {
|
||||
static auto method = Feature::javaClass.GetStaticMethod<jni::Object<Feature> (jni::Object<Geometry>, jni::Object<JsonObject>, jni::String)>(env, "fromGeometry");
|
||||
return Feature::javaClass.Call(env, method, geometry, properties, id);
|
||||
}
|
||||
|
||||
void Feature::registerNative(jni::JNIEnv& env) {
|
||||
// Lookup the class
|
||||
Feature::javaClass = *jni::Class<Feature>::Find(env).NewGlobalRef(env).release();
|
||||
}
|
||||
|
||||
jni::Class<Feature> Feature::javaClass;
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
29
platform/android/src/geometry/feature.hpp
Normal file
29
platform/android/src/geometry/feature.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/geometry.hpp>
|
||||
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
#include "geometry.hpp"
|
||||
#include "../gson/json_object.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class Feature : private mbgl::util::noncopyable {
|
||||
public:
|
||||
|
||||
static constexpr auto Name() { return "com/mapbox/services/commons/geojson/Feature"; };
|
||||
|
||||
static jni::Object<Feature> fromGeometry(jni::JNIEnv&, jni::Object<Geometry>, jni::Object<JsonObject>, jni::String);
|
||||
|
||||
static jni::Class<Feature> javaClass;
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
16
platform/android/src/geometry/geometry.hpp
Normal file
16
platform/android/src/geometry/geometry.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class Geometry : private mbgl::util::noncopyable {
|
||||
public:
|
||||
static constexpr auto Name() { return "com/mapbox/services/commons/geojson/Geometry"; };
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
31
platform/android/src/geometry/lat_lng.cpp
Normal file
31
platform/android/src/geometry/lat_lng.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "lat_lng.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
jni::Object<LatLng> LatLng::New(jni::JNIEnv& env, double latitude, double longitude) {
|
||||
static auto constructor = LatLng::javaClass.GetConstructor<double, double>(env);
|
||||
return LatLng::javaClass.New(env, constructor, latitude, longitude);
|
||||
}
|
||||
|
||||
mbgl::Point<double> LatLng::getGeometry(jni::JNIEnv& env, jni::Object<LatLng> latLng) {
|
||||
static auto latitudeField = LatLng::javaClass.GetField<jni::jdouble>(env, "latitude");
|
||||
static auto longitudeField = LatLng::javaClass.GetField<jni::jdouble>(env, "longitude");
|
||||
return mbgl::Point<double>(latLng.Get(env, longitudeField), latLng.Get(env, latitudeField));
|
||||
}
|
||||
|
||||
mbgl::LatLng LatLng::getLatLng(jni::JNIEnv& env, jni::Object<LatLng> latLng) {
|
||||
auto point = LatLng::getGeometry(env, latLng);
|
||||
return mbgl::LatLng(point.y, point.x);
|
||||
}
|
||||
|
||||
void LatLng::registerNative(jni::JNIEnv& env) {
|
||||
// Lookup the class
|
||||
LatLng::javaClass = *jni::Class<LatLng>::Find(env).NewGlobalRef(env).release();
|
||||
}
|
||||
|
||||
jni::Class<LatLng> LatLng::javaClass;
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
31
platform/android/src/geometry/lat_lng.hpp
Normal file
31
platform/android/src/geometry/lat_lng.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/geo.hpp>
|
||||
#include <mbgl/util/geometry.hpp>
|
||||
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class LatLng : private mbgl::util::noncopyable {
|
||||
public:
|
||||
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/geometry/LatLng"; };
|
||||
|
||||
static jni::Object<LatLng> New(jni::JNIEnv&, double, double);
|
||||
|
||||
static mbgl::Point<double> getGeometry(jni::JNIEnv&, jni::Object<LatLng>);
|
||||
|
||||
static mbgl::LatLng getLatLng(jni::JNIEnv&, jni::Object<LatLng>);
|
||||
|
||||
static jni::Class<LatLng> javaClass;
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
31
platform/android/src/geometry/lat_lng_bounds.cpp
Normal file
31
platform/android/src/geometry/lat_lng_bounds.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "lat_lng_bounds.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
jni::Object<LatLngBounds> LatLngBounds::New(jni::JNIEnv& env, mbgl::LatLngBounds bounds) {
|
||||
static auto constructor = LatLngBounds::javaClass.GetConstructor<double, double, double, double>(env);
|
||||
return LatLngBounds::javaClass.New(env, constructor, bounds.north(), bounds.east(), bounds.south(), bounds.west());
|
||||
}
|
||||
|
||||
mbgl::LatLngBounds LatLngBounds::getLatLngBounds(jni::JNIEnv& env, jni::Object<LatLngBounds> bounds) {
|
||||
static auto swLat = LatLngBounds::javaClass.GetField<jni::jdouble>(env, "mLatSouth");
|
||||
static auto swLon = LatLngBounds::javaClass.GetField<jni::jdouble>(env, "mLonWest");
|
||||
static auto neLat = LatLngBounds::javaClass.GetField<jni::jdouble>(env, "mLatNorth");
|
||||
static auto neLon = LatLngBounds::javaClass.GetField<jni::jdouble>(env, "mLonEast");
|
||||
return mbgl::LatLngBounds::hull(
|
||||
{ bounds.Get(env, swLat), bounds.Get(env, swLon) },
|
||||
{ bounds.Get(env, neLat), bounds.Get(env, neLon) }
|
||||
);
|
||||
}
|
||||
|
||||
void LatLngBounds::registerNative(jni::JNIEnv& env) {
|
||||
// Lookup the class
|
||||
LatLngBounds::javaClass = *jni::Class<LatLngBounds>::Find(env).NewGlobalRef(env).release();
|
||||
}
|
||||
|
||||
jni::Class<LatLngBounds> LatLngBounds::javaClass;
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
29
platform/android/src/geometry/lat_lng_bounds.hpp
Normal file
29
platform/android/src/geometry/lat_lng_bounds.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/geo.hpp>
|
||||
#include <mbgl/util/geometry.hpp>
|
||||
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class LatLngBounds : private mbgl::util::noncopyable {
|
||||
public:
|
||||
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/geometry/LatLngBounds"; };
|
||||
|
||||
static jni::Object<LatLngBounds> New(jni::JNIEnv&, mbgl::LatLngBounds);
|
||||
|
||||
static mbgl::LatLngBounds getLatLngBounds(jni::JNIEnv&, jni::Object<LatLngBounds>);
|
||||
|
||||
static jni::Class<LatLngBounds> javaClass;
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
20
platform/android/src/geometry/projected_meters.cpp
Normal file
20
platform/android/src/geometry/projected_meters.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "projected_meters.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
jni::Object<ProjectedMeters> ProjectedMeters::New(jni::JNIEnv& env, double northing, double easting) {
|
||||
static auto constructor = ProjectedMeters::javaClass.GetConstructor<double, double>(env);
|
||||
return ProjectedMeters::javaClass.New(env, constructor, northing, easting);
|
||||
}
|
||||
|
||||
void ProjectedMeters::registerNative(jni::JNIEnv& env) {
|
||||
// Lookup the class
|
||||
ProjectedMeters::javaClass = *jni::Class<ProjectedMeters>::Find(env).NewGlobalRef(env).release();
|
||||
}
|
||||
|
||||
jni::Class<ProjectedMeters> ProjectedMeters::javaClass;
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
26
platform/android/src/geometry/projected_meters.hpp
Normal file
26
platform/android/src/geometry/projected_meters.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/geometry.hpp>
|
||||
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class ProjectedMeters : private mbgl::util::noncopyable {
|
||||
public:
|
||||
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/geometry/ProjectedMeters"; };
|
||||
|
||||
static jni::Object<ProjectedMeters> New(jni::JNIEnv&, double, double);
|
||||
|
||||
static jni::Class<ProjectedMeters> javaClass;
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
20
platform/android/src/graphics/pointf.cpp
Normal file
20
platform/android/src/graphics/pointf.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "pointf.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
jni::Object<PointF> PointF::New(jni::JNIEnv& env, float x, float y) {
|
||||
static auto constructor = PointF::javaClass.GetConstructor<float, float>(env);
|
||||
return PointF::javaClass.New(env, constructor, x, y);
|
||||
}
|
||||
|
||||
void PointF::registerNative(jni::JNIEnv& env) {
|
||||
// Lookup the class
|
||||
PointF::javaClass = *jni::Class<PointF>::Find(env).NewGlobalRef(env).release();
|
||||
}
|
||||
|
||||
jni::Class<PointF> PointF::javaClass;
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
25
platform/android/src/graphics/pointf.hpp
Normal file
25
platform/android/src/graphics/pointf.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class PointF : private mbgl::util::noncopyable {
|
||||
public:
|
||||
|
||||
static constexpr auto Name() { return "android/graphics/PointF"; };
|
||||
|
||||
static jni::Object<PointF> New(jni::JNIEnv&, float, float);
|
||||
|
||||
static jni::Class<PointF> javaClass;
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
35
platform/android/src/graphics/rectf.cpp
Normal file
35
platform/android/src/graphics/rectf.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#include "rectf.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
float RectF::getLeft(jni::JNIEnv& env, jni::Object<RectF> rectf) {
|
||||
static auto field = RectF::javaClass.GetField<float>(env, "left");
|
||||
return rectf.Get(env, field);
|
||||
}
|
||||
|
||||
float RectF::getTop(jni::JNIEnv& env, jni::Object<RectF> rectf) {
|
||||
static auto field = RectF::javaClass.GetField<float>(env, "top");
|
||||
return rectf.Get(env, field);
|
||||
}
|
||||
|
||||
float RectF::getRight(jni::JNIEnv& env, jni::Object<RectF> rectf) {
|
||||
static auto field = RectF::javaClass.GetField<float>(env, "right");
|
||||
return rectf.Get(env, field);
|
||||
}
|
||||
|
||||
float RectF::getBottom(jni::JNIEnv& env, jni::Object<RectF> rectf) {
|
||||
static auto field = RectF::javaClass.GetField<float>(env, "bottom");
|
||||
return rectf.Get(env, field);
|
||||
}
|
||||
|
||||
void RectF::registerNative(jni::JNIEnv& env) {
|
||||
// Lookup the class
|
||||
RectF::javaClass = *jni::Class<RectF>::Find(env).NewGlobalRef(env).release();
|
||||
}
|
||||
|
||||
jni::Class<RectF> RectF::javaClass;
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
31
platform/android/src/graphics/rectf.hpp
Normal file
31
platform/android/src/graphics/rectf.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class RectF : private mbgl::util::noncopyable {
|
||||
public:
|
||||
|
||||
static constexpr auto Name() { return "android/graphics/RectF"; };
|
||||
|
||||
static float getLeft(jni::JNIEnv&, jni::Object<RectF>);
|
||||
|
||||
static float getTop(jni::JNIEnv&, jni::Object<RectF>);
|
||||
|
||||
static float getRight(jni::JNIEnv&, jni::Object<RectF>);
|
||||
|
||||
static float getBottom(jni::JNIEnv&, jni::Object<RectF>);
|
||||
|
||||
static jni::Class<RectF> javaClass;
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
16
platform/android/src/gson/json_object.hpp
Normal file
16
platform/android/src/gson/json_object.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class JsonObject : private mbgl::util::noncopyable {
|
||||
public:
|
||||
static constexpr auto Name() { return "com/google/gson/JsonObject"; };
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
18
platform/android/src/java/util.cpp
Normal file
18
platform/android/src/java/util.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "util.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
namespace java {
|
||||
namespace util {
|
||||
|
||||
jni::Class<List> List::javaClass;
|
||||
|
||||
void registerNative(jni::JNIEnv& env) {
|
||||
List::javaClass = *jni::Class<List>::Find(env).NewGlobalRef(env).release();
|
||||
}
|
||||
|
||||
|
||||
} // namespace util
|
||||
} // namespace java
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
33
platform/android/src/java/util.hpp
Normal file
33
platform/android/src/java/util.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
namespace java {
|
||||
namespace util {
|
||||
|
||||
class List : private mbgl::util::noncopyable {
|
||||
public:
|
||||
|
||||
static constexpr auto Name() { return "java/util/List"; };
|
||||
|
||||
template<class T>
|
||||
static jni::Array<jni::Object<T>> toArray(jni::JNIEnv& env, jni::Object<List> list) {
|
||||
static auto toArray = List::javaClass.GetMethod<jni::Array<jni::Object<>> ()>(env, "toArray");
|
||||
return (jni::Array<jni::Object<T>>) list.Call(env, toArray);
|
||||
};
|
||||
|
||||
static jni::Class<List> javaClass;
|
||||
|
||||
};
|
||||
|
||||
void registerNative(jni::JNIEnv&);
|
||||
|
||||
|
||||
} // namespace util
|
||||
} // namespace java
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,15 +14,9 @@ extern JavaVM* theJVM;
|
||||
extern std::string cachePath;
|
||||
extern std::string dataPath;
|
||||
extern std::string apkPath;
|
||||
extern std::string androidRelease;
|
||||
|
||||
extern jmethodID onInvalidateId;
|
||||
extern jmethodID onMapChangedId;
|
||||
extern jmethodID onFpsChangedId;
|
||||
extern jmethodID onSnapshotReadyId;
|
||||
|
||||
extern bool attach_jni_thread(JavaVM* vm, JNIEnv** env, std::string threadName);
|
||||
extern void detach_jni_thread(JavaVM* vm, JNIEnv** env, bool detach);
|
||||
bool attach_jni_thread(JavaVM* vm, JNIEnv** env, std::string threadName);
|
||||
void detach_jni_thread(JavaVM* vm, JNIEnv** env, bool detach);
|
||||
|
||||
extern void registerNatives(JavaVM* vm);
|
||||
|
||||
|
||||
22
platform/android/src/jni/generic_global_ref_deleter.hpp
Normal file
22
platform/android/src/jni/generic_global_ref_deleter.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
#include "../attach_env.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
// A deleter that doesn't retain an JNIEnv handle but instead tries to attach the JVM. This means
|
||||
// it can be used on any thread to delete a global ref.
|
||||
struct GenericGlobalRefDeleter {
|
||||
void operator()(jni::jobject* p) const {
|
||||
if (p) {
|
||||
auto env = AttachEnv();
|
||||
env->DeleteGlobalRef(jni::Unwrap(p));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,71 +1,265 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/map/backend.hpp>
|
||||
#include <mbgl/map/camera.hpp>
|
||||
#include <mbgl/map/map.hpp>
|
||||
#include <mbgl/map/view.hpp>
|
||||
#include <mbgl/map/backend.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/default_thread_pool.hpp>
|
||||
#include <mbgl/util/run_loop.hpp>
|
||||
#include <mbgl/storage/default_file_source.hpp>
|
||||
#include <mbgl/storage/network_status.hpp>
|
||||
|
||||
#include "file_source.hpp"
|
||||
#include "annotation/marker.hpp"
|
||||
#include "annotation/polygon.hpp"
|
||||
#include "annotation/polyline.hpp"
|
||||
#include "graphics/pointf.hpp"
|
||||
#include "graphics/rectf.hpp"
|
||||
#include "geometry/feature.hpp"
|
||||
#include "geometry/lat_lng.hpp"
|
||||
#include "geometry/projected_meters.hpp"
|
||||
#include "style/layers/layers.hpp"
|
||||
#include "style/sources/sources.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <jni.h>
|
||||
#include <android/native_window.h>
|
||||
#include <EGL/egl.h>
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class NativeMapView : public mbgl::View, public mbgl::Backend {
|
||||
class NativeMapView : public View, public Backend {
|
||||
public:
|
||||
NativeMapView(JNIEnv *env, jobject obj, float pixelRatio, int availableProcessors, size_t totalMemory);
|
||||
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/maps/NativeMapView"; };
|
||||
|
||||
static jni::Class<NativeMapView> javaClass;
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
|
||||
NativeMapView(jni::JNIEnv&, jni::Object<NativeMapView>, jni::Object<FileSource>, jni::jfloat, jni::jint, jni::jlong);
|
||||
|
||||
virtual ~NativeMapView();
|
||||
|
||||
mbgl::Size getFramebufferSize() const;
|
||||
void updateViewBinding();
|
||||
// mbgl::View //
|
||||
|
||||
void bind() override;
|
||||
|
||||
void invalidate() override;
|
||||
// mbgl::Backend //
|
||||
|
||||
void invalidate() override;
|
||||
void notifyMapChange(mbgl::MapChange) override;
|
||||
|
||||
mbgl::Map &getMap();
|
||||
mbgl::DefaultFileSource &getFileSource();
|
||||
// JNI //
|
||||
|
||||
void initializeDisplay();
|
||||
void terminateDisplay();
|
||||
void destroy(jni::JNIEnv&);
|
||||
|
||||
void initializeContext();
|
||||
void terminateContext();
|
||||
void render(jni::JNIEnv&);
|
||||
|
||||
void createSurface(ANativeWindow *window);
|
||||
void destroySurface();
|
||||
void update(jni::JNIEnv&);
|
||||
|
||||
void render();
|
||||
void resizeView(jni::JNIEnv&, int, int);
|
||||
|
||||
void enableFps(bool enable);
|
||||
void updateFps();
|
||||
void resizeFramebuffer(jni::JNIEnv&, int, int);
|
||||
|
||||
void resizeView(int width, int height);
|
||||
void resizeFramebuffer(int width, int height);
|
||||
mbgl::EdgeInsets getInsets() { return insets;}
|
||||
void setInsets(mbgl::EdgeInsets insets_);
|
||||
void initializeDisplay(jni::JNIEnv&);
|
||||
|
||||
void scheduleTakeSnapshot();
|
||||
void terminateDisplay(jni::JNIEnv&);
|
||||
|
||||
void initializeContext(jni::JNIEnv&);
|
||||
|
||||
void terminateContext(jni::JNIEnv&);
|
||||
|
||||
void createSurface(jni::JNIEnv&, jni::Object<>);
|
||||
|
||||
void destroySurface(jni::JNIEnv&);
|
||||
|
||||
jni::String getStyleUrl(jni::JNIEnv&);
|
||||
|
||||
void setStyleUrl(jni::JNIEnv&, jni::String);
|
||||
|
||||
jni::String getStyleJson(jni::JNIEnv&);
|
||||
|
||||
void setStyleJson(jni::JNIEnv&, jni::String);
|
||||
|
||||
void cancelTransitions(jni::JNIEnv&);
|
||||
|
||||
void setGestureInProgress(jni::JNIEnv&, jni::jboolean);
|
||||
|
||||
void moveBy(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jlong);
|
||||
|
||||
void jumpTo(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jdouble, jni::jdouble, jni::jdouble);
|
||||
|
||||
void easeTo(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jdouble, jni::jlong, jni::jdouble, jni::jdouble, jni::jboolean);
|
||||
|
||||
void flyTo(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jdouble, jni::jlong, jni::jdouble, jni::jdouble);
|
||||
|
||||
jni::Object<LatLng> getLatLng(JNIEnv&);
|
||||
|
||||
void setLatLng(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jlong);
|
||||
|
||||
void setReachability(jni::JNIEnv&, jni::jboolean);
|
||||
|
||||
void resetPosition(jni::JNIEnv&);
|
||||
|
||||
jni::jdouble getPitch(jni::JNIEnv&);
|
||||
|
||||
void setPitch(jni::JNIEnv&, jni::jdouble, jni::jlong);
|
||||
|
||||
void scaleBy(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jdouble, jni::jlong);
|
||||
|
||||
void setScale(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jdouble, jni::jlong);
|
||||
|
||||
jni::jdouble getScale(jni::JNIEnv&);
|
||||
|
||||
void setZoom(jni::JNIEnv&, jni::jdouble, jni::jlong);
|
||||
|
||||
jni::jdouble getZoom(jni::JNIEnv&);
|
||||
|
||||
void resetZoom(jni::JNIEnv&);
|
||||
|
||||
void setMinZoom(jni::JNIEnv&, jni::jdouble);
|
||||
|
||||
jni::jdouble getMinZoom(jni::JNIEnv&);
|
||||
|
||||
void setMaxZoom(jni::JNIEnv&, jni::jdouble);
|
||||
|
||||
jni::jdouble getMaxZoom(jni::JNIEnv&);
|
||||
|
||||
void rotateBy(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jdouble, jni::jdouble, jni::jlong);
|
||||
|
||||
void setBearing(jni::JNIEnv&, jni::jdouble, jni::jlong);
|
||||
|
||||
void setBearingXY(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jdouble, jni::jlong);
|
||||
|
||||
jni::jdouble getBearing(jni::JNIEnv&);
|
||||
|
||||
void resetNorth(jni::JNIEnv&);
|
||||
|
||||
void setVisibleCoordinateBounds(JNIEnv&, jni::Array<jni::Object<LatLng>>, jni::Object<RectF>, jni::jdouble, jni::jlong);
|
||||
|
||||
void setContentPadding(JNIEnv&, double, double, double, double);
|
||||
|
||||
void scheduleSnapshot(jni::JNIEnv&);
|
||||
|
||||
void enableFps(jni::JNIEnv&, jni::jboolean enable);
|
||||
|
||||
jni::Array<jni::jdouble> getCameraValues(jni::JNIEnv&);
|
||||
|
||||
void updateMarker(jni::JNIEnv&, jni::jlong, jni::jdouble, jni::jdouble, jni::String);
|
||||
|
||||
jni::Array<jni::jlong> addMarkers(jni::JNIEnv&, jni::Array<jni::Object<Marker>>);
|
||||
|
||||
void onLowMemory(JNIEnv& env);
|
||||
|
||||
void setDebug(JNIEnv&, jni::jboolean);
|
||||
|
||||
void cycleDebugOptions(JNIEnv&);
|
||||
|
||||
jni::jboolean getDebug(JNIEnv&);
|
||||
|
||||
jni::jboolean isFullyLoaded(JNIEnv&);
|
||||
|
||||
jni::jdouble getMetersPerPixelAtLatitude(JNIEnv&, jni::jdouble, jni::jdouble);
|
||||
|
||||
jni::Object<ProjectedMeters> projectedMetersForLatLng(JNIEnv&, jni::jdouble, jni::jdouble);
|
||||
|
||||
jni::Object<PointF> pixelForLatLng(JNIEnv&, jdouble, jdouble);
|
||||
|
||||
jni::Object<LatLng> latLngForProjectedMeters(JNIEnv&, jdouble, jdouble);
|
||||
|
||||
jni::Object<LatLng> latLngForPixel(JNIEnv&, jfloat, jfloat);
|
||||
|
||||
jni::Array<jlong> addPolylines(JNIEnv&, jni::Array<jni::Object<Polyline>>);
|
||||
|
||||
jni::Array<jlong> addPolygons(JNIEnv&, jni::Array<jni::Object<Polygon>>);
|
||||
|
||||
void updatePolyline(JNIEnv&, jlong, jni::Object<Polyline>);
|
||||
|
||||
void updatePolygon(JNIEnv&, jlong, jni::Object<Polygon>);
|
||||
|
||||
void removeAnnotations(JNIEnv&, jni::Array<jlong>);
|
||||
|
||||
void addAnnotationIcon(JNIEnv&, jni::String, jint, jint, jfloat, jni::Array<jbyte>);
|
||||
|
||||
jni::jdouble getTopOffsetPixelsForAnnotationSymbol(JNIEnv&, jni::String);
|
||||
|
||||
jni::jlong getTransitionDuration(JNIEnv&);
|
||||
|
||||
void setTransitionDuration(JNIEnv&, jni::jlong);
|
||||
|
||||
jni::jlong getTransitionDelay(JNIEnv&);
|
||||
|
||||
void setTransitionDelay(JNIEnv&, jni::jlong);
|
||||
|
||||
jni::Array<jlong> queryPointAnnotations(JNIEnv&, jni::Object<RectF>);
|
||||
|
||||
jni::Array<jni::Object<Feature>> queryRenderedFeaturesForPoint(JNIEnv&, jni::jfloat, jni::jfloat, jni::Array<jni::String>);
|
||||
|
||||
jni::Array<jni::Object<Feature>> queryRenderedFeaturesForBox(JNIEnv&, jni::jfloat, jni::jfloat, jni::jfloat, jni::jfloat, jni::Array<jni::String>);
|
||||
|
||||
jni::Object<Layer> getLayer(JNIEnv&, jni::String);
|
||||
|
||||
void addLayer(JNIEnv&, jlong, jni::String);
|
||||
|
||||
void removeLayerById(JNIEnv&, jni::String);
|
||||
|
||||
void removeLayer(JNIEnv&, jlong);
|
||||
|
||||
jni::Object<Source> getSource(JNIEnv&, jni::String);
|
||||
|
||||
void addSource(JNIEnv&, jni::jlong);
|
||||
|
||||
void removeSourceById(JNIEnv&, jni::String);
|
||||
|
||||
void removeSource(JNIEnv&, jlong);
|
||||
|
||||
void addImage(JNIEnv&, jni::String, jni::jint, jni::jint, jni::jfloat, jni::Array<jbyte>);
|
||||
|
||||
void removeImage(JNIEnv&, jni::String);
|
||||
|
||||
protected:
|
||||
// mbgl::Backend //
|
||||
|
||||
void activate() override;
|
||||
void deactivate() override;
|
||||
|
||||
private:
|
||||
void _initializeDisplay();
|
||||
|
||||
void _terminateDisplay();
|
||||
|
||||
void _initializeContext();
|
||||
|
||||
void _terminateContext();
|
||||
|
||||
void _createSurface(ANativeWindow*);
|
||||
|
||||
void _destroySurface();
|
||||
|
||||
EGLConfig chooseConfig(const EGLConfig configs[], EGLint numConfigs);
|
||||
|
||||
void updateViewBinding();
|
||||
mbgl::Size getFramebufferSize() const;
|
||||
|
||||
void updateFps();
|
||||
|
||||
private:
|
||||
|
||||
JavaVM *vm = nullptr;
|
||||
JNIEnv *env = nullptr;
|
||||
jweak obj = nullptr;
|
||||
jni::UniqueWeakObject<NativeMapView> javaPeer;
|
||||
|
||||
std::string styleUrl;
|
||||
std::string apiKey;
|
||||
|
||||
ANativeWindow *window = nullptr;
|
||||
|
||||
EGLConfig config = nullptr;
|
||||
EGLint format = -1;
|
||||
|
||||
EGLDisplay oldDisplay = EGL_NO_DISPLAY;
|
||||
EGLSurface oldReadSurface = EGL_NO_SURFACE;
|
||||
EGLSurface oldDrawSurface = EGL_NO_SURFACE;
|
||||
@@ -75,15 +269,11 @@ private:
|
||||
EGLSurface surface = EGL_NO_SURFACE;
|
||||
EGLContext context = EGL_NO_CONTEXT;
|
||||
|
||||
EGLConfig config = nullptr;
|
||||
EGLint format = -1;
|
||||
|
||||
std::string styleUrl;
|
||||
std::string apiKey;
|
||||
|
||||
bool firstTime = false;
|
||||
float pixelRatio;
|
||||
bool fpsEnabled = false;
|
||||
bool snapshot = false;
|
||||
bool firstRender = true;
|
||||
double fps = 0.0;
|
||||
|
||||
int width = 0;
|
||||
@@ -96,12 +286,12 @@ private:
|
||||
size_t totalMemory = 0;
|
||||
|
||||
// Ensure these are initialised last
|
||||
mbgl::DefaultFileSource& fileSource;
|
||||
std::shared_ptr<mbgl::ThreadPool> threadPool;
|
||||
std::unique_ptr<mbgl::Map> map;
|
||||
mbgl::EdgeInsets insets;
|
||||
|
||||
unsigned active = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
|
||||
164
platform/android/src/offline/offline_manager.cpp
Normal file
164
platform/android/src/offline/offline_manager.cpp
Normal file
@@ -0,0 +1,164 @@
|
||||
#include "offline_manager.hpp"
|
||||
|
||||
#include <mbgl/util/string.hpp>
|
||||
|
||||
#include "../attach_env.hpp"
|
||||
#include "../jni/generic_global_ref_deleter.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
// OfflineManager //
|
||||
|
||||
OfflineManager::OfflineManager(jni::JNIEnv& env, jni::Object<FileSource> jFileSource)
|
||||
: fileSource(mbgl::android::FileSource::getDefaultFileSource(env, jFileSource)) {
|
||||
}
|
||||
|
||||
OfflineManager::~OfflineManager() {}
|
||||
|
||||
void OfflineManager::setOfflineMapboxTileCountLimit(jni::JNIEnv&, jni::jlong limit) {
|
||||
fileSource.setOfflineMapboxTileCountLimit(limit);
|
||||
}
|
||||
|
||||
void OfflineManager::listOfflineRegions(jni::JNIEnv& env_, jni::Object<FileSource> jFileSource_, jni::Object<ListOfflineRegionsCallback> callback_) {
|
||||
// list regions
|
||||
fileSource.listOfflineRegions([
|
||||
//Keep a shared ptr to a global reference of the callback and file source so they are not GC'd in the meanwhile
|
||||
callback = std::shared_ptr<jni::jobject>(callback_.NewGlobalRef(env_).release()->Get(), GenericGlobalRefDeleter()),
|
||||
jFileSource = std::shared_ptr<jni::jobject>(jFileSource_.NewGlobalRef(env_).release()->Get(), GenericGlobalRefDeleter())
|
||||
](std::exception_ptr error, mbgl::optional<std::vector<mbgl::OfflineRegion>> regions) mutable {
|
||||
|
||||
// Reattach, the callback comes from a different thread
|
||||
android::UniqueEnv env = android::AttachEnv();
|
||||
|
||||
if (error) {
|
||||
OfflineManager::ListOfflineRegionsCallback::onError(*env, jni::Object<ListOfflineRegionsCallback>(*callback), error);
|
||||
} else if (regions) {
|
||||
OfflineManager::ListOfflineRegionsCallback::onList(*env, jni::Object<FileSource>(*jFileSource), jni::Object<ListOfflineRegionsCallback>(*callback), std::move(regions));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void OfflineManager::createOfflineRegion(jni::JNIEnv& env_,
|
||||
jni::Object<FileSource> jFileSource_,
|
||||
jni::Object<OfflineRegionDefinition> definition_,
|
||||
jni::Array<jni::jbyte> metadata_,
|
||||
jni::Object<CreateOfflineRegionCallback> callback_) {
|
||||
// Convert
|
||||
|
||||
// XXX hardcoded cast for now as we only support OfflineTilePyramidRegionDefinition
|
||||
auto definition = OfflineTilePyramidRegionDefinition::getDefinition(env_, jni::Object<OfflineTilePyramidRegionDefinition>(*definition_));
|
||||
|
||||
mbgl::OfflineRegionMetadata metadata;
|
||||
if (metadata_) {
|
||||
metadata = OfflineRegion::metadata(env_, metadata_);
|
||||
}
|
||||
|
||||
// Create region
|
||||
fileSource.createOfflineRegion(definition, metadata, [
|
||||
//Keep a shared ptr to a global reference of the callback and file source so they are not GC'd in the meanwhile
|
||||
callback = std::shared_ptr<jni::jobject>(callback_.NewGlobalRef(env_).release()->Get(), GenericGlobalRefDeleter()),
|
||||
jFileSource = std::shared_ptr<jni::jobject>(jFileSource_.NewGlobalRef(env_).release()->Get(), GenericGlobalRefDeleter())
|
||||
](std::exception_ptr error, mbgl::optional<mbgl::OfflineRegion> region) mutable {
|
||||
|
||||
// Reattach, the callback comes from a different thread
|
||||
android::UniqueEnv env = android::AttachEnv();
|
||||
|
||||
if (error) {
|
||||
OfflineManager::CreateOfflineRegionCallback::onError(*env, jni::Object<CreateOfflineRegionCallback>(*callback), error);
|
||||
} else if (region) {
|
||||
OfflineManager::CreateOfflineRegionCallback::onCreate(
|
||||
*env,
|
||||
jni::Object<FileSource>(*jFileSource),
|
||||
jni::Object<CreateOfflineRegionCallback>(*callback), std::move(region)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
jni::Class<OfflineManager> OfflineManager::javaClass;
|
||||
|
||||
void OfflineManager::registerNative(jni::JNIEnv& env) {
|
||||
OfflineManager::ListOfflineRegionsCallback::registerNative(env);
|
||||
OfflineManager::CreateOfflineRegionCallback::registerNative(env);
|
||||
|
||||
javaClass = *jni::Class<OfflineManager>::Find(env).NewGlobalRef(env).release();
|
||||
|
||||
#define METHOD(MethodPtr, name) jni::MakeNativePeerMethod<decltype(MethodPtr), (MethodPtr)>(name)
|
||||
|
||||
jni::RegisterNativePeer<OfflineManager>( env, javaClass, "nativePtr",
|
||||
std::make_unique<OfflineManager, JNIEnv&, jni::Object<FileSource>>,
|
||||
"initialize",
|
||||
"finalize",
|
||||
METHOD(&OfflineManager::setOfflineMapboxTileCountLimit, "setOfflineMapboxTileCountLimit"),
|
||||
METHOD(&OfflineManager::listOfflineRegions, "listOfflineRegions"),
|
||||
METHOD(&OfflineManager::createOfflineRegion, "createOfflineRegion"));
|
||||
}
|
||||
|
||||
// OfflineManager::ListOfflineRegionsCallback //
|
||||
|
||||
void OfflineManager::ListOfflineRegionsCallback::onError(jni::JNIEnv& env,
|
||||
jni::Object<OfflineManager::ListOfflineRegionsCallback> callback,
|
||||
std::exception_ptr error) {
|
||||
static auto method = javaClass.GetMethod<void (jni::String)>(env, "onError");
|
||||
std::string message = mbgl::util::toString(error);
|
||||
callback.Call(env, method, jni::Make<jni::String>(env, message));
|
||||
}
|
||||
|
||||
void OfflineManager::ListOfflineRegionsCallback::onList(jni::JNIEnv& env,
|
||||
jni::Object<FileSource> jFileSource,
|
||||
jni::Object<OfflineManager::ListOfflineRegionsCallback> callback,
|
||||
mbgl::optional<std::vector<mbgl::OfflineRegion>> regions) {
|
||||
//Convert the regions to java peer objects
|
||||
std::size_t index = 0;
|
||||
auto jregions = jni::Array<jni::Object<OfflineRegion>>::New(env, regions->size(), OfflineRegion::javaClass);
|
||||
for (auto& region : *regions) {
|
||||
auto jregion = OfflineRegion::New(env, jFileSource, std::move(region));
|
||||
jregions.Set(env, index, jregion);
|
||||
jni::DeleteLocalRef(env, jregion);
|
||||
index++;
|
||||
}
|
||||
|
||||
// Trigger callback
|
||||
static auto method = javaClass.GetMethod<void (jni::Array<jni::Object<OfflineRegion>>)>(env, "onList");
|
||||
callback.Call(env, method, jregions);
|
||||
jni::DeleteLocalRef(env, jregions);
|
||||
}
|
||||
|
||||
jni::Class<OfflineManager::ListOfflineRegionsCallback> OfflineManager::ListOfflineRegionsCallback::javaClass;
|
||||
|
||||
void OfflineManager::ListOfflineRegionsCallback::registerNative(jni::JNIEnv& env) {
|
||||
javaClass = *jni::Class<OfflineManager::ListOfflineRegionsCallback>::Find(env).NewGlobalRef(env).release();
|
||||
}
|
||||
|
||||
// OfflineManager::CreateOfflineRegionCallback //
|
||||
|
||||
void OfflineManager::CreateOfflineRegionCallback::onError(jni::JNIEnv& env,
|
||||
jni::Object<OfflineManager::CreateOfflineRegionCallback> callback,
|
||||
std::exception_ptr error) {
|
||||
static auto method = javaClass.GetMethod<void (jni::String)>(env, "onError");
|
||||
std::string message = mbgl::util::toString(error);
|
||||
callback.Call(env, method, jni::Make<jni::String>(env, message));
|
||||
}
|
||||
|
||||
void OfflineManager::CreateOfflineRegionCallback::onCreate(jni::JNIEnv& env,
|
||||
jni::Object<FileSource> jFileSource,
|
||||
jni::Object<OfflineManager::CreateOfflineRegionCallback> callback,
|
||||
mbgl::optional<mbgl::OfflineRegion> region) {
|
||||
//Convert the region to java peer object
|
||||
auto jregion = OfflineRegion::New(env, jFileSource, std::move(*region));
|
||||
|
||||
// Trigger callback
|
||||
static auto method = javaClass.GetMethod<void (jni::Object<OfflineRegion>)>(env, "onCreate");
|
||||
callback.Call(env, method, jregion);
|
||||
jni::DeleteLocalRef(env, jregion);
|
||||
}
|
||||
|
||||
jni::Class<OfflineManager::CreateOfflineRegionCallback> OfflineManager::CreateOfflineRegionCallback::javaClass;
|
||||
|
||||
void OfflineManager::CreateOfflineRegionCallback::registerNative(jni::JNIEnv& env) {
|
||||
javaClass = *jni::Class<OfflineManager::CreateOfflineRegionCallback>::Find(env).NewGlobalRef(env).release();
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
75
platform/android/src/offline/offline_manager.hpp
Normal file
75
platform/android/src/offline/offline_manager.hpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <mbgl/storage/default_file_source.hpp>
|
||||
#include <mbgl/storage/offline.hpp>
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
#include "../file_source.hpp"
|
||||
#include "offline_region.hpp"
|
||||
#include "offline_region_definition.hpp"
|
||||
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class OfflineManager {
|
||||
public:
|
||||
|
||||
class ListOfflineRegionsCallback {
|
||||
public:
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/offline/OfflineManager$ListOfflineRegionsCallback";}
|
||||
|
||||
static void onError(jni::JNIEnv&, jni::Object<OfflineManager::ListOfflineRegionsCallback>, std::exception_ptr);
|
||||
|
||||
static void onList(jni::JNIEnv&,
|
||||
jni::Object<FileSource>,
|
||||
jni::Object<OfflineManager::ListOfflineRegionsCallback>,
|
||||
mbgl::optional<std::vector<mbgl::OfflineRegion>>);
|
||||
|
||||
static jni::Class<OfflineManager::ListOfflineRegionsCallback> javaClass;
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
};
|
||||
|
||||
class CreateOfflineRegionCallback {
|
||||
public:
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/offline/OfflineManager$CreateOfflineRegionCallback"; }
|
||||
|
||||
static void onError(jni::JNIEnv&, jni::Object<OfflineManager::CreateOfflineRegionCallback>, std::exception_ptr);
|
||||
|
||||
static void onCreate(jni::JNIEnv&,
|
||||
jni::Object<FileSource>,
|
||||
jni::Object<OfflineManager::CreateOfflineRegionCallback>,
|
||||
mbgl::optional<mbgl::OfflineRegion>);
|
||||
|
||||
static jni::Class<OfflineManager::CreateOfflineRegionCallback> javaClass;
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
};
|
||||
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/offline/OfflineManager"; };
|
||||
|
||||
static jni::Class<OfflineManager> javaClass;
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
|
||||
OfflineManager(jni::JNIEnv&, jni::Object<FileSource>);
|
||||
~OfflineManager();
|
||||
|
||||
void setOfflineMapboxTileCountLimit(jni::JNIEnv&, jni::jlong limit);
|
||||
|
||||
void listOfflineRegions(jni::JNIEnv&, jni::Object<FileSource>, jni::Object<ListOfflineRegionsCallback> callback);
|
||||
|
||||
void createOfflineRegion(jni::JNIEnv&,
|
||||
jni::Object<FileSource> jFileSource_,
|
||||
jni::Object<OfflineRegionDefinition> definition,
|
||||
jni::Array<jni::jbyte> metadata,
|
||||
jni::Object<OfflineManager::CreateOfflineRegionCallback> callback);
|
||||
|
||||
private:
|
||||
mbgl::DefaultFileSource& fileSource;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
308
platform/android/src/offline/offline_region.cpp
Normal file
308
platform/android/src/offline/offline_region.cpp
Normal file
@@ -0,0 +1,308 @@
|
||||
#include "offline_region.hpp"
|
||||
|
||||
#include <mbgl/util/logging.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
|
||||
#include "offline_region_definition.hpp"
|
||||
#include "offline_region_error.hpp"
|
||||
#include "offline_region_status.hpp"
|
||||
#include "../attach_env.hpp"
|
||||
#include "../jni/generic_global_ref_deleter.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
// OfflineRegion //
|
||||
|
||||
OfflineRegion::OfflineRegion(jni::JNIEnv& env, jni::jlong offlineRegionPtr, jni::Object<FileSource> jFileSource)
|
||||
: region(reinterpret_cast<mbgl::OfflineRegion *>(offlineRegionPtr)),
|
||||
fileSource(mbgl::android::FileSource::getDefaultFileSource(env, jFileSource)) {}
|
||||
|
||||
OfflineRegion::~OfflineRegion() {}
|
||||
|
||||
void OfflineRegion::setOfflineRegionObserver(jni::JNIEnv& env_, jni::Object<OfflineRegion::OfflineRegionObserver> callback) {
|
||||
|
||||
// Define the observer
|
||||
class Observer : public mbgl::OfflineRegionObserver {
|
||||
public:
|
||||
Observer(jni::UniqueObject<OfflineRegion::OfflineRegionObserver>&& callback_)
|
||||
//TODO add a generic deleter for jni::Object
|
||||
: callback(callback_.release()->Get()) {
|
||||
}
|
||||
|
||||
~Observer() override {
|
||||
android::UniqueEnv env = android::AttachEnv();
|
||||
env->DeleteGlobalRef(Unwrap(*callback));
|
||||
}
|
||||
|
||||
void statusChanged(mbgl::OfflineRegionStatus status) override {
|
||||
// Reattach, the callback comes from a different thread
|
||||
android::UniqueEnv env = android::AttachEnv();
|
||||
|
||||
// Status object
|
||||
auto jStatus = OfflineRegionStatus::New(*env, status);
|
||||
|
||||
// Call
|
||||
static auto method = OfflineRegion::OfflineRegionObserver::javaClass
|
||||
.GetMethod<void (jni::Object<OfflineRegionStatus>)>(*env, "onStatusChanged");
|
||||
callback.Call(*env, method, jStatus);
|
||||
|
||||
// Delete references
|
||||
jni::DeleteLocalRef(*env, jStatus);
|
||||
}
|
||||
|
||||
void responseError(mbgl::Response::Error error) override {
|
||||
// Reattach, the callback comes from a different thread
|
||||
android::UniqueEnv env = android::AttachEnv();
|
||||
|
||||
// Error object
|
||||
auto jError = OfflineRegionError::New(*env, error);
|
||||
|
||||
// Call
|
||||
static auto method = OfflineRegion::OfflineRegionObserver::javaClass
|
||||
.GetMethod<void (jni::Object<mbgl::android::OfflineRegionError>)>(*env, "onError");
|
||||
callback.Call(*env, method, jError);
|
||||
|
||||
// Delete references
|
||||
jni::DeleteLocalRef(*env, jError);
|
||||
}
|
||||
|
||||
void mapboxTileCountLimitExceeded(uint64_t limit) override {
|
||||
// Reattach, the callback comes from a different thread
|
||||
android::UniqueEnv env = android::AttachEnv();
|
||||
|
||||
// Send limit
|
||||
static auto method = OfflineRegion::OfflineRegionObserver::javaClass
|
||||
.GetMethod<void (jni::jlong)>(*env, "mapboxTileCountLimitExceeded");
|
||||
callback.Call(*env, method, jlong(limit));
|
||||
}
|
||||
|
||||
jni::Object<OfflineRegion::OfflineRegionObserver> callback;
|
||||
};
|
||||
|
||||
// Set the observer
|
||||
fileSource.setOfflineRegionObserver(*region, std::make_unique<Observer>(callback.NewGlobalRef(env_)));
|
||||
}
|
||||
|
||||
void OfflineRegion::setOfflineRegionDownloadState(jni::JNIEnv&, jni::jint jState) {
|
||||
// State
|
||||
mbgl::OfflineRegionDownloadState state;
|
||||
switch (jState) {
|
||||
case 0:
|
||||
state = mbgl::OfflineRegionDownloadState::Inactive;
|
||||
break;
|
||||
case 1:
|
||||
state = mbgl::OfflineRegionDownloadState::Active;
|
||||
break;
|
||||
default:
|
||||
mbgl::Log::Error(mbgl::Event::JNI, "State can only be 0 (inactive) or 1 (active).");
|
||||
return;
|
||||
}
|
||||
|
||||
fileSource.setOfflineRegionDownloadState(*region, state);
|
||||
}
|
||||
|
||||
void OfflineRegion::getOfflineRegionStatus(jni::JNIEnv& env_, jni::Object<OfflineRegionStatusCallback> callback_) {
|
||||
|
||||
fileSource.getOfflineRegionStatus(*region, [
|
||||
//Ensure the object is not gc'd in the meanwhile
|
||||
callback = std::shared_ptr<jni::jobject>(callback_.NewGlobalRef(env_).release()->Get(), GenericGlobalRefDeleter())
|
||||
](std::exception_ptr error, mbgl::optional<mbgl::OfflineRegionStatus> status) mutable {
|
||||
// Reattach, the callback comes from a different thread
|
||||
android::UniqueEnv env = android::AttachEnv();
|
||||
|
||||
if (error) {
|
||||
OfflineRegionStatusCallback::onError(*env, jni::Object<OfflineRegionStatusCallback>(*callback), error);
|
||||
} else if (status) {
|
||||
OfflineRegionStatusCallback::onStatus(*env, jni::Object<OfflineRegionStatusCallback>(*callback), std::move(status));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void OfflineRegion::deleteOfflineRegion(jni::JNIEnv& env_, jni::Object<OfflineRegionDeleteCallback> callback_) {
|
||||
// Delete
|
||||
fileSource.deleteOfflineRegion(std::move(*region), [
|
||||
//Ensure the object is not gc'd in the meanwhile
|
||||
callback = std::shared_ptr<jni::jobject>(callback_.NewGlobalRef(env_).release()->Get(), GenericGlobalRefDeleter())
|
||||
](std::exception_ptr error) mutable {
|
||||
// Reattach, the callback comes from a different thread
|
||||
android::UniqueEnv env = android::AttachEnv();
|
||||
|
||||
if (error) {
|
||||
OfflineRegionDeleteCallback::onError(*env, jni::Object<OfflineRegionDeleteCallback>(*callback), error);
|
||||
} else {
|
||||
OfflineRegionDeleteCallback::onDelete(*env, jni::Object<OfflineRegionDeleteCallback>(*callback));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void OfflineRegion::updateOfflineRegionMetadata(jni::JNIEnv& env_, jni::Array<jni::jbyte> jMetadata, jni::Object<OfflineRegionUpdateMetadataCallback> callback_) {
|
||||
|
||||
// Convert
|
||||
auto metadata = OfflineRegion::metadata(env_, jMetadata);
|
||||
|
||||
fileSource.updateOfflineMetadata(region->getID(), metadata, [
|
||||
//Ensure the object is not gc'd in the meanwhile
|
||||
callback = std::shared_ptr<jni::jobject>(callback_.NewGlobalRef(env_).release()->Get(), GenericGlobalRefDeleter())
|
||||
](std::exception_ptr error, mbgl::optional<mbgl::OfflineRegionMetadata> data) mutable {
|
||||
// Reattach, the callback comes from a different thread
|
||||
android::UniqueEnv env = android::AttachEnv();
|
||||
|
||||
if (error) {
|
||||
OfflineRegionUpdateMetadataCallback::onError(*env, jni::Object<OfflineRegionUpdateMetadataCallback>(*callback), error);
|
||||
} else if (data) {
|
||||
OfflineRegionUpdateMetadataCallback::onUpdate(*env, jni::Object<OfflineRegionUpdateMetadataCallback>(*callback), std::move(data));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
jni::Object<OfflineRegion> OfflineRegion::New(jni::JNIEnv& env, jni::Object<FileSource> jFileSource, mbgl::OfflineRegion region) {
|
||||
|
||||
// Definition
|
||||
auto definition = jni::Object<OfflineRegionDefinition>(*OfflineTilePyramidRegionDefinition::New(env, region.getDefinition()));
|
||||
|
||||
// Metadata
|
||||
auto metadata = OfflineRegion::metadata(env, region.getMetadata());
|
||||
|
||||
// Create region java object
|
||||
static auto constructor = OfflineRegion::javaClass.GetConstructor<jni::jlong, jni::Object<FileSource>, jni::jlong, jni::Object<OfflineRegionDefinition>, jni::Array<jni::jbyte>>(env);
|
||||
auto jregion = OfflineRegion::javaClass.New(env, constructor,
|
||||
reinterpret_cast<jni::jlong>(new mbgl::OfflineRegion(std::move(region))), //Copy a region to the heap
|
||||
jFileSource, jni::jlong(region.getID()), definition, metadata);
|
||||
|
||||
//Delete references
|
||||
jni::DeleteLocalRef(env, definition);
|
||||
jni::DeleteLocalRef(env, metadata);
|
||||
|
||||
return jregion;
|
||||
}
|
||||
|
||||
jni::Array<jni::jbyte> OfflineRegion::metadata(jni::JNIEnv& env, mbgl::OfflineRegionMetadata metadata_) {
|
||||
std::vector<jni::jbyte> convertedMetadata(metadata_.begin(), metadata_.end());
|
||||
std::size_t length = static_cast<std::size_t>(convertedMetadata.size());
|
||||
auto metadata = jni::Array<jni::jbyte>::New(env, length);
|
||||
metadata.SetRegion<std::vector<jni::jbyte>>(env, 0, convertedMetadata);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
mbgl::OfflineRegionMetadata OfflineRegion::metadata(jni::JNIEnv& env, jni::Array<jni::jbyte> metadata_) {
|
||||
std::size_t length = metadata_.Length(env);
|
||||
auto metadata_tmp = std::vector<jni::jbyte>();
|
||||
metadata_tmp.resize(length);
|
||||
metadata_.GetRegion<std::vector<jni::jbyte>>(env, 0, metadata_tmp);
|
||||
auto metadata = std::vector<uint8_t>(metadata_tmp.begin(), metadata_tmp.end());
|
||||
return metadata;
|
||||
}
|
||||
|
||||
jni::Class<OfflineRegion> OfflineRegion::javaClass;
|
||||
|
||||
void OfflineRegion::registerNative(jni::JNIEnv& env) {
|
||||
OfflineRegion::OfflineRegionObserver::registerNative(env);
|
||||
OfflineRegion::OfflineRegionStatusCallback::registerNative(env);
|
||||
OfflineRegion::OfflineRegionDeleteCallback::registerNative(env);
|
||||
OfflineRegion::OfflineRegionUpdateMetadataCallback::registerNative(env);
|
||||
|
||||
javaClass = *jni::Class<OfflineRegion>::Find(env).NewGlobalRef(env).release();
|
||||
|
||||
#define METHOD(MethodPtr, name) jni::MakeNativePeerMethod<decltype(MethodPtr), (MethodPtr)>(name)
|
||||
|
||||
jni::RegisterNativePeer<OfflineRegion>( env, javaClass, "nativePtr",
|
||||
std::make_unique<OfflineRegion, JNIEnv&, jni::jlong, jni::Object<FileSource>>,
|
||||
"initialize",
|
||||
"finalize",
|
||||
METHOD(&OfflineRegion::setOfflineRegionObserver, "setOfflineRegionObserver"),
|
||||
METHOD(&OfflineRegion::setOfflineRegionDownloadState, "setOfflineRegionDownloadState"),
|
||||
METHOD(&OfflineRegion::getOfflineRegionStatus, "getOfflineRegionStatus"),
|
||||
METHOD(&OfflineRegion::deleteOfflineRegion, "deleteOfflineRegion"),
|
||||
METHOD(&OfflineRegion::updateOfflineRegionMetadata, "updateOfflineRegionMetadata")
|
||||
);
|
||||
}
|
||||
|
||||
// OfflineRegionObserver //
|
||||
|
||||
jni::Class<OfflineRegion::OfflineRegionObserver> OfflineRegion::OfflineRegionObserver::javaClass;
|
||||
|
||||
void OfflineRegion::OfflineRegionObserver::registerNative(jni::JNIEnv& env) {
|
||||
javaClass = *jni::Class<OfflineRegion::OfflineRegionObserver>::Find(env).NewGlobalRef(env).release();
|
||||
}
|
||||
|
||||
// OfflineRegionStatusCallback //
|
||||
|
||||
jni::Class<OfflineRegion::OfflineRegionStatusCallback> OfflineRegion::OfflineRegionStatusCallback::javaClass;
|
||||
|
||||
void OfflineRegion::OfflineRegionStatusCallback::registerNative(jni::JNIEnv& env) {
|
||||
javaClass = *jni::Class<OfflineRegionStatusCallback>::Find(env).NewGlobalRef(env).release();
|
||||
}
|
||||
|
||||
void OfflineRegion::OfflineRegionStatusCallback::onError(jni::JNIEnv& env,
|
||||
jni::Object<OfflineRegion::OfflineRegionStatusCallback> callback,
|
||||
std::exception_ptr error) {
|
||||
static auto method = javaClass.GetMethod<void (jni::String)>(env, "onError");
|
||||
std::string message = mbgl::util::toString(error);
|
||||
callback.Call(env, method, jni::Make<jni::String>(env, message));
|
||||
}
|
||||
|
||||
void OfflineRegion::OfflineRegionStatusCallback::onStatus(jni::JNIEnv& env,
|
||||
jni::Object<OfflineRegion::OfflineRegionStatusCallback> callback,
|
||||
mbgl::optional<mbgl::OfflineRegionStatus> status) {
|
||||
//Convert to java peer object
|
||||
auto jStatus = OfflineRegionStatus::New(env, std::move(*status));
|
||||
|
||||
// Trigger callback
|
||||
static auto method = javaClass.GetMethod<void (jni::Object<OfflineRegionStatus>)>(env, "onStatus");
|
||||
callback.Call(env, method, jStatus);
|
||||
jni::DeleteLocalRef(env, jStatus);
|
||||
}
|
||||
|
||||
// OfflineRegionDeleteCallback //
|
||||
|
||||
jni::Class<OfflineRegion::OfflineRegionDeleteCallback> OfflineRegion::OfflineRegionDeleteCallback::javaClass;
|
||||
|
||||
void OfflineRegion::OfflineRegionDeleteCallback::registerNative(jni::JNIEnv& env) {
|
||||
javaClass = *jni::Class<OfflineRegionDeleteCallback>::Find(env).NewGlobalRef(env).release();
|
||||
}
|
||||
|
||||
void OfflineRegion::OfflineRegionDeleteCallback::onError(jni::JNIEnv& env,
|
||||
jni::Object<OfflineRegion::OfflineRegionDeleteCallback> callback,
|
||||
std::exception_ptr error) {
|
||||
static auto method = javaClass.GetMethod<void (jni::String)>(env, "onError");
|
||||
std::string message = mbgl::util::toString(error);
|
||||
callback.Call(env, method, jni::Make<jni::String>(env, message));
|
||||
}
|
||||
|
||||
void OfflineRegion::OfflineRegionDeleteCallback::onDelete(jni::JNIEnv& env, jni::Object<OfflineRegion::OfflineRegionDeleteCallback> callback) {
|
||||
// Trigger callback
|
||||
static auto method = javaClass.GetMethod<void ()>(env, "onDelete");
|
||||
callback.Call(env, method);
|
||||
}
|
||||
|
||||
// OfflineRegionUpdateMetadataCallback //
|
||||
|
||||
jni::Class<OfflineRegion::OfflineRegionUpdateMetadataCallback> OfflineRegion::OfflineRegionUpdateMetadataCallback::javaClass;
|
||||
|
||||
void OfflineRegion::OfflineRegionUpdateMetadataCallback::registerNative(jni::JNIEnv& env) {
|
||||
javaClass = *jni::Class<OfflineRegionUpdateMetadataCallback>::Find(env).NewGlobalRef(env).release();
|
||||
}
|
||||
|
||||
void OfflineRegion::OfflineRegionUpdateMetadataCallback::onError(jni::JNIEnv& env,
|
||||
jni::Object<OfflineRegion::OfflineRegionUpdateMetadataCallback> callback,
|
||||
std::exception_ptr error) {
|
||||
static auto method = javaClass.GetMethod<void (jni::String)>(env, "onError");
|
||||
std::string message = mbgl::util::toString(error);
|
||||
callback.Call(env, method, jni::Make<jni::String>(env, message));
|
||||
}
|
||||
|
||||
void OfflineRegion::OfflineRegionUpdateMetadataCallback::onUpdate(jni::JNIEnv& env,
|
||||
jni::Object<OfflineRegion::OfflineRegionUpdateMetadataCallback> callback,
|
||||
mbgl::optional<mbgl::OfflineRegionMetadata> metadata) {
|
||||
//Convert to java peer object
|
||||
auto jMetadata = OfflineRegion::metadata(env, std::move(*metadata));
|
||||
|
||||
// Trigger callback
|
||||
static auto method = javaClass.GetMethod<void (jni::Array<jni::jbyte>)>(env, "onUpdate");
|
||||
callback.Call(env, method, jMetadata);
|
||||
jni::DeleteLocalRef(env, jMetadata);
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
99
platform/android/src/offline/offline_region.hpp
Normal file
99
platform/android/src/offline/offline_region.hpp
Normal file
@@ -0,0 +1,99 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/storage/offline.hpp>
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
#include "../file_source.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class OfflineRegion {
|
||||
public:
|
||||
class OfflineRegionObserver {
|
||||
public:
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionObserver"; };
|
||||
|
||||
static jni::Class<OfflineRegionObserver> javaClass;
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
};
|
||||
|
||||
class OfflineRegionStatusCallback {
|
||||
public:
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionStatusCallback"; };
|
||||
|
||||
static void onError(jni::JNIEnv&, jni::Object<OfflineRegionStatusCallback>, std::exception_ptr);
|
||||
|
||||
static void onStatus(jni::JNIEnv&,
|
||||
jni::Object<OfflineRegionStatusCallback>,
|
||||
mbgl::optional<mbgl::OfflineRegionStatus>);
|
||||
|
||||
static jni::Class<OfflineRegionStatusCallback> javaClass;
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
};
|
||||
|
||||
class OfflineRegionDeleteCallback {
|
||||
public:
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionDeleteCallback"; };
|
||||
|
||||
static void onError(jni::JNIEnv&, jni::Object<OfflineRegionDeleteCallback>, std::exception_ptr);
|
||||
|
||||
static void onDelete(jni::JNIEnv&, jni::Object<OfflineRegionDeleteCallback>);
|
||||
|
||||
static jni::Class<OfflineRegionDeleteCallback> javaClass;
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
};
|
||||
|
||||
class OfflineRegionUpdateMetadataCallback {
|
||||
public:
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/offline/OfflineRegion$OfflineRegionUpdateMetadataCallback"; };
|
||||
|
||||
static void onError(jni::JNIEnv&, jni::Object<OfflineRegionUpdateMetadataCallback>, std::exception_ptr);
|
||||
|
||||
static void onUpdate(jni::JNIEnv&,
|
||||
jni::Object<OfflineRegionUpdateMetadataCallback>,
|
||||
mbgl::optional<mbgl::OfflineRegionMetadata>);
|
||||
|
||||
static jni::Class<OfflineRegionUpdateMetadataCallback> javaClass;
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
};
|
||||
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/offline/OfflineRegion"; };
|
||||
|
||||
OfflineRegion(jni::JNIEnv&, jni::jlong, jni::Object<FileSource>);
|
||||
|
||||
~OfflineRegion();
|
||||
|
||||
void setOfflineRegionObserver(jni::JNIEnv&, jni::Object<OfflineRegion::OfflineRegionObserver>);
|
||||
|
||||
void setOfflineRegionDownloadState(jni::JNIEnv&, jni::jint);
|
||||
|
||||
void getOfflineRegionStatus(jni::JNIEnv&, jni::Object<OfflineRegion::OfflineRegionStatusCallback>);
|
||||
|
||||
void deleteOfflineRegion(jni::JNIEnv&, jni::Object<OfflineRegionDeleteCallback>);
|
||||
|
||||
void updateOfflineRegionMetadata(jni::JNIEnv&, jni::Array<jni::jbyte>, jni::Object<OfflineRegionUpdateMetadataCallback>);
|
||||
|
||||
static jni::Object<OfflineRegion> New(jni::JNIEnv&, jni::Object<FileSource>, mbgl::OfflineRegion);
|
||||
|
||||
static jni::Array<jni::jbyte> metadata(jni::JNIEnv&, mbgl::OfflineRegionMetadata);
|
||||
|
||||
static mbgl::OfflineRegionMetadata metadata(jni::JNIEnv&, jni::Array<jni::jbyte>);
|
||||
|
||||
static jni::Class<OfflineRegion> javaClass;
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
|
||||
private:
|
||||
std::unique_ptr<mbgl::OfflineRegion> region;
|
||||
mbgl::DefaultFileSource& fileSource;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
69
platform/android/src/offline/offline_region_definition.cpp
Normal file
69
platform/android/src/offline/offline_region_definition.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include "offline_region_definition.hpp"
|
||||
|
||||
#include "../geometry/lat_lng_bounds.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
// OfflineRegionDefinition //
|
||||
|
||||
jni::Class<OfflineRegionDefinition> OfflineRegionDefinition::javaClass;
|
||||
|
||||
void OfflineRegionDefinition::registerNative(jni::JNIEnv& env) {
|
||||
javaClass = *jni::Class<OfflineRegionDefinition>::Find(env).NewGlobalRef(env).release();
|
||||
}
|
||||
|
||||
// OfflineTilePyramidRegionDefinition //
|
||||
|
||||
jni::Object<OfflineTilePyramidRegionDefinition> OfflineTilePyramidRegionDefinition::New(jni::JNIEnv& env, mbgl::OfflineTilePyramidRegionDefinition definition) {
|
||||
|
||||
//Convert objects
|
||||
auto styleURL = jni::Make<jni::String>(env, definition.styleURL);
|
||||
auto bounds = LatLngBounds::New(env, definition.bounds);
|
||||
|
||||
static auto constructor = javaClass.GetConstructor<jni::String, jni::Object<LatLngBounds>, jni::jdouble, jni::jdouble, jni::jfloat>(env);
|
||||
auto jdefinition = javaClass.New(env, constructor, styleURL, bounds, definition.minZoom, definition.maxZoom, definition.pixelRatio);
|
||||
|
||||
//Delete References
|
||||
jni::DeleteLocalRef(env, styleURL);
|
||||
jni::DeleteLocalRef(env, bounds);
|
||||
|
||||
return jdefinition;
|
||||
}
|
||||
|
||||
mbgl::OfflineTilePyramidRegionDefinition OfflineTilePyramidRegionDefinition::getDefinition(jni::JNIEnv& env, jni::Object<OfflineTilePyramidRegionDefinition> jDefinition) {
|
||||
// Field references
|
||||
static auto styleURLF = javaClass.GetField<jni::String>(env, "styleURL");
|
||||
static auto boundsF = javaClass.GetField<jni::Object<LatLngBounds>>(env, "bounds");
|
||||
static auto minZoomF = javaClass.GetField<jni::jdouble>(env, "minZoom");
|
||||
static auto maxZoomF = javaClass.GetField<jni::jdouble>(env, "maxZoom");
|
||||
static auto pixelRatioF = javaClass.GetField<jni::jfloat>(env, "pixelRatio");
|
||||
|
||||
// Get objects
|
||||
auto jStyleURL = jDefinition.Get(env, styleURLF);
|
||||
auto jBounds = jDefinition.Get(env, boundsF);
|
||||
|
||||
// Create definition
|
||||
mbgl::OfflineTilePyramidRegionDefinition definition(
|
||||
jni::Make<std::string>(env, jStyleURL),
|
||||
LatLngBounds::getLatLngBounds(env, jBounds),
|
||||
jDefinition.Get(env, minZoomF),
|
||||
jDefinition.Get(env, maxZoomF),
|
||||
jDefinition.Get(env, pixelRatioF)
|
||||
);
|
||||
|
||||
// Delete references
|
||||
jni::DeleteLocalRef(env, jStyleURL);
|
||||
jni::DeleteLocalRef(env, jBounds);
|
||||
|
||||
return definition;
|
||||
}
|
||||
|
||||
jni::Class<OfflineTilePyramidRegionDefinition> OfflineTilePyramidRegionDefinition::javaClass;
|
||||
|
||||
void OfflineTilePyramidRegionDefinition::registerNative(jni::JNIEnv& env) {
|
||||
javaClass = *jni::Class<OfflineTilePyramidRegionDefinition>::Find(env).NewGlobalRef(env).release();
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
34
platform/android/src/offline/offline_region_definition.hpp
Normal file
34
platform/android/src/offline/offline_region_definition.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/storage/offline.hpp>
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class OfflineRegionDefinition {
|
||||
public:
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/offline/OfflineRegionDefinition"; };
|
||||
|
||||
static jni::Class<OfflineRegionDefinition> javaClass;
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
|
||||
};
|
||||
|
||||
class OfflineTilePyramidRegionDefinition: public OfflineRegionDefinition {
|
||||
public:
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/offline/OfflineTilePyramidRegionDefinition"; };
|
||||
|
||||
static jni::Object<OfflineTilePyramidRegionDefinition> New(jni::JNIEnv&, mbgl::OfflineTilePyramidRegionDefinition);
|
||||
|
||||
static mbgl::OfflineTilePyramidRegionDefinition getDefinition(jni::JNIEnv&, jni::Object<OfflineTilePyramidRegionDefinition>);
|
||||
|
||||
static jni::Class<OfflineTilePyramidRegionDefinition> javaClass;
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
53
platform/android/src/offline/offline_region_error.cpp
Normal file
53
platform/android/src/offline/offline_region_error.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#include "offline_region_error.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
jni::Object<OfflineRegionError> OfflineRegionError::New(jni::JNIEnv& env, mbgl::Response::Error error) {
|
||||
|
||||
// Handle the value of reason independently of the underlying int value
|
||||
std::string reason;
|
||||
switch(error.reason) {
|
||||
case mbgl::Response::Error::Reason::Success:
|
||||
reason = "REASON_SUCCESS";
|
||||
break;
|
||||
case mbgl::Response::Error::Reason::NotFound:
|
||||
reason = "REASON_NOT_FOUND";
|
||||
break;
|
||||
case mbgl::Response::Error::Reason::Server:
|
||||
reason = "REASON_SERVER";
|
||||
break;
|
||||
case mbgl::Response::Error::Reason::Connection:
|
||||
reason = "REASON_CONNECTION";
|
||||
break;
|
||||
case mbgl::Response::Error::Reason::RateLimit:
|
||||
reason = "REASON_RATE_LIMIT";
|
||||
break;
|
||||
case mbgl::Response::Error::Reason::Other:
|
||||
reason = "REASON_OTHER";
|
||||
break;
|
||||
}
|
||||
|
||||
// Convert
|
||||
auto jReason = jni::Make<jni::String>(env, reason);
|
||||
auto jMessage = jni::Make<jni::String>(env, error.message);
|
||||
|
||||
// Create java object
|
||||
static auto constructor = javaClass.GetConstructor<jni::String, jni::String>(env);
|
||||
auto jError = javaClass.New(env, constructor, jReason, jMessage);
|
||||
|
||||
// Delete references
|
||||
jni::DeleteLocalRef(env, jReason);
|
||||
jni::DeleteLocalRef(env, jMessage);
|
||||
|
||||
return jError;
|
||||
}
|
||||
|
||||
jni::Class<OfflineRegionError> OfflineRegionError::javaClass;
|
||||
|
||||
void OfflineRegionError::registerNative(jni::JNIEnv& env) {
|
||||
javaClass = *jni::Class<OfflineRegionError>::Find(env).NewGlobalRef(env).release();
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
21
platform/android/src/offline/offline_region_error.hpp
Normal file
21
platform/android/src/offline/offline_region_error.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/storage/offline.hpp>
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class OfflineRegionError {
|
||||
public:
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/offline/OfflineRegionError"; };
|
||||
|
||||
static jni::Object<OfflineRegionError> New(jni::JNIEnv&, mbgl::Response::Error);
|
||||
|
||||
static jni::Class<OfflineRegionError> javaClass;
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
39
platform/android/src/offline/offline_region_status.cpp
Normal file
39
platform/android/src/offline/offline_region_status.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include "offline_region_status.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
jni::Object<OfflineRegionStatus> OfflineRegionStatus::New(jni::JNIEnv& env, mbgl::OfflineRegionStatus status) {
|
||||
|
||||
// Convert to jint
|
||||
jint downloadState;
|
||||
switch(status.downloadState) {
|
||||
case mbgl::OfflineRegionDownloadState::Inactive:
|
||||
downloadState = 0;
|
||||
break;
|
||||
case mbgl::OfflineRegionDownloadState::Active:
|
||||
downloadState = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// Create java object
|
||||
static auto constructor = javaClass.GetConstructor<jint, jlong, jlong, jlong, jlong, jlong, jboolean>(env);
|
||||
return javaClass.New(env, constructor,
|
||||
downloadState,
|
||||
jlong(status.completedResourceCount),
|
||||
jlong(status.completedResourceSize),
|
||||
jlong(status.completedTileCount),
|
||||
jlong(status.completedTileSize),
|
||||
jlong(status.requiredResourceCount),
|
||||
jboolean(status.requiredResourceCountIsPrecise)
|
||||
);
|
||||
}
|
||||
|
||||
jni::Class<OfflineRegionStatus> OfflineRegionStatus::javaClass;
|
||||
|
||||
void OfflineRegionStatus::registerNative(jni::JNIEnv& env) {
|
||||
javaClass = *jni::Class<OfflineRegionStatus>::Find(env).NewGlobalRef(env).release();
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
21
platform/android/src/offline/offline_region_status.hpp
Normal file
21
platform/android/src/offline/offline_region_status.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/storage/offline.hpp>
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class OfflineRegionStatus {
|
||||
public:
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/offline/OfflineRegionStatus"; };
|
||||
|
||||
static jni::Object<OfflineRegionStatus> New(jni::JNIEnv&, mbgl::OfflineRegionStatus status);
|
||||
|
||||
static jni::Class<OfflineRegionStatus> javaClass;
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include <mbgl/util/logging.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <mbgl/util/feature.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
Reference in New Issue
Block a user