summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Zugaldia <antonio@mapbox.com>2019-04-18 16:29:20 -0400
committerGitHub <noreply@github.com>2019-04-18 16:29:20 -0400
commitd0a1526a94dd596e02306ae8c3638ca58e24a323 (patch)
tree056e98ffbd3bb21e1f671471ff7f04de4e606ae9
parentec8cf0ce8b56086c990fdf0c95b7a11d159481f4 (diff)
downloadqtlocation-mapboxgl-d0a1526a94dd596e02306ae8c3638ca58e24a323.tar.gz
[android] Introduce AccountsManager to support SKU tokens in API requests (#14404)
-rw-r--r--platform/android/LICENSE.md6
-rw-r--r--platform/android/MapboxGLAndroidSDK/build.gradle1
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/AccountsManager.java112
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java13
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java5
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HttpRequestUrl.java4
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/TelemetryImpl.java8
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java8
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/AccountsManagerTest.java24
-rw-r--r--platform/android/gradle/dependencies.gradle2
10 files changed, 174 insertions, 9 deletions
diff --git a/platform/android/LICENSE.md b/platform/android/LICENSE.md
index 35ae99120f..b269437fe6 100644
--- a/platform/android/LICENSE.md
+++ b/platform/android/LICENSE.md
@@ -71,6 +71,12 @@ License: [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt)
===========================================================================
+Mapbox GL uses portions of the Mapbox Accounts SDK for Android.
+URL: [https://github.com/mapbox/mapbox-accounts-android](https://github.com/mapbox/mapbox-accounts-android)
+License: [Mapbox Terms of Service](https://www.mapbox.com/tos/)
+
+===========================================================================
+
Mapbox GL uses portions of the Mapbox Android Core Library.
URL: [https://github.com/mapbox/mapbox-events-android](https://github.com/mapbox/mapbox-events-android)
License: [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt)
diff --git a/platform/android/MapboxGLAndroidSDK/build.gradle b/platform/android/MapboxGLAndroidSDK/build.gradle
index 108f6315d8..510dc79d43 100644
--- a/platform/android/MapboxGLAndroidSDK/build.gradle
+++ b/platform/android/MapboxGLAndroidSDK/build.gradle
@@ -7,6 +7,7 @@ dependencies {
api dependenciesList.mapboxAndroidTelemetry
api dependenciesList.mapboxJavaGeoJSON
api dependenciesList.mapboxAndroidGestures
+ api dependenciesList.mapboxAndroidAccounts
implementation dependenciesList.mapboxJavaTurf
implementation dependenciesList.supportAnnotations
implementation dependenciesList.supportFragmentV4
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/AccountsManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/AccountsManager.java
new file mode 100644
index 0000000000..4fd0200a37
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/AccountsManager.java
@@ -0,0 +1,112 @@
+package com.mapbox.mapboxsdk;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.support.annotation.NonNull;
+import android.text.TextUtils;
+import android.text.format.DateUtils;
+
+import com.mapbox.android.accounts.v1.MapboxAccounts;
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
+
+/**
+ * REMOVAL OR MODIFICATION OF THE FOLLOWING CODE VIOLATES THE MAPBOX TERMS
+ * OF SERVICE
+ *
+ * The following code is used to access Mapbox's Mapping APIs.
+ *
+ * Removal or modification of this code when used with Mapbox's Mapping APIs
+ * can result in termination of your agreement and/or your account with
+ * Mapbox.
+ *
+ * Using this code to access Mapbox Mapping APIs from outside the Mapbox Maps
+ * SDK also violates the Mapbox Terms of Service. On Android, Mapping APIs
+ * should be accessed using the methods documented at
+ * https://www.mapbox.com/android.
+ *
+ * You can access the Mapbox Terms of Service at https://www.mapbox.com/tos/
+ */
+class AccountsManager {
+ private static final String PREFERENCE_USER_ID = "com.mapbox.mapboxsdk.accounts.userid";
+ private static final String PREFERENCE_TIMESTAMP = "com.mapbox.mapboxsdk.accounts.timestamp";
+ private static final String PREFERENCE_SKU_TOKEN = "com.mapbox.mapboxsdk.accounts.skutoken";
+
+ private long timestamp;
+ private String skuToken;
+
+ AccountsManager() {
+ String userId = validateUserId();
+ validateRotation(userId);
+ }
+
+ private String validateUserId() {
+ SharedPreferences sharedPreferences = getSharedPreferences();
+ String userId = sharedPreferences.getString(PREFERENCE_USER_ID, "");
+ if (TextUtils.isEmpty(userId)) {
+ userId = generateUserId();
+ SharedPreferences.Editor editor = getSharedPreferences().edit();
+ editor.putString(PREFERENCE_USER_ID, userId);
+ editor.apply();
+ }
+
+ return userId;
+ }
+
+ private void validateRotation(String userId) {
+ SharedPreferences sharedPreferences = getSharedPreferences();
+ timestamp = sharedPreferences.getLong(PREFERENCE_TIMESTAMP, 0L);
+ skuToken = sharedPreferences.getString(PREFERENCE_SKU_TOKEN, "");
+ if (timestamp == 0L || TextUtils.isEmpty(skuToken)) {
+ skuToken = generateSkuToken(userId);
+ timestamp = persistRotation(skuToken);
+ }
+ }
+
+ String getSkuToken() {
+ if (isExpired()) {
+ SharedPreferences sharedPreferences = getSharedPreferences();
+ String userId = sharedPreferences.getString(PREFERENCE_USER_ID, "");
+ skuToken = generateSkuToken(userId);
+ timestamp = persistRotation(skuToken);
+ }
+
+ return skuToken;
+ }
+
+ private boolean isExpired() {
+ return isExpired(getNow(), timestamp);
+ }
+
+ static boolean isExpired(long now, long then) {
+ return ((now - then) > DateUtils.HOUR_IN_MILLIS);
+ }
+
+ private long persistRotation(String skuToken) {
+ long now = getNow();
+ SharedPreferences.Editor editor = getSharedPreferences().edit();
+ editor.putLong(PREFERENCE_TIMESTAMP, now);
+ editor.putString(PREFERENCE_SKU_TOKEN, skuToken);
+ editor.apply();
+ return now;
+ }
+
+ @NonNull
+ private SharedPreferences getSharedPreferences() {
+ return Mapbox.getApplicationContext()
+ .getSharedPreferences(MapboxConstants.MAPBOX_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ }
+
+ static long getNow() {
+ return System.currentTimeMillis();
+ }
+
+ @NonNull
+ private String generateUserId() {
+ return MapboxAccounts.obtainEndUserId();
+ }
+
+ @NonNull
+ private String generateSkuToken(String userId) {
+ return MapboxAccounts.obtainMapsSkuUserToken(userId);
+ }
+}
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 f5304017a5..5a1c49a0a4 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
@@ -34,6 +34,8 @@ public final class Mapbox {
private String accessToken;
@Nullable
private TelemetryDefinition telemetry;
+ @Nullable
+ private AccountsManager accounts;
/**
* Get an instance of Mapbox.
@@ -56,6 +58,7 @@ public final class Mapbox {
INSTANCE = new Mapbox(appContext, accessToken);
if (isAccessTokenValid(accessToken)) {
initializeTelemetry();
+ INSTANCE.accounts = new AccountsManager();
}
ConnectivityReceiver.instance(appContext);
}
@@ -88,6 +91,16 @@ public final class Mapbox {
}
/**
+ * Returns a SKU token, refreshed if necessary. This method is meant for internal SDK
+ * usage only.
+ *
+ * @return the SKU token
+ */
+ public static String getSkuToken() {
+ return INSTANCE.accounts.getSkuToken();
+ }
+
+ /**
* Application context
*
* @return the application context
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java
index 2b69646fcc..ffcf8d74ec 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java
@@ -13,6 +13,11 @@ public class MapboxConstants {
public static final Locale MAPBOX_LOCALE = Locale.US;
/**
+ * The name of the desired preferences file for Android's SharedPreferences.
+ */
+ public static final String MAPBOX_SHARED_PREFERENCES = "MapboxSharedPreferences";
+
+ /**
* Key used to switch storage to external in AndroidManifest.xml
*/
public static final String KEY_META_DATA_SET_STORAGE_EXTERNAL = "com.mapbox.SetStorageExternal";
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HttpRequestUrl.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HttpRequestUrl.java
index 37e3869692..ec4d90cbc7 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HttpRequestUrl.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HttpRequestUrl.java
@@ -2,6 +2,8 @@ package com.mapbox.mapboxsdk.http;
import android.support.annotation.NonNull;
+import com.mapbox.mapboxsdk.Mapbox;
+
public class HttpRequestUrl {
private HttpRequestUrl() {
@@ -22,7 +24,7 @@ public class HttpRequestUrl {
} else {
resourceUrl = resourceUrl + "&";
}
- resourceUrl = resourceUrl + "events=true";
+ resourceUrl = resourceUrl + "events=true&sku=" + Mapbox.getSkuToken();
}
return resourceUrl;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/TelemetryImpl.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/TelemetryImpl.java
index 46a0c47d50..944999715a 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/TelemetryImpl.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/TelemetryImpl.java
@@ -4,8 +4,8 @@ import android.content.Context;
import android.os.Bundle;
import android.support.annotation.FloatRange;
import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
+import com.mapbox.android.accounts.v1.MapboxAccounts;
import com.mapbox.android.telemetry.AppUserTurnstile;
import com.mapbox.android.telemetry.MapboxTelemetry;
import com.mapbox.android.telemetry.SessionInterval;
@@ -21,9 +21,8 @@ import java.util.UUID;
public class TelemetryImpl implements TelemetryDefinition {
- @Nullable
- private MapboxTelemetry telemetry;
- private Context appContext;
+ private final MapboxTelemetry telemetry;
+ private final Context appContext;
public TelemetryImpl() {
appContext = Mapbox.getApplicationContext();
@@ -42,6 +41,7 @@ public class TelemetryImpl implements TelemetryDefinition {
public void onAppUserTurnstileEvent() {
AppUserTurnstile turnstileEvent = new AppUserTurnstile(BuildConfig.MAPBOX_SDK_IDENTIFIER,
BuildConfig.MAPBOX_SDK_VERSION);
+ turnstileEvent.setSkuId(MapboxAccounts.SKU_ID_MAPS_MAUS);
telemetry.push(turnstileEvent);
telemetry.push(MapEventFactory.buildMapLoadEvent(new PhoneState(appContext)));
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java
index db99f255ac..cc4988b549 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java
@@ -31,7 +31,6 @@ import java.util.concurrent.locks.ReentrantLock;
public class FileSource {
private static final String TAG = "Mbgl-FileSource";
- private static final String MAPBOX_SHARED_PREFERENCES = "MapboxSharedPreferences";
private static final String MAPBOX_SHARED_PREFERENCE_RESOURCES_CACHE_PATH = "fileSourceResourcesCachePath";
private static final Lock resourcesCachePathLoaderLock = new ReentrantLock();
private static final Lock internalCachePathLoaderLock = new ReentrantLock();
@@ -107,7 +106,8 @@ public class FileSource {
*/
@NonNull
private static String getCachePath(@NonNull Context context) {
- SharedPreferences preferences = context.getSharedPreferences(MAPBOX_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences preferences = context.getSharedPreferences(
+ MapboxConstants.MAPBOX_SHARED_PREFERENCES, Context.MODE_PRIVATE);
String cachePath = preferences.getString(MAPBOX_SHARED_PREFERENCE_RESOURCES_CACHE_PATH, null);
if (!isPathWritable(cachePath)) {
@@ -116,7 +116,7 @@ public class FileSource {
// Reset stored cache path
SharedPreferences.Editor editor =
- context.getSharedPreferences(MAPBOX_SHARED_PREFERENCES, Context.MODE_PRIVATE).edit();
+ context.getSharedPreferences(MapboxConstants.MAPBOX_SHARED_PREFERENCES, Context.MODE_PRIVATE).edit();
editor.remove(MAPBOX_SHARED_PREFERENCE_RESOURCES_CACHE_PATH).apply();
}
@@ -306,7 +306,7 @@ public class FileSource {
callback.onError(fileSourceActivatedMessage);
} else {
final SharedPreferences.Editor editor =
- context.getSharedPreferences(MAPBOX_SHARED_PREFERENCES, Context.MODE_PRIVATE).edit();
+ context.getSharedPreferences(MapboxConstants.MAPBOX_SHARED_PREFERENCES, Context.MODE_PRIVATE).edit();
editor.putString(MAPBOX_SHARED_PREFERENCE_RESOURCES_CACHE_PATH, path);
editor.apply();
setResourcesCachePath(context, path);
diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/AccountsManagerTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/AccountsManagerTest.java
new file mode 100644
index 0000000000..3f846e6640
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/AccountsManagerTest.java
@@ -0,0 +1,24 @@
+package com.mapbox.mapboxsdk;
+
+import android.text.format.DateUtils;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class AccountsManagerTest {
+ @Test
+ public void testIsExpired() {
+ long now = AccountsManager.getNow();
+
+ long defaultValue = 0L;
+ long tooOld = now - DateUtils.HOUR_IN_MILLIS - 1;
+ long futureValue = now + 1;
+ long immediatePast = now - 1;
+
+ Assert.assertTrue(AccountsManager.isExpired(now, defaultValue));
+ Assert.assertTrue(AccountsManager.isExpired(now, tooOld));
+
+ Assert.assertFalse(AccountsManager.isExpired(now, futureValue));
+ Assert.assertFalse(AccountsManager.isExpired(now, immediatePast));
+ }
+}
diff --git a/platform/android/gradle/dependencies.gradle b/platform/android/gradle/dependencies.gradle
index f9c6f2ac1b..4d95456284 100644
--- a/platform/android/gradle/dependencies.gradle
+++ b/platform/android/gradle/dependencies.gradle
@@ -11,6 +11,7 @@ ext {
mapboxTelemetry : '4.4.1',
mapboxCore : '1.3.0',
mapboxGestures : '0.4.1',
+ mapboxAccounts : '0.1.0',
supportLib : '27.1.1',
constraintLayout: '1.1.2',
uiAutomator : '2.1.3',
@@ -39,6 +40,7 @@ ext {
mapboxJavaGeoJSON : "com.mapbox.mapboxsdk:mapbox-sdk-geojson:${versions.mapboxServices}",
mapboxAndroidTelemetry : "com.mapbox.mapboxsdk:mapbox-android-telemetry:${versions.mapboxTelemetry}",
mapboxAndroidGestures : "com.mapbox.mapboxsdk:mapbox-android-gestures:${versions.mapboxGestures}",
+ mapboxAndroidAccounts : "com.mapbox.mapboxsdk:mapbox-android-accounts:${versions.mapboxAccounts}",
mapboxJavaTurf : "com.mapbox.mapboxsdk:mapbox-sdk-turf:${versions.mapboxServices}",
junit : "junit:junit:${versions.junit}",