summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2017-01-16 21:17:04 +0100
committerKonstantin Käfer <mail@kkaefer.com>2017-01-17 11:32:14 +0100
commitea273d4e75f51a6cb7a6fc7573c7722e34e730f1 (patch)
treef57a4acd50f77444f74db821b248e88f150a6b9f
parent7983e3a67c557a0fcf118984404ea1756416b521 (diff)
downloadqtlocation-mapboxgl-ea273d4e75f51a6cb7a6fc7573c7722e34e730f1.tar.gz
[android] expose DefaultFileSource via jni.hpp
Instantiate only one DefaultFileSource in the global Mapbox singleton, instead of one per Map object
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java108
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java4
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java8
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java18
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java29
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java41
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java67
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/DefaultFileSource.java91
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml2
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml1
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxApplication.java9
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/MapboxApplication.java11
-rw-r--r--platform/android/config.cmake4
-rwxr-xr-xplatform/android/src/jni.cpp40
-rw-r--r--platform/android/src/jni.hpp3
-rwxr-xr-xplatform/android/src/native_map_view.cpp19
-rwxr-xr-xplatform/android/src/native_map_view.hpp13
-rw-r--r--platform/android/src/storage/default_file_source_peer.cpp54
-rw-r--r--platform/android/src/storage/default_file_source_peer.hpp40
19 files changed, 340 insertions, 222 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java
index 9d20e968c8..d093a86ff0 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java
@@ -1,6 +1,9 @@
package com.mapbox.mapboxsdk;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Environment;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.annotation.NonNull;
@@ -10,13 +13,20 @@ import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.exceptions.InvalidAccessTokenException;
import com.mapbox.mapboxsdk.net.ConnectivityReceiver;
import com.mapbox.mapboxsdk.telemetry.MapboxEventManager;
+import com.mapbox.mapboxsdk.storage.DefaultFileSource;
-public final class Mapbox {
+import java.io.File;
+
+import timber.log.Timber;
+public final class Mapbox {
private static Mapbox INSTANCE;
private Context context;
- private String accessToken;
private Boolean connected;
+ private DefaultFileSource fileSource;
+
+ // Default database name
+ private static final String DATABASE_NAME = "mbgl-offline.db";
/**
* Get an instance of Mapbox.
@@ -28,29 +38,27 @@ public final class Mapbox {
* @param accessToken Mapbox access token
* @return the single instance of Mapbox
*/
- public static synchronized Mapbox getInstance(@NonNull Context context, @NonNull String accessToken) {
+ public static synchronized Mapbox getInstance(@NonNull Context context,
+ @NonNull String accessToken, String apiBaseURL) {
if (INSTANCE == null) {
+ validateAccessToken(accessToken);
Context appContext = context.getApplicationContext();
- INSTANCE = new Mapbox(appContext, accessToken);
+ INSTANCE = new Mapbox(appContext, accessToken, apiBaseURL);
MapboxEventManager.getMapboxEventManager().initialize(appContext, accessToken);
ConnectivityReceiver.instance(appContext);
}
return INSTANCE;
}
- private Mapbox(@NonNull Context context, @NonNull String accessToken) {
+ private Mapbox(@NonNull Context context, @NonNull String accessToken, String apiBaseURL) {
this.context = context;
- this.accessToken = accessToken;
- }
- /**
- * Access Token for this application.
- *
- * @return Mapbox Access Token
- */
- public static String getAccessToken() {
- validateAccessToken();
- return INSTANCE.accessToken;
+ String databasePath = getDatabasePath(context) + File.separator + DATABASE_NAME;
+ this.fileSource = new DefaultFileSource(databasePath, context.getPackageCodePath());
+ this.fileSource.setAccessToken(accessToken);
+ if (apiBaseURL != null && !TextUtils.isEmpty(apiBaseURL)) {
+ this.fileSource.setAPIBaseURL(apiBaseURL);
+ }
}
/**
@@ -58,8 +66,7 @@ public final class Mapbox {
*
* @throws InvalidAccessTokenException exception thrown when not using a valid accessToken
*/
- private static void validateAccessToken() throws InvalidAccessTokenException {
- String accessToken = INSTANCE.accessToken;
+ private static void validateAccessToken(@NonNull String accessToken) throws InvalidAccessTokenException {
if (TextUtils.isEmpty(accessToken) || (!accessToken.toLowerCase(MapboxConstants.MAPBOX_LOCALE).startsWith("pk.")
&& !accessToken.toLowerCase(MapboxConstants.MAPBOX_LOCALE).startsWith("sk."))) {
throw new InvalidAccessTokenException();
@@ -74,6 +81,13 @@ public final class Mapbox {
}
/**
+ * Default file source
+ */
+ public static DefaultFileSource getDefaultFileSource() {
+ return INSTANCE.fileSource;
+ }
+
+ /**
* Manually sets the connectivity state of the app. This is useful for apps that control their
* own connectivity state and want to bypass any checks to the ConnectivityManager.
*
@@ -101,4 +115,62 @@ public final class Mapbox {
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return (activeNetwork != null && activeNetwork.isConnected());
}
-} \ No newline at end of file
+
+ /**
+ * Checks if external storage is available to at least read. In order for this to work, make
+ * sure you include &lt;uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /&gt;
+ * (or WRITE_EXTERNAL_STORAGE) for API level &lt; 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;
+ }
+
+ 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;
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java
index 2c6251638a..a179dc1f46 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java
@@ -16,6 +16,7 @@ import java.net.NoRouteToHostException;
import java.net.ProtocolException;
import java.net.SocketException;
import java.net.UnknownHostException;
+import java.net.MalformedURLException;
import java.util.concurrent.locks.ReentrantLock;
import javax.net.ssl.SSLException;
@@ -62,6 +63,9 @@ class HTTPRequest implements Callback {
}
HttpUrl httpUrl = HttpUrl.parse(resourceUrl);
+ if (httpUrl == null) {
+ throw new MalformedURLException("Could not load invalid URL: " + resourceUrl);
+ }
final String host = httpUrl.host().toLowerCase(MapboxConstants.MAPBOX_LOCALE);
if (host.equals("mapbox.com") || host.endsWith(".mapbox.com") || host.equals("mapbox.cn")
|| host.endsWith(".mapbox.cn")) {
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
index 3cb074d209..e3f2124d9f 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
@@ -21,7 +21,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;
@@ -199,8 +198,6 @@ public class MapView extends FrameLayout {
*/
@UiThread
public void onCreate(@Nullable Bundle savedInstanceState) {
- nativeMapView.setAccessToken(Mapbox.getAccessToken());
-
if (savedInstanceState == null) {
MapboxEvent.trackMapLoadEvent();
} else if (savedInstanceState.getBoolean(MapboxConstants.STATE_HAS_SAVED_STATE)) {
@@ -405,11 +402,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);
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
index f460a77229..30abee0d2c 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
@@ -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;
@@ -93,7 +92,6 @@ public final class MapboxMap {
// Map configuration
setDebugActive(options.getDebugActive());
- setApiBaseUrl(options);
setStyleUrl(options);
}
@@ -759,17 +757,6 @@ public final class MapboxMap {
}
//
- // API endpoint config
- //
-
- private void setApiBaseUrl(@NonNull MapboxMapOptions options) {
- String apiBaseUrl = options.getApiBaseUrl();
- if (!TextUtils.isEmpty(apiBaseUrl)) {
- nativeMapView.setApiBaseUrl(apiBaseUrl);
- }
- }
-
- //
// Styling
//
@@ -837,10 +824,7 @@ 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);
setStyleUrl(style);
}
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java
index 518ef47329..af99e6657e 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java
@@ -77,8 +77,6 @@ public class MapboxMapOptions implements Parcelable {
private int myLocationAccuracyTintColor;
private int myLocationAccuracyAlpha;
- private String apiBaseUrl;
-
@Deprecated
private boolean textureMode;
@@ -141,7 +139,6 @@ public class MapboxMapOptions implements Parcelable {
myLocationAccuracyTintColor = in.readInt();
style = in.readString();
- apiBaseUrl = in.readString();
textureMode = in.readByte() != 0;
}
@@ -172,7 +169,6 @@ public class MapboxMapOptions implements Parcelable {
try {
mapboxMapOptions.camera(new CameraPosition.Builder(typedArray).build());
mapboxMapOptions.styleUrl(typedArray.getString(R.styleable.mapbox_MapView_mapbox_styleUrl));
- mapboxMapOptions.apiBaseUrl(typedArray.getString(R.styleable.mapbox_MapView_mapbox_apiBaseUrl));
mapboxMapOptions.zoomGesturesEnabled(
typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_uiZoomGestures, true));
@@ -284,17 +280,6 @@ public class MapboxMapOptions implements Parcelable {
}
/**
- * Specifies the URL used for API endpoint.
- *
- * @param apiBaseUrl The base of our API endpoint
- * @return This
- */
- public MapboxMapOptions apiBaseUrl(String apiBaseUrl) {
- this.apiBaseUrl = apiBaseUrl;
- return this;
- }
-
- /**
* Specifies a the initial camera position for the map view.
*
* @param cameraPosition Inital camera position
@@ -656,15 +641,6 @@ public class MapboxMapOptions implements Parcelable {
}
/**
- * Get the current configured API endpoint base URL.
- *
- * @return Base URL to be used API endpoint.
- */
- public String getApiBaseUrl() {
- return apiBaseUrl;
- }
-
- /**
* Get the current configured initial camera position for a map view.
*
* @return CameraPosition to be initially used.
@@ -1003,7 +979,6 @@ public class MapboxMapOptions implements Parcelable {
dest.writeInt(myLocationAccuracyTintColor);
dest.writeString(style);
- dest.writeString(apiBaseUrl);
dest.writeByte((byte) (textureMode ? 1 : 0));
}
@@ -1114,9 +1089,6 @@ public class MapboxMapOptions implements Parcelable {
if (style != null ? !style.equals(options.style) : options.style != null) {
return false;
}
- if (apiBaseUrl != null ? !apiBaseUrl.equals(options.apiBaseUrl) : options.apiBaseUrl != null) {
- return false;
- }
return false;
}
@@ -1156,7 +1128,6 @@ public class MapboxMapOptions implements Parcelable {
result = 31 * result + Arrays.hashCode(myLocationBackgroundPadding);
result = 31 * result + myLocationAccuracyTintColor;
result = 31 * result + myLocationAccuracyAlpha;
- result = 31 * result + (apiBaseUrl != null ? apiBaseUrl.hashCode() : 0);
result = 31 * result + (textureMode ? 1 : 0);
result = 31 * result + (style != null ? style.hashCode() : 0);
return result;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
index 05d1bf1750..831f281401 100755
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
@@ -13,6 +13,7 @@ import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Surface;
+import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.Polygon;
@@ -20,7 +21,7 @@ import com.mapbox.mapboxsdk.annotations.Polyline;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.ProjectedMeters;
-import com.mapbox.mapboxsdk.offline.OfflineManager;
+import com.mapbox.mapboxsdk.storage.DefaultFileSource;
import com.mapbox.mapboxsdk.style.layers.Layer;
import com.mapbox.mapboxsdk.style.layers.NoSuchLayerException;
import com.mapbox.mapboxsdk.style.sources.NoSuchSourceException;
@@ -70,15 +71,10 @@ final class NativeMapView {
public NativeMapView(MapView mapView) {
Context context = mapView.getContext();
- String dataPath = OfflineManager.getDatabasePath(context);
- // With the availability of offline, we're unifying the ambient (cache) and the offline
- // databases to be in the same folder, outside cache, to avoid automatic deletion from
- // the system
- String cachePath = dataPath;
+ DefaultFileSource fileSource = Mapbox.getDefaultFileSource();
pixelRatio = context.getResources().getDisplayMetrics().density;
- String apkPath = context.getPackageCodePath();
int availableProcessors = Runtime.getRuntime().availableProcessors();
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
@@ -97,7 +93,7 @@ final class NativeMapView {
}
onMapChangedListeners = new CopyOnWriteArrayList<>();
this.mapView = mapView;
- nativeMapViewPtr = nativeCreate(cachePath, dataPath, apkPath, pixelRatio, availableProcessors, totalMemory);
+ nativeMapViewPtr = nativeCreate(fileSource, pixelRatio, availableProcessors, totalMemory);
}
//
@@ -294,20 +290,6 @@ final class NativeMapView {
return nativeGetStyleJson(nativeMapViewPtr);
}
- public void setAccessToken(String accessToken) {
- if (isDestroyedOn("setAccessToken")) {
- return;
- }
- nativeSetAccessToken(nativeMapViewPtr, accessToken);
- }
-
- public String getAccessToken() {
- if (isDestroyedOn("getAccessToken")) {
- return null;
- }
- return nativeGetAccessToken(nativeMapViewPtr);
- }
-
public void cancelTransitions() {
if (isDestroyedOn("cancelTransitions")) {
return;
@@ -884,13 +866,6 @@ final class NativeMapView {
nativeScheduleTakeSnapshot(nativeMapViewPtr);
}
- public void setApiBaseUrl(String baseUrl) {
- if (isDestroyedOn("setApiBaseUrl")) {
- return;
- }
- nativeSetAPIBaseURL(nativeMapViewPtr, baseUrl);
- }
-
public float getPixelRatio() {
return pixelRatio;
}
@@ -938,7 +913,7 @@ final class NativeMapView {
// JNI methods
//
- private native long nativeCreate(String cachePath, String dataPath, String apkPath, float pixelRatio,
+ private native long nativeCreate(DefaultFileSource fileSource, float pixelRatio,
int availableProcessors, long totalMemory);
private native void nativeDestroy(long nativeMapViewPtr);
@@ -983,10 +958,6 @@ final class NativeMapView {
private native String nativeGetStyleJson(long nativeMapViewPtr);
- private native void nativeSetAccessToken(long nativeMapViewPtr, String accessToken);
-
- private native String nativeGetAccessToken(long nativeMapViewPtr);
-
private native void nativeCancelTransitions(long nativeMapViewPtr);
private native void nativeSetGestureInProgress(long nativeMapViewPtr, boolean inProgress);
@@ -1131,8 +1102,6 @@ final class NativeMapView {
private native Feature[] nativeQueryRenderedFeaturesForBox(long nativeMapViewPtr, float left, float top, float right,
float bottom, String[] layerIds);
- private native void nativeSetAPIBaseURL(long nativeMapViewPtr, String baseUrl);
-
int getWidth() {
if (isDestroyedOn("")) {
return 0;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java
index beaea73024..04a4a00292 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java
@@ -1,15 +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 java.io.File;
@@ -92,74 +88,17 @@ public class OfflineManager {
* Constructors
*/
private OfflineManager(Context context) {
+ // TODO: r
// Get a pointer to the DefaultFileSource instance
- String assetRoot = getDatabasePath(context);
+ String assetRoot = Mapbox.getDatabasePath(context);
String cachePath = assetRoot + File.separator + DATABASE_NAME;
mDefaultFileSourcePtr = createDefaultFileSource(cachePath, assetRoot, DEFAULT_MAX_CACHE_SIZE);
- setAccessToken(mDefaultFileSourcePtr, Mapbox.getAccessToken());
+ setAccessToken(mDefaultFileSourcePtr, Mapbox.getDefaultFileSource().getAccessToken());
// 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 &lt;uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /&gt;
- * (or WRITE_EXTERNAL_STORAGE) for API level &lt; 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() {
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/DefaultFileSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/DefaultFileSource.java
new file mode 100644
index 0000000000..02e3ed0908
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/DefaultFileSource.java
@@ -0,0 +1,91 @@
+package com.mapbox.mapboxsdk.storage;
+
+import android.support.annotation.UiThread;
+import android.support.annotation.NonNull;
+
+@UiThread
+public class DefaultFileSource {
+ //
+ // Native peer management
+ //
+ static {
+ System.loadLibrary("mapbox-gl");
+ }
+
+ // Pointer to the native peer
+ private long peer;
+
+ // Initializes the native peer object
+ private native void initialize(String cachePath, String assetRoot, long maximumCacheSize);
+
+ @Override
+ protected native void finalize() throws Throwable;
+
+ //
+ // Constants
+ //
+
+ /*
+ * The maximumCacheSize parameter is a limit applied to non-offline resources only,
+ * i.e. resources added to the database for the "ambient use" caching functionality.
+ * There is no size limit for offline resources.
+ */
+ private static final long DEFAULT_MAX_CACHE_SIZE = 50 * 1024 * 1024;
+
+ //
+ // Constructors
+ //
+
+ /**
+ * Creates a new DefaultFileSource object.
+ *
+ * @param cachePath Path to the cache database file
+ * @param assetRoot Path to the APK that contains the assets
+ * @param maximumCacheSize Maximum size of the database file, in bytes
+ */
+ public DefaultFileSource(@NonNull String cachePath, @NonNull String assetRoot, long maximumCacheSize) {
+ initialize(cachePath, assetRoot, maximumCacheSize);
+ }
+
+ /**
+ * Creates a new DefaultFileSource object.
+ *
+ * @param cachePath Path to the cache database file
+ * @param assetRoot Path to the APK that contains the assets
+ */
+ public DefaultFileSource(@NonNull String cachePath, @NonNull String assetRoot) {
+ initialize(cachePath, assetRoot, DEFAULT_MAX_CACHE_SIZE);
+ }
+
+ //
+ // Methods
+ //
+
+ /**
+ * Sets the API base URL when connecting to Mapbox servers. Defaults to <code>https://api.mapbox.com</code>.
+ *
+ * @param apiBaseURL New path prefix of Mapbox-hosted assets
+ */
+ public native void setAPIBaseURL(@NonNull String apiBaseURL);
+
+ /**
+ * Returns the currently set API base URL for Mapbox-hosted assets.
+ *
+ * @return The path prefix for Mapbox-hosted assets
+ */
+ public native String getAPIBaseURL();
+
+ /**
+ * Sets the access token for Mapbox resources.
+ *
+ * @param accessToken New access token for Mapbox-hosted assets
+ */
+ public native void setAccessToken(@NonNull String accessToken);
+
+ /**
+ * Returns the current Mapbox access token.
+ *
+ * @return The access token currently used for requesting Mapbox-hosted assets
+ */
+ public native String getAccessToken();
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml b/platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml
index 5b2945d55d..8e18c6ee59 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml
@@ -8,9 +8,7 @@
<public name="mapbox_AlertDialogStyle" type="style" />
<!-- Exposed attrs.xml -->
- <public name="mapbox_accessToken" type="attr" />
<public name="mapbox_styleUrl" type="attr" />
- <public name="mapbox_apiBaseUrl" type="attr" />
<public name="mapbox_cameraTargetLng" type="attr" />
<public name="mapbox_cameraTargetLat" type="attr" />
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml
index 12c395d46f..77b95a0ede 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml
@@ -4,7 +4,6 @@
<!--Configuration-->
<attr name="mapbox_styleUrl" format="string" />
- <attr name="mapbox_apiBaseUrl" format="string" />
<!--Camera-->
<attr name="mapbox_cameraTargetLat" format="float" />
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxApplication.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxApplication.java
index a10c6eaad3..1964bad825 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxApplication.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxApplication.java
@@ -37,7 +37,14 @@ public class MapboxApplication extends Application {
.penaltyDeath()
.build());
- Mapbox.getInstance(getApplicationContext(), getString(R.string.mapbox_access_token));
+ // Obtain the API base URL, but don't expect it to exist.
+ String apiBaseURL = null;
+ int apiBaseURLID = getResources().getIdentifier("mapbox_api_base_url", "string", getPackageName());
+ if (apiBaseURLID != 0) {
+ apiBaseURL = getString(apiBaseURLID);
+ }
+
+ Mapbox.getInstance(getApplicationContext(), getString(R.string.mapbox_access_token), apiBaseURL);
}
private void initializeLogger() {
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/MapboxApplication.java b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/MapboxApplication.java
index cbbdcb8493..f8c72b327a 100644
--- a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/MapboxApplication.java
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/MapboxApplication.java
@@ -11,7 +11,16 @@ public class MapboxApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
- Mapbox.getInstance(getApplicationContext(), getString(R.string.mapbox_access_token));
+
+ // Obtain the API base URL, but don't expect it to exist.
+ String apiBaseURL = null;
+ int apiBaseURLID = getResources().getIdentifier("mapbox_api_base_url", "string", getPackageName());
+ if (apiBaseURLID != 0) {
+ apiBaseURL = getString(apiBaseURLID);
+ }
+
+ Mapbox.getInstance(getApplicationContext(), getString(R.string.mapbox_access_token), apiBaseURL);
+
LeakCanary.install(this);
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
diff --git a/platform/android/config.cmake b/platform/android/config.cmake
index 635c27a44f..61669d48a7 100644
--- a/platform/android/config.cmake
+++ b/platform/android/config.cmake
@@ -89,6 +89,10 @@ macro(mbgl_platform_core)
PRIVATE platform/default/mbgl/util/default_thread_pool.cpp
PRIVATE platform/default/mbgl/util/default_thread_pool.hpp
+ # Storage
+ PRIVATE platform/android/src/storage/default_file_source_peer.cpp
+ PRIVATE platform/android/src/storage/default_file_source_peer.hpp
+
# Conversion C++ -> Java
platform/android/src/conversion/constant.hpp
platform/android/src/conversion/conversion.hpp
diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp
index 5182e268f3..d136766455 100755
--- a/platform/android/src/jni.cpp
+++ b/platform/android/src/jni.cpp
@@ -14,6 +14,7 @@
#include "connectivity_listener.hpp"
#include "style/layers/layers.hpp"
#include "style/sources/sources.hpp"
+#include "storage/default_file_source_peer.hpp"
#include "conversion/conversion.hpp"
#include "conversion/collection.hpp"
@@ -27,6 +28,7 @@
#include <mbgl/sprite/sprite_image.hpp>
#include <mbgl/util/event.hpp>
#include <mbgl/util/logging.hpp>
+#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/network_status.hpp>
#include <mbgl/util/exception.hpp>
#include <mbgl/util/optional.hpp>
@@ -46,9 +48,6 @@ void RegisterNativeHTTPRequest(JNIEnv&);
JavaVM* theJVM;
-std::string cachePath;
-std::string dataPath;
-std::string apkPath;
std::string androidRelease;
jni::jmethodID* onInvalidateId = nullptr;
@@ -299,12 +298,9 @@ namespace {
using namespace mbgl::android;
using DebugOptions = mbgl::MapDebugOptions;
-jlong nativeCreate(JNIEnv *env, jni::jobject* obj, jni::jstring* cachePath_, jni::jstring* dataPath_, jni::jstring* apkPath_, jfloat pixelRatio, jint availableProcessors, jlong totalMemory) {
+jlong nativeCreate(JNIEnv *env, jni::jobject* obj, jni::Object<DefaultFileSourcePeer> fileSource, jfloat pixelRatio, jint availableProcessors, jlong totalMemory) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeCreate");
- cachePath = std_string_from_jstring(env, cachePath_);
- dataPath = std_string_from_jstring(env, dataPath_);
- apkPath = std_string_from_jstring(env, apkPath_);
- return reinterpret_cast<jlong>(new NativeMapView(env, jni::Unwrap(obj), pixelRatio, availableProcessors, totalMemory));
+ return reinterpret_cast<jlong>(new NativeMapView(env, jni::Unwrap(obj), fileSource, pixelRatio, availableProcessors, totalMemory));
}
void nativeDestroy(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) {
@@ -419,12 +415,6 @@ jni::jobject* nativeGetClasses(JNIEnv *env, jni::jobject* obj, jlong nativeMapVi
return std_vector_string_to_jobject(env, nativeMapView->getMap().getClasses());
}
-void nativeSetAPIBaseURL(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* url) {
- assert(nativeMapViewPtr != 0);
- NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
- nativeMapView->getFileSource().setAPIBaseURL(std_string_from_jstring(env, url));
-}
-
void nativeSetStyleUrl(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* url) {
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
@@ -449,18 +439,6 @@ jni::jstring* nativeGetStyleJson(JNIEnv *env, jni::jobject* obj, jlong nativeMap
return std_string_to_jstring(env, nativeMapView->getMap().getStyleJSON());
}
-void nativeSetAccessToken(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* accessToken) {
- assert(nativeMapViewPtr != 0);
- NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
- nativeMapView->getFileSource().setAccessToken(std_string_from_jstring(env, accessToken));
-}
-
-jni::jstring* nativeGetAccessToken(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) {
- assert(nativeMapViewPtr != 0);
- NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
- return std_string_to_jstring(env, nativeMapView->getFileSource().getAccessToken());
-}
-
void nativeCancelTransitions(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) {
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
@@ -1728,6 +1706,9 @@ void registerNatives(JavaVM *vm) {
registerNativeSources(env);
ConnectivityListener::registerNative(env);
+ mbgl::Log::Error(mbgl::Event::JNI, "registering DefaultFileSource peer");
+ DefaultFileSourcePeer::registerNative(env);
+
latLngClass = &jni::FindClass(env, "com/mapbox/mapboxsdk/geometry/LatLng");
latLngClass = jni::NewGlobalRef(env, latLngClass).release();
latLngConstructorId = &jni::GetMethodID(env, *latLngClass, "<init>", "(DD)V");
@@ -1804,7 +1785,7 @@ void registerNatives(JavaVM *vm) {
#define MAKE_NATIVE_METHOD(name, sig) jni::MakeNativeMethod<decltype(name), name>( #name, sig )
jni::RegisterNatives(env, nativeMapViewClass,
- MAKE_NATIVE_METHOD(nativeCreate, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;FIJ)J"),
+ MAKE_NATIVE_METHOD(nativeCreate, "(Lcom/mapbox/mapboxsdk/storage/DefaultFileSource;FIJ)J"),
MAKE_NATIVE_METHOD(nativeDestroy, "(J)V"),
MAKE_NATIVE_METHOD(nativeInitializeDisplay, "(J)V"),
MAKE_NATIVE_METHOD(nativeTerminateDisplay, "(J)V"),
@@ -1825,8 +1806,6 @@ void registerNatives(JavaVM *vm) {
MAKE_NATIVE_METHOD(nativeGetStyleUrl, "(J)Ljava/lang/String;"),
MAKE_NATIVE_METHOD(nativeSetStyleJson, "(JLjava/lang/String;)V"),
MAKE_NATIVE_METHOD(nativeGetStyleJson, "(J)Ljava/lang/String;"),
- MAKE_NATIVE_METHOD(nativeSetAccessToken, "(JLjava/lang/String;)V"),
- MAKE_NATIVE_METHOD(nativeGetAccessToken, "(J)Ljava/lang/String;"),
MAKE_NATIVE_METHOD(nativeCancelTransitions, "(J)V"),
MAKE_NATIVE_METHOD(nativeSetGestureInProgress, "(JZ)V"),
MAKE_NATIVE_METHOD(nativeMoveBy, "(JDDJ)V"),
@@ -1889,8 +1868,7 @@ void registerNatives(JavaVM *vm) {
MAKE_NATIVE_METHOD(nativeSetContentPadding, "(JDDDD)V"),
MAKE_NATIVE_METHOD(nativeScheduleTakeSnapshot, "(J)V"),
MAKE_NATIVE_METHOD(nativeQueryRenderedFeaturesForPoint, "(JFF[Ljava/lang/String;)[Lcom/mapbox/services/commons/geojson/Feature;"),
- MAKE_NATIVE_METHOD(nativeQueryRenderedFeaturesForBox, "(JFFFF[Ljava/lang/String;)[Lcom/mapbox/services/commons/geojson/Feature;"),
- MAKE_NATIVE_METHOD(nativeSetAPIBaseURL, "(JLjava/lang/String;)V")
+ MAKE_NATIVE_METHOD(nativeQueryRenderedFeaturesForBox, "(JFFFF[Ljava/lang/String;)[Lcom/mapbox/services/commons/geojson/Feature;")
);
// Offline begin
diff --git a/platform/android/src/jni.hpp b/platform/android/src/jni.hpp
index 90ec914cf2..f6a71c13e4 100644
--- a/platform/android/src/jni.hpp
+++ b/platform/android/src/jni.hpp
@@ -11,9 +11,6 @@ namespace android {
extern JavaVM* theJVM;
-extern std::string cachePath;
-extern std::string dataPath;
-extern std::string apkPath;
extern std::string androidRelease;
extern jmethodID onInvalidateId;
diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp
index 8234b74af2..3e2013c0d3 100755
--- a/platform/android/src/native_map_view.cpp
+++ b/platform/android/src/native_map_view.cpp
@@ -10,6 +10,7 @@
#include <sys/system_properties.h>
+#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/util/platform.hpp>
#include <mbgl/util/event.hpp>
#include <mbgl/util/logging.hpp>
@@ -37,10 +38,16 @@ void log_egl_string(EGLDisplay display, EGLint name, const char *label) {
}
}
-NativeMapView::NativeMapView(JNIEnv *env_, jobject obj_, float pixelRatio, int availableProcessors_, size_t totalMemory_)
+NativeMapView::NativeMapView(JNIEnv* env_,
+ jobject obj_,
+ jni::Object<DefaultFileSourcePeer> fileSource_,
+ float pixelRatio,
+ int availableProcessors_,
+ size_t totalMemory_)
: env(env_),
availableProcessors(availableProcessors_),
totalMemory(totalMemory_),
+ fileSource(fileSource_.NewGlobalRef(*env)),
threadPool(4) {
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::NativeMapView");
@@ -58,13 +65,13 @@ NativeMapView::NativeMapView(JNIEnv *env_, jobject obj_, float pixelRatio, int a
return;
}
- fileSource = std::make_unique<mbgl::DefaultFileSource>(
- mbgl::android::cachePath + "/mbgl-offline.db",
- mbgl::android::apkPath);
+ jni::Field<DefaultFileSourcePeer, jlong> peerField{ *env, DefaultFileSourcePeer::javaClass,
+ "peer" };
+ auto fileSourcePtr = reinterpret_cast<DefaultFileSourcePeer*>(fileSource->Get(*env, peerField));
map = std::make_unique<mbgl::Map>(
*this, mbgl::Size{ static_cast<uint32_t>(width), static_cast<uint32_t>(height) },
- pixelRatio, *fileSource, threadPool, MapMode::Continuous);
+ pixelRatio, fileSourcePtr->getFileSource(), threadPool, MapMode::Continuous);
float zoomFactor = map->getMaxZoom() - map->getMinZoom() + 1;
float cpuFactor = availableProcessors;
@@ -218,8 +225,6 @@ void NativeMapView::render() {
mbgl::Map &NativeMapView::getMap() { return *map; }
-mbgl::DefaultFileSource &NativeMapView::getFileSource() { return *fileSource; }
-
void NativeMapView::initializeDisplay() {
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::initializeDisplay");
diff --git a/platform/android/src/native_map_view.hpp b/platform/android/src/native_map_view.hpp
index e7379700a9..ea75ef7702 100755
--- a/platform/android/src/native_map_view.hpp
+++ b/platform/android/src/native_map_view.hpp
@@ -5,7 +5,8 @@
#include <mbgl/map/backend.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/default_thread_pool.hpp>
-#include <mbgl/storage/default_file_source.hpp>
+
+#include "storage/default_file_source_peer.hpp"
#include <string>
#include <jni.h>
@@ -17,7 +18,12 @@ namespace android {
class NativeMapView : public mbgl::View, public mbgl::Backend {
public:
- NativeMapView(JNIEnv *env, jobject obj, float pixelRatio, int availableProcessors, size_t totalMemory);
+ NativeMapView(JNIEnv* env,
+ jobject obj,
+ jni::Object<DefaultFileSourcePeer> fileSourcePeer,
+ float pixelRatio,
+ int availableProcessors,
+ size_t totalMemory);
virtual ~NativeMapView();
mbgl::Size getFramebufferSize() const;
@@ -29,7 +35,6 @@ public:
void notifyMapChange(mbgl::MapChange) override;
mbgl::Map &getMap();
- mbgl::DefaultFileSource &getFileSource();
void initializeDisplay();
void terminateDisplay();
@@ -96,7 +101,7 @@ private:
size_t totalMemory = 0;
// Ensure these are initialised last
- std::unique_ptr<mbgl::DefaultFileSource> fileSource;
+ jni::UniqueObject<DefaultFileSourcePeer> fileSource;
mbgl::ThreadPool threadPool;
std::unique_ptr<mbgl::Map> map;
mbgl::EdgeInsets insets;
diff --git a/platform/android/src/storage/default_file_source_peer.cpp b/platform/android/src/storage/default_file_source_peer.cpp
new file mode 100644
index 0000000000..6f8a36b78a
--- /dev/null
+++ b/platform/android/src/storage/default_file_source_peer.cpp
@@ -0,0 +1,54 @@
+#include "default_file_source_peer.hpp"
+
+#include <mbgl/storage/default_file_source.hpp>
+
+namespace mbgl {
+namespace android {
+
+jni::Class<DefaultFileSourcePeer> DefaultFileSourcePeer::javaClass;
+
+#define NATIVE_METHOD(MethodPtr, name) \
+ jni::MakeNativePeerMethod<decltype(MethodPtr), (MethodPtr)>(name)
+
+void DefaultFileSourcePeer::registerNative(jni::JNIEnv& env) {
+ javaClass = *jni::Class<DefaultFileSourcePeer>::Find(env).NewGlobalRef(env).release();
+
+ jni::RegisterNativePeer<DefaultFileSourcePeer>(
+ env, javaClass, "peer",
+ std::make_unique<DefaultFileSourcePeer, JNIEnv&, jni::String, jni::String, jni::jlong>,
+ "initialize", "finalize",
+ NATIVE_METHOD(&DefaultFileSourcePeer::setAPIBaseURL, "setAPIBaseURL"),
+ NATIVE_METHOD(&DefaultFileSourcePeer::getAPIBaseURL, "getAPIBaseURL"),
+ NATIVE_METHOD(&DefaultFileSourcePeer::setAccessToken, "setAccessToken"),
+ NATIVE_METHOD(&DefaultFileSourcePeer::getAccessToken, "getAccessToken"));
+}
+
+DefaultFileSourcePeer::DefaultFileSourcePeer(jni::JNIEnv& env,
+ jni::String cachePath,
+ jni::String assetRoot,
+ jni::jlong maximumCacheSize)
+ : native(std::make_unique<DefaultFileSource>(jni::Make<std::string>(env, cachePath),
+ jni::Make<std::string>(env, assetRoot),
+ maximumCacheSize)) {
+}
+
+DefaultFileSourcePeer::~DefaultFileSourcePeer() = default;
+
+void DefaultFileSourcePeer::setAPIBaseURL(jni::JNIEnv& env, jni::String baseURL) {
+ native->setAPIBaseURL(jni::Make<std::string>(env, baseURL));
+}
+
+jni::String DefaultFileSourcePeer::getAPIBaseURL(jni::JNIEnv& env) {
+ return jni::Make<jni::String>(env, native->getAPIBaseURL());
+}
+
+void DefaultFileSourcePeer::setAccessToken(jni::JNIEnv& env, jni::String accessToken) {
+ native->setAccessToken(jni::Make<std::string>(env, accessToken));
+}
+
+jni::String DefaultFileSourcePeer::getAccessToken(jni::JNIEnv& env) {
+ return jni::Make<jni::String>(env, native->getAccessToken());
+}
+
+} // namespace android
+} // namespace mbgl
diff --git a/platform/android/src/storage/default_file_source_peer.hpp b/platform/android/src/storage/default_file_source_peer.hpp
new file mode 100644
index 0000000000..c0f60447b3
--- /dev/null
+++ b/platform/android/src/storage/default_file_source_peer.hpp
@@ -0,0 +1,40 @@
+#pragma once
+
+#include <jni/jni.hpp>
+
+#include <memory>
+
+namespace mbgl {
+
+class DefaultFileSource;
+
+namespace android {
+
+class DefaultFileSourcePeer {
+public:
+ static constexpr auto Name() { return "com/mapbox/mapboxsdk/storage/DefaultFileSource"; }
+ static jni::Class<DefaultFileSourcePeer> javaClass;
+ static void registerNative(jni::JNIEnv&);
+
+ DefaultFileSourcePeer(jni::JNIEnv&,
+ jni::String cachePath,
+ jni::String assetRoot,
+ jni::jlong maximumCacheSize);
+ ~DefaultFileSourcePeer();
+
+ void setAPIBaseURL(jni::JNIEnv&, jni::String);
+ jni::String getAPIBaseURL(jni::JNIEnv&);
+
+ void setAccessToken(jni::JNIEnv&, jni::String);
+ jni::String getAccessToken(jni::JNIEnv&);
+
+ DefaultFileSource& getFileSource() {
+ return *native;
+ }
+
+private:
+ const std::unique_ptr<DefaultFileSource> native;
+};
+
+} // namespace android
+} // namespace mbgl