summaryrefslogtreecommitdiff
path: root/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module
diff options
context:
space:
mode:
authortobrun <tobrun.van.nuland@gmail.com>2018-07-17 15:05:53 +0200
committerTobrun <tobrun@mapbox.com>2018-08-24 18:40:11 +0200
commitd297bf10ef89e97da30e1a00dd49560e18bcb3f0 (patch)
tree7f7eea2ffd8125777d258a62683d3ffbeb66820f /platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module
parent0f58d956d7b525f3722f24494784c8b97801105a (diff)
downloadqtlocation-mapboxgl-d297bf10ef89e97da30e1a00dd49560e18bcb3f0.tar.gz
[android] - modularise the sdk
Diffstat (limited to 'platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module')
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/http/HttpRequestImpl.java179
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/http/HttpRequestUtil.java64
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/TelemetryImpl.java173
3 files changed, 416 insertions, 0 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/http/HttpRequestImpl.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/http/HttpRequestImpl.java
new file mode 100644
index 0000000000..3195022d3a
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/http/HttpRequestImpl.java
@@ -0,0 +1,179 @@
+package com.mapbox.mapboxsdk.module.http;
+
+import android.os.Build;
+import android.support.annotation.NonNull;
+import android.text.TextUtils;
+import android.util.Log;
+import com.mapbox.mapboxsdk.BuildConfig;
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
+import com.mapbox.mapboxsdk.http.HttpRequest;
+import com.mapbox.mapboxsdk.http.HttpIdentifier;
+import com.mapbox.mapboxsdk.http.HttpLogger;
+import com.mapbox.mapboxsdk.http.HttpResponder;
+import com.mapbox.mapboxsdk.http.HttpRequestUrl;
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.Dispatcher;
+import okhttp3.HttpUrl;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
+
+import javax.net.ssl.SSLException;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.NoRouteToHostException;
+import java.net.ProtocolException;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+
+import static com.mapbox.mapboxsdk.module.http.HttpRequestUtil.toHumanReadableAscii;
+
+public class HttpRequestImpl implements HttpRequest {
+
+ private static final String userAgentString = toHumanReadableAscii(
+ String.format("%s %s (%s) Android/%s (%s)",
+ HttpIdentifier.getIdentifier(),
+ BuildConfig.MAPBOX_VERSION_STRING,
+ BuildConfig.GIT_REVISION_SHORT,
+ Build.VERSION.SDK_INT,
+ Build.CPU_ABI)
+ );
+
+ private static OkHttpClient client = new OkHttpClient.Builder().dispatcher(getDispatcher()).build();
+
+ private Call call;
+
+ @Override
+ public void executeRequest(HttpResponder httpRequest, long nativePtr, String resourceUrl,
+ String etag, String modified) {
+ OkHttpCallback callback = new OkHttpCallback(httpRequest);
+ try {
+ HttpUrl httpUrl = HttpUrl.parse(resourceUrl);
+ if (httpUrl == null) {
+ HttpLogger.log(Log.ERROR, String.format("[HTTP] Unable to parse resourceUrl %s", resourceUrl));
+ return;
+ }
+
+ final String host = httpUrl.host().toLowerCase(MapboxConstants.MAPBOX_LOCALE);
+ resourceUrl = HttpRequestUrl.buildResourceUrl(host, resourceUrl, httpUrl.querySize());
+
+ final Request.Builder builder = new Request.Builder()
+ .url(resourceUrl)
+ .tag(resourceUrl.toLowerCase(MapboxConstants.MAPBOX_LOCALE))
+ .addHeader("User-Agent", userAgentString);
+ if (etag.length() > 0) {
+ builder.addHeader("If-None-Match", etag);
+ } else if (modified.length() > 0) {
+ builder.addHeader("If-Modified-Since", modified);
+ }
+
+ final Request request = builder.build();
+ call = client.newCall(request);
+ call.enqueue(callback);
+ } catch (Exception exception) {
+ callback.handleFailure(call, exception);
+ }
+ }
+
+ @Override
+ public void cancelRequest() {
+ // call can be null if the constructor gets aborted (e.g, under a NoRouteToHostException).
+ if (call != null) {
+ call.cancel();
+ }
+ }
+
+ public static void enablePrintRequestUrlOnFailure(boolean enabled) {
+ HttpLogger.logRequestUrl = enabled;
+ }
+
+ public static void enableLog(boolean enabled) {
+ HttpLogger.logEnabled = enabled;
+ }
+
+ public static void setOkHttpClient(OkHttpClient okHttpClient) {
+ HttpRequestImpl.client = okHttpClient;
+ }
+
+ private static class OkHttpCallback implements Callback {
+
+ private HttpResponder httpRequest;
+
+ OkHttpCallback(HttpResponder httpRequest) {
+ this.httpRequest = httpRequest;
+ }
+
+ @Override
+ public void onFailure(@NonNull Call call, @NonNull IOException e) {
+ handleFailure(call, e);
+ }
+
+ @Override
+ public void onResponse(@NonNull Call call, @NonNull Response response) {
+ if (response.isSuccessful()) {
+ HttpLogger.log(Log.VERBOSE, String.format("[HTTP] Request was successful (code = %s).", response.code()));
+ } else {
+ // We don't want to call this unsuccessful because a 304 isn't really an error
+ String message = !TextUtils.isEmpty(response.message()) ? response.message() : "No additional information";
+ HttpLogger.log(Log.DEBUG, String.format("[HTTP] Request with response = %s: %s", response.code(), message));
+ }
+
+ ResponseBody responseBody = response.body();
+ if (responseBody == null) {
+ HttpLogger.log(Log.ERROR, "[HTTP] Received empty response body");
+ return;
+ }
+
+ byte[] body;
+ try {
+ body = responseBody.bytes();
+ } catch (IOException ioException) {
+ onFailure(call, ioException);
+ // throw ioException;
+ return;
+ } finally {
+ response.close();
+ }
+
+ httpRequest.onResponse(response.code(),
+ response.header("ETag"),
+ response.header("Last-Modified"),
+ response.header("Cache-Control"),
+ response.header("Expires"),
+ response.header("Retry-After"),
+ response.header("x-rate-limit-reset"),
+ body);
+ }
+
+ private void handleFailure(Call call, Exception e) {
+ String errorMessage = e.getMessage() != null ? e.getMessage() : "Error processing the request";
+ int type = getFailureType(e);
+
+ if (HttpLogger.logEnabled && call != null && call.request() != null) {
+ String requestUrl = call.request().url().toString();
+ HttpLogger.logFailure(type, errorMessage, requestUrl);
+ }
+ httpRequest.handleFailure(type, errorMessage);
+ }
+
+ private int getFailureType(Exception e) {
+ if ((e instanceof NoRouteToHostException) || (e instanceof UnknownHostException) || (e instanceof SocketException)
+ || (e instanceof ProtocolException) || (e instanceof SSLException)) {
+ return CONNECTION_ERROR;
+ } else if ((e instanceof InterruptedIOException)) {
+ return TEMPORARY_ERROR;
+ }
+ return PERMANENT_ERROR;
+ }
+ }
+
+ private static Dispatcher getDispatcher() {
+ Dispatcher dispatcher = new Dispatcher();
+ // Matches core limit set on
+ // https://github.com/mapbox/mapbox-gl-native/blob/master/platform/android/src/http_file_source.cpp#L192
+ dispatcher.setMaxRequestsPerHost(20);
+ return dispatcher;
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/http/HttpRequestUtil.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/http/HttpRequestUtil.java
new file mode 100644
index 0000000000..66031ea724
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/http/HttpRequestUtil.java
@@ -0,0 +1,64 @@
+package com.mapbox.mapboxsdk.module.http;
+
+import okhttp3.OkHttpClient;
+import okio.Buffer;
+
+/**
+ * Utility class for setting OkHttpRequest configurations
+ */
+public class HttpRequestUtil {
+
+ /**
+ * Set the log state of OkHttpRequest. Default value is true.
+ * <p>
+ * This configuration will outlast the lifecycle of the Map.
+ * </p>
+ *
+ * @param enabled True will enable logging, false will disable
+ */
+ public static void setLogEnabled(boolean enabled) {
+ HttpRequestImpl.enableLog(enabled);
+ }
+
+ /**
+ * Enable printing of the request url when an error occurred. Default value is false.
+ * <p>
+ * Requires {@link #setLogEnabled(boolean)} to be activated.
+ * </p>
+ * <p>
+ * This configuration will outlast the lifecycle of the Map.
+ * </p>
+ *
+ * @param enabled True will print urls, false will disable
+ */
+ public static void setPrintRequestUrlOnFailure(boolean enabled) {
+ HttpRequestImpl.enablePrintRequestUrlOnFailure(enabled);
+ }
+
+ /**
+ * Set the OkHttpClient used for requesting map resources.
+ *
+ * @param client the OkHttpClient
+ */
+ public static void setOkHttpClient(OkHttpClient client) {
+ HttpRequestImpl.setOkHttpClient(client);
+ }
+
+ static String toHumanReadableAscii(String s) {
+ for (int i = 0, length = s.length(), c; i < length; i += Character.charCount(c)) {
+ c = s.codePointAt(i);
+ if (c > '\u001f' && c < '\u007f') {
+ continue;
+ }
+
+ Buffer buffer = new Buffer();
+ buffer.writeUtf8(s, 0, i);
+ for (int j = i; j < length; j += Character.charCount(c)) {
+ c = s.codePointAt(j);
+ buffer.writeUtf8CodePoint(c > '\u001f' && c < '\u007f' ? c : '?');
+ }
+ return buffer.readUtf8();
+ }
+ return s;
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000000..4a0b425a86
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/TelemetryImpl.java
@@ -0,0 +1,173 @@
+package com.mapbox.mapboxsdk.module.telemetry;
+
+import android.content.Context;
+import com.mapbox.android.telemetry.AppUserTurnstile;
+import com.mapbox.android.telemetry.Event;
+import com.mapbox.android.telemetry.MapEventFactory;
+import com.mapbox.android.telemetry.MapState;
+import com.mapbox.android.telemetry.MapboxTelemetry;
+import com.mapbox.android.telemetry.SessionInterval;
+import com.mapbox.android.telemetry.TelemetryEnabler;
+import com.mapbox.mapboxsdk.BuildConfig;
+import com.mapbox.mapboxsdk.Mapbox;
+import com.mapbox.mapboxsdk.log.Logger;
+import com.mapbox.mapboxsdk.maps.TelemetryDefinition;
+
+import java.lang.reflect.Field;
+
+public class TelemetryImpl implements TelemetryDefinition {
+
+ private static final String TAG = "Mbgl-TelemetryImpl";
+ private static TelemetryImpl instance;
+ private MapboxTelemetry telemetry;
+
+ /**
+ * Get a single instance of TelemetryImpl.
+ *
+ * @return instance of Telemetry
+ * @deprecated reference instance from Mapbox.java instead
+ */
+ @Deprecated
+ public static synchronized TelemetryImpl getInstance() {
+ if (instance == null) {
+ instance = new TelemetryImpl();
+ }
+ return instance;
+ }
+
+ private TelemetryImpl() {
+ Context appContext = Mapbox.getApplicationContext();
+ String accessToken = Mapbox.getAccessToken();
+ telemetry = new MapboxTelemetry(appContext, accessToken, BuildConfig.MAPBOX_EVENTS_USER_AGENT);
+ TelemetryEnabler.State telemetryState = TelemetryEnabler.retrieveTelemetryStateFromPreferences();
+ if (TelemetryEnabler.State.ENABLED.equals(telemetryState)) {
+ telemetry.enable();
+ }
+ }
+
+ /**
+ * Register the app user turnstile event
+ */
+ @Override
+ public void onAppUserTurnstileEvent() {
+ AppUserTurnstile turnstileEvent = new AppUserTurnstile(BuildConfig.MAPBOX_SDK_IDENTIFIER,
+ BuildConfig.MAPBOX_SDK_VERSION);
+ telemetry.push(turnstileEvent);
+ MapEventFactory mapEventFactory = new MapEventFactory();
+ telemetry.push(mapEventFactory.createMapLoadEvent(Event.Type.MAP_LOAD));
+ }
+
+ /**
+ * Register an end-user gesture interaction event.
+ *
+ * @param eventType type of gesture event occurred
+ * @param latitude the latitude value of the gesture focal point
+ * @param longitude the longitude value of the gesture focal point
+ * @param zoom current zoom of the map
+ */
+ @Override
+ public void onGestureInteraction(String eventType, double latitude, double longitude, double zoom) {
+ MapEventFactory mapEventFactory = new MapEventFactory();
+ MapState state = new MapState(latitude, longitude, zoom);
+ state.setGesture(eventType);
+ telemetry.push(mapEventFactory.createMapGestureEvent(Event.Type.MAP_CLICK, state));
+ }
+
+ /**
+ * Set the end-user selected state to participate or opt-out in telemetry collection.
+ */
+ @Override
+ public void setUserTelemetryRequestState(boolean enabledTelemetry) {
+ if (enabledTelemetry) {
+ TelemetryEnabler.updateTelemetryState(TelemetryEnabler.State.ENABLED);
+ telemetry.enable();
+ } else {
+ telemetry.disable();
+ TelemetryEnabler.updateTelemetryState(TelemetryEnabler.State.DISABLED);
+ }
+ }
+
+ /**
+ * Set the debug logging state of telemetry.
+ *
+ * @param debugLoggingEnabled true to enable logging
+ */
+ @Override
+ public void setDebugLoggingEnabled(boolean debugLoggingEnabled) {
+ telemetry.updateDebugLoggingEnabled(debugLoggingEnabled);
+ }
+
+ /**
+ * Set the telemetry rotation session id interval
+ *
+ * @param interval the selected session interval
+ * @return true if rotation session id was updated
+ */
+ @Override
+ public boolean setSessionIdRotationInterval(int interval) {
+ return telemetry.updateSessionIdRotationInterval(new SessionInterval(interval));
+ }
+
+ /**
+ * Set the debug logging state of telemetry.
+ *
+ * @param debugLoggingEnabled true to enable logging
+ * @deprecated use {@link #setDebugLoggingEnabled(boolean)} instead
+ */
+ @Deprecated
+ public static void updateDebugLoggingEnabled(boolean debugLoggingEnabled) {
+ TelemetryDefinition definition = Mapbox.getTelemetry();
+ if (definition != null) {
+ definition.setDebugLoggingEnabled(debugLoggingEnabled);
+ }
+ }
+
+ /**
+ * Update the telemetry rotation session id interval
+ *
+ * @param interval the selected session interval
+ * @return true if rotation session id was updated
+ * @deprecated use {@link #setSessionIdRotationInterval(int)} instead
+ */
+ @Deprecated
+ public static boolean updateSessionIdRotationInterval(SessionInterval interval) {
+ try {
+ Field field = interval.getClass().getDeclaredField("interval");
+ field.setAccessible(true);
+ Integer intervalValue = (Integer) field.get(interval);
+ TelemetryDefinition definition = Mapbox.getTelemetry();
+ if (definition != null) {
+ return definition.setSessionIdRotationInterval(intervalValue);
+ }
+ } catch (Exception exception) {
+ Logger.e(TAG, "Exception occurred when updating session id rotation interval", exception);
+ }
+ return false;
+ }
+
+ /**
+ * Method to be called when an end-user has selected to participate in telemetry collection.
+ *
+ * @deprecated use {@link #setUserTelemetryRequestState(boolean)} with parameter true instead
+ */
+ @Deprecated
+ public static void enableOnUserRequest() {
+ TelemetryDefinition definition = Mapbox.getTelemetry();
+ if (definition != null) {
+ definition.setUserTelemetryRequestState(true);
+ }
+ }
+
+ /**
+ * Method to be called when an end-user has selected to opt-out of telemetry collection.
+ *
+ * @deprecated use {@link #setUserTelemetryRequestState(boolean)} with parameter false instead
+ */
+ @Deprecated
+ public static void disableOnUserRequest() {
+ TelemetryDefinition definition = Mapbox.getTelemetry();
+ if (definition != null) {
+ definition.setUserTelemetryRequestState(false);
+ }
+ }
+}