[android] Introduce AccountsManager to support SKU tokens in API requests (#14404)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -87,6 +90,16 @@ public final class Mapbox {
|
||||
FileSource.getInstance(getApplicationContext()).setAccessToken(accessToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
|
||||
@@ -12,6 +12,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
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user