diff --git a/platform/android/MapboxGLAndroidModuleBase/.gitignore b/platform/android/MapboxGLAndroidModuleBase/.gitignore
new file mode 100644
index 00000000000..796b96d1c40
--- /dev/null
+++ b/platform/android/MapboxGLAndroidModuleBase/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/platform/android/MapboxGLAndroidModuleBase/build.gradle b/platform/android/MapboxGLAndroidModuleBase/build.gradle
new file mode 100644
index 00000000000..aedbb26a8ae
--- /dev/null
+++ b/platform/android/MapboxGLAndroidModuleBase/build.gradle
@@ -0,0 +1,25 @@
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion androidVersions.compileSdkVersion
+
+ defaultConfig {
+ minSdkVersion androidVersions.minSdkVersion
+ targetSdkVersion androidVersions.targetSdkVersion
+ buildConfigField "String", "MAPBOX_VERSION_STRING", String.format("\"Mapbox/%s\"", project.VERSION_NAME)
+ buildConfigField "String", "MAPBOX_SDK_IDENTIFIER", String.format("\"%s\"", "mapbox-maps-android")
+ buildConfigField "String", "MAPBOX_SDK_VERSION", String.format("\"%s\"", project.VERSION_NAME)
+ versionCode 1
+ versionName "1.0"
+ buildConfigField "String", "MAPBOX_EVENTS_USER_AGENT", String.format("\"MapboxEventsAndroid/%s\"", project.VERSION_NAME)
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ dependencies {
+ implementation dependenciesList.supportAnnotations
+ }
+}
\ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidModuleBase/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidModuleBase/src/main/AndroidManifest.xml
new file mode 100644
index 00000000000..1ac48e6903b
--- /dev/null
+++ b/platform/android/MapboxGLAndroidModuleBase/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java b/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java
similarity index 100%
rename from platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java
rename to platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java
diff --git a/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/constants/TelemetryConstants.java b/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/constants/TelemetryConstants.java
new file mode 100644
index 00000000000..31a1baea4ab
--- /dev/null
+++ b/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/constants/TelemetryConstants.java
@@ -0,0 +1,13 @@
+package com.mapbox.mapboxsdk.constants;
+
+public class TelemetryConstants {
+
+ public static final String TWO_FINGER_TAP = "TwoFingerTap";
+ public static final String DOUBLE_TAP = "DoubleTap";
+ public static final String SINGLE_TAP = "SingleTap";
+ public static final String PAN = "Pan";
+ public static final String PINCH = "Pinch";
+ public static final String ROTATION = "Rotation";
+ public static final String PITCH = "Pitch";
+
+}
diff --git a/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/http/HttpRequest.java b/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/http/HttpRequest.java
new file mode 100644
index 00000000000..786aa1143bd
--- /dev/null
+++ b/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/http/HttpRequest.java
@@ -0,0 +1,95 @@
+package com.mapbox.mapboxsdk.http;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.support.annotation.NonNull;
+import com.mapbox.mapboxsdk.utils.MapboxConfigurationWrapper;
+
+/**
+ * Base class for performing core http requests.
+ *
+ * This abstraction allows to provide alternative implementations for the http interaction of this library.
+ *
+ */
+public abstract class HttpRequest {
+
+ static final int CONNECTION_ERROR = 0;
+ static final int TEMPORARY_ERROR = 1;
+ static final int PERMANENT_ERROR = 2;
+
+ /**
+ * Executes the request.
+ *
+ * @param httpRequest callback to be invoked when we receive a response
+ * @param nativePtr the pointer associated to the request
+ * @param resourceUrl the resource url to download
+ * @param etag http header, identifier for a specific version of a resource
+ * @param modified http header, used to determine if a resource hasn't been modified since
+ */
+ public abstract void executeRequest(HttpRequestResponder httpRequest, long nativePtr, String resourceUrl,
+ String etag, String modified);
+
+ /**
+ * Cancels the request.
+ */
+ public abstract void cancelRequest();
+
+ //
+ // Utility methods
+ //
+
+ /**
+ * Returns the application identifier, consisting out the package name, version name and version code.
+ *
+ * @return the appliciation identifier
+ */
+ static String getApplicationIdentifier() {
+ return getApplicationIdentifier(MapboxConfigurationWrapper.getContext());
+ }
+
+ /**
+ * Returns the application identifier, consisting out the package name, version name and version code.
+ *
+ * @param context the context used to retrieve the package manager from
+ * @return the appliciation identifier
+ */
+ private static String getApplicationIdentifier(@NonNull Context context) {
+ try {
+ PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
+ return String.format("%s/%s (%s)", context.getPackageName(), packageInfo.versionName, packageInfo.versionCode);
+ } catch (Exception exception) {
+ return "";
+ }
+ }
+
+ /**
+ * Adapts a resource request url based on the host and query size.
+ *
+ * @param host the host used as endpoint
+ * @param resourceUrl the resource to download
+ * @param querySize the query size of the resource request
+ * @return the adapted resource url
+ */
+ String buildResourceUrl(String host, String resourceUrl, int querySize) {
+ if (isValidMapboxEndpoint(host)) {
+ if (querySize == 0) {
+ resourceUrl = resourceUrl + "?";
+ } else {
+ resourceUrl = resourceUrl + "&";
+ }
+ resourceUrl = resourceUrl + "events=true";
+ }
+ return resourceUrl;
+ }
+
+ /**
+ * Validates if the host used as endpoint is a valid Mapbox endpoint.
+ *
+ * @param host the host used as endpoint
+ * @return true if a valid Mapbox endpoint
+ */
+ private boolean isValidMapboxEndpoint(String host) {
+ return host.equals("mapbox.com") || host.endsWith(".mapbox.com") || host.equals("mapbox.cn")
+ || host.endsWith(".mapbox.cn");
+ }
+}
diff --git a/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/http/HttpRequestResponder.java b/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/http/HttpRequestResponder.java
new file mode 100644
index 00000000000..9d67e3c2810
--- /dev/null
+++ b/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/http/HttpRequestResponder.java
@@ -0,0 +1,32 @@
+package com.mapbox.mapboxsdk.http;
+
+/**
+ * Interface definition for a callback to be invoked when either a response was returned for a requested resource or
+ * when an error occurred when requesting the resource.
+ */
+public interface HttpRequestResponder {
+
+ /**
+ * Invoked when a resource has finished.
+ *
+ * @param responseCode http response code
+ * @param eTag http header, identifier for a specific version of a resource
+ * @param lastModified http header, used to determine if a resource hasn't been modified since
+ * @param cacheControl http header, used to determine cache strategy of a resource
+ * @param expires http header, used to determine when a resource is stale
+ * @param retryAfter http header, used to indicate when the service is expected to be unavailable to the client
+ * @param xRateLimitReset http header, used to determine the remaining window before the rate limit resets
+ * @param body http response body, in an array of bytes representation
+ */
+ void onResponse(int responseCode, String eTag, String lastModified, String cacheControl, String expires,
+ String retryAfter, String xRateLimitReset, byte[] body);
+
+ /**
+ * Invoked when a resource failed to be retrieved.
+ *
+ * @param type the error type, either one of {@link HttpRequest#CONNECTION_ERROR},
+ * {@link HttpRequest#TEMPORARY_ERROR} or {@link HttpRequest#PERMANENT_ERROR}
+ * @param errorMessage the error message associated with the failure
+ */
+ void handleFailure(int type, String errorMessage);
+}
diff --git a/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/log/Logger.java b/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/log/Logger.java
new file mode 100644
index 00000000000..955df1ad5cb
--- /dev/null
+++ b/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/log/Logger.java
@@ -0,0 +1,118 @@
+package com.mapbox.mapboxsdk.log;
+
+import android.util.Log;
+
+public final class Logger {
+
+ private static final LoggerDefinition DEFAULT = new LoggerDefinition() {
+
+ @Override
+ public void v(String tag, String msg) {
+ Log.v(tag, msg);
+ }
+
+ @Override
+ public void v(String tag, String msg, Throwable tr) {
+ Log.v(tag, msg, tr);
+ }
+
+ @Override
+ public void d(String tag, String msg) {
+ Log.d(tag, msg);
+ }
+
+ @Override
+ public void d(String tag, String msg, Throwable tr) {
+ Log.d(tag, msg, tr);
+ }
+
+ @Override
+ public void i(String tag, String msg) {
+ Log.i(tag, msg);
+ }
+
+ @Override
+ public void i(String tag, String msg, Throwable tr) {
+ Log.i(tag, msg, tr);
+ }
+
+ @Override
+ public void w(String tag, String msg) {
+ Log.w(tag, msg);
+ }
+
+ @Override
+ public void w(String tag, String msg, Throwable tr) {
+ Log.w(tag, msg, tr);
+ }
+
+ @Override
+ public void w(String tag, Throwable tr) {
+ Log.w(tag, tr);
+ }
+
+ @Override
+ public void e(String tag, String msg) {
+ Log.e(tag, msg);
+ }
+
+ @Override
+ public void e(String tag, String msg, Throwable tr) {
+ Log.e(tag, msg, tr);
+ }
+ };
+
+ private static volatile LoggerDefinition logger = DEFAULT;
+
+ public static void setLoggerDefinition(LoggerDefinition loggerDefinition) {
+ logger = loggerDefinition;
+ }
+
+ public static void v(String tag, String msg) {
+ logger.v(tag, msg);
+ }
+
+ public static void v(String tag, String msg, Throwable tr) {
+ logger.v(tag, msg, tr);
+ }
+
+ public static void d(String tag, String msg) {
+ logger.d(tag, msg);
+ }
+
+ public static void d(String tag, String msg, Throwable tr) {
+ logger.d(tag, msg, tr);
+ }
+
+ public static void i(String tag, String msg) {
+ logger.i(tag, msg);
+ }
+
+ public static void i(String tag, String msg, Throwable tr) {
+ logger.i(tag, msg, tr);
+ }
+
+ public static void w(String tag, String msg) {
+ logger.w(tag, msg);
+ }
+
+ public static void w(String tag, String msg, Throwable tr) {
+ logger.w(tag, msg, tr);
+ }
+
+ public static void w(String tag, Throwable tr) {
+ logger.w(tag, tr);
+ }
+
+ public static void e(String tag, String msg) {
+ logger.e(tag, msg);
+ }
+
+ public static void e(String tag, String msg, Throwable tr) {
+ logger.e(tag, msg, tr);
+ }
+
+ public static void log(int severity, String tag, String message) {
+ LoggerDefinition.log(severity, tag, message);
+ }
+}
\ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/log/LoggerDefinition.java b/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/log/LoggerDefinition.java
new file mode 100644
index 00000000000..fcb2a7faa79
--- /dev/null
+++ b/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/log/LoggerDefinition.java
@@ -0,0 +1,50 @@
+package com.mapbox.mapboxsdk.log;
+
+import android.util.Log;
+
+public interface LoggerDefinition {
+
+ void v(String tag, String msg);
+
+ void v(String tag, String msg, Throwable tr);
+
+ void d(String tag, String msg);
+
+ void d(String tag, String msg, Throwable tr);
+
+ void i(String tag, String msg);
+
+ void i(String tag, String msg, Throwable tr);
+
+ void w(String tag, String msg);
+
+ void w(String tag, String msg, Throwable tr);
+
+ void w(String tag, Throwable tr);
+
+ void e(String tag, String msg);
+
+ void e(String tag, String msg, Throwable tr);
+
+ static void log(int severity, String tag, String message) {
+ switch (severity) {
+ case Log.VERBOSE:
+ Logger.v(tag, message);
+ break;
+ case Log.DEBUG:
+ Logger.d(tag, message);
+ break;
+ case Log.INFO:
+ Logger.i(tag, message);
+ break;
+ case Log.WARN:
+ Logger.w(tag, message);
+ break;
+ case Log.ERROR:
+ Logger.e(tag, message);
+ break;
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+}
\ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryBase.java b/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryBase.java
new file mode 100644
index 00000000000..8e429e4f234
--- /dev/null
+++ b/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryBase.java
@@ -0,0 +1,13 @@
+package com.mapbox.mapboxsdk.telemetry;
+
+public interface TelemetryBase {
+
+ void onAppUserTurnstileEvent();
+ void onGestureInteraction(String eventType, double latitude, double longitude, double zoom);
+
+ void enableOnUserRequest();
+ void disableOnUserRequest();
+ void setDebugLoggingEnabled(boolean debugLoggingEnabled);
+ void setSessionIdRotationInterval(int interval);
+
+}
diff --git a/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/utils/MapboxConfigurationWrapper.java b/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/utils/MapboxConfigurationWrapper.java
new file mode 100644
index 00000000000..8690cb7efb0
--- /dev/null
+++ b/platform/android/MapboxGLAndroidModuleBase/src/main/java/com/mapbox/mapboxsdk/utils/MapboxConfigurationWrapper.java
@@ -0,0 +1,43 @@
+package com.mapbox.mapboxsdk.utils;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+
+/**
+ * Application context wrapper, provides context to modular components.
+ *
+ * Initialised as part of Mapbox.java.
+ *
+ */
+public class MapboxConfigurationWrapper extends ContextWrapper {
+
+ private static MapboxConfigurationWrapper instance;
+ private static String accessToken;
+
+ public static synchronized MapboxConfigurationWrapper initialize(Context context, String accessToken) {
+ if (instance == null) {
+ instance = new MapboxConfigurationWrapper(context.getApplicationContext(), accessToken);
+ }
+ return instance;
+ }
+
+ private MapboxConfigurationWrapper(Context base, String token) {
+ super(base.getApplicationContext());
+ accessToken = token;
+ }
+
+ public static Context getContext() {
+ Context context = instance.getBaseContext();
+ if (context == null) {
+ throw new IllegalStateException("MapboxConfigurationWrapper isn't initialised correctly.");
+ }
+ return instance.getBaseContext();
+ }
+
+ public static String getAccessToken() {
+ if (accessToken == null) {
+ throw new IllegalStateException("MapboxConfigurationWrapper isn't initialised correctly.");
+ }
+ return accessToken;
+ }
+}
diff --git a/platform/android/MapboxGLAndroidModuleHttp/.gitignore b/platform/android/MapboxGLAndroidModuleHttp/.gitignore
new file mode 100644
index 00000000000..796b96d1c40
--- /dev/null
+++ b/platform/android/MapboxGLAndroidModuleHttp/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/platform/android/MapboxGLAndroidModuleHttp/build.gradle b/platform/android/MapboxGLAndroidModuleHttp/build.gradle
new file mode 100644
index 00000000000..c31f28b1e1f
--- /dev/null
+++ b/platform/android/MapboxGLAndroidModuleHttp/build.gradle
@@ -0,0 +1,29 @@
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion androidVersions.compileSdkVersion
+
+ defaultConfig {
+ minSdkVersion androidVersions.minSdkVersion
+ targetSdkVersion androidVersions.targetSdkVersion
+ versionCode 1
+ versionName "1.0"
+ buildConfigField "String", "GIT_REVISION_SHORT", String.format("\"%s\"", getGitRevision())
+ buildConfigField "String", "MAPBOX_VERSION_STRING", String.format("\"Mapbox/%s\"", project.VERSION_NAME)
+ }
+}
+
+dependencies {
+ api(project(':MapboxGLAndroidModuleBase'))
+ implementation dependenciesList.okhttp3
+ implementation dependenciesList.supportAnnotations
+ implementation dependenciesList.timber
+}
+
+def static getGitRevision() {
+ def cmd = "git rev-parse --short HEAD"
+ def proc = cmd.execute()
+ def ref = proc.text.trim()
+ return ref
+}
+
diff --git a/platform/android/MapboxGLAndroidModuleHttp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidModuleHttp/src/main/AndroidManifest.xml
new file mode 100644
index 00000000000..bb661323470
--- /dev/null
+++ b/platform/android/MapboxGLAndroidModuleHttp/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/platform/android/MapboxGLAndroidModuleHttp/src/main/java/com/mapbox/mapboxsdk/http/HttpRequestImpl.java b/platform/android/MapboxGLAndroidModuleHttp/src/main/java/com/mapbox/mapboxsdk/http/HttpRequestImpl.java
new file mode 100644
index 00000000000..c562f1b1478
--- /dev/null
+++ b/platform/android/MapboxGLAndroidModuleHttp/src/main/java/com/mapbox/mapboxsdk/http/HttpRequestImpl.java
@@ -0,0 +1,186 @@
+package com.mapbox.mapboxsdk.http;
+
+import android.os.Build;
+import android.support.annotation.NonNull;
+import android.text.TextUtils;
+import android.util.Log;
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
+import okhttp3.*;
+import timber.log.Timber;
+
+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.http.HttpRequestUtil.toHumanReadableAscii;
+
+public class HttpRequestImpl extends HttpRequest {
+
+ private static final String userAgentString = toHumanReadableAscii(
+ String.format("%s %s (%s) Android/%s (%s)",
+ getApplicationIdentifier(),
+ 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 static boolean logEnabled = true;
+ private static boolean logRequestUrl = false;
+
+ private Call call;
+
+ @Override
+ public void executeRequest(HttpRequestResponder httpRequest, long nativePtr, String resourceUrl,
+ String etag, String modified) {
+ OkHttpCallback callback = new OkHttpCallback(httpRequest);
+ try {
+ HttpUrl httpUrl = HttpUrl.parse(resourceUrl);
+ if (httpUrl == null) {
+ log(Log.ERROR, String.format("[HTTP] Unable to parse resourceUrl %s", resourceUrl));
+ return;
+ }
+
+ final String host = httpUrl.host().toLowerCase(MapboxConstants.MAPBOX_LOCALE);
+ resourceUrl = 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) {
+ logRequestUrl = enabled;
+ }
+
+ public static void enableLog(boolean enabled) {
+ logEnabled = enabled;
+ }
+
+ public static void setOkHttpClient(OkHttpClient okHttpClient) {
+ HttpRequestImpl.client = okHttpClient;
+ }
+
+ private static class OkHttpCallback implements Callback {
+
+ private HttpRequestResponder httpRequest;
+
+ OkHttpCallback(HttpRequestResponder 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()) {
+ 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";
+ log(Log.DEBUG, String.format("[HTTP] Request with response code = %s: %s", response.code(), message));
+ }
+
+ ResponseBody responseBody = response.body();
+ if (responseBody == null) {
+ 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 (logEnabled && call != null && call.request() != null) {
+ String requestUrl = call.request().url().toString();
+ logFailure(type, errorMessage, requestUrl);
+ }
+ httpRequest.handleFailure(type, errorMessage);
+ }
+
+ private void logFailure(int type, String errorMessage, String requestUrl) {
+ log(type == TEMPORARY_ERROR ? Log.DEBUG : type == CONNECTION_ERROR ? Log.INFO : Log.WARN,
+ String.format(
+ "Request failed due to a %s error: %s %s",
+ type == TEMPORARY_ERROR ? "temporary" : type == CONNECTION_ERROR ? "connection" : "permanent",
+ errorMessage,
+ logRequestUrl ? requestUrl : ""
+ )
+ );
+ }
+
+ 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;
+ }
+
+ static void log(int type, String errorMessage) {
+ if (logEnabled) {
+ Timber.log(type, errorMessage);
+ }
+ }
+}
\ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HttpRequestUtil.java b/platform/android/MapboxGLAndroidModuleHttp/src/main/java/com/mapbox/mapboxsdk/http/HttpRequestUtil.java
similarity index 52%
rename from platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HttpRequestUtil.java
rename to platform/android/MapboxGLAndroidModuleHttp/src/main/java/com/mapbox/mapboxsdk/http/HttpRequestUtil.java
index 872032867ae..d8b9591a634 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HttpRequestUtil.java
+++ b/platform/android/MapboxGLAndroidModuleHttp/src/main/java/com/mapbox/mapboxsdk/http/HttpRequestUtil.java
@@ -1,14 +1,15 @@
package com.mapbox.mapboxsdk.http;
import okhttp3.OkHttpClient;
+import okio.Buffer;
/**
- * Utility class for setting HttpRequest configurations
+ * Utility class for setting OkHttpRequest configurations
*/
public class HttpRequestUtil {
/**
- * Set the log state of HttpRequest. Default value is true.
+ * Set the log state of OkHttpRequest. Default value is true.
*
* This configuration will outlast the lifecycle of the Map.
*
@@ -16,7 +17,7 @@ public class HttpRequestUtil {
* @param enabled True will enable logging, false will disable
*/
public static void setLogEnabled(boolean enabled) {
- HTTPRequest.enableLog(enabled);
+ HttpRequestImpl.enableLog(enabled);
}
/**
@@ -31,7 +32,7 @@ public static void setLogEnabled(boolean enabled) {
* @param enabled True will print urls, false will disable
*/
public static void setPrintRequestUrlOnFailure(boolean enabled) {
- HTTPRequest.enablePrintRequestUrlOnFailure(enabled);
+ HttpRequestImpl.enablePrintRequestUrlOnFailure(enabled);
}
/**
@@ -40,7 +41,24 @@ public static void setPrintRequestUrlOnFailure(boolean enabled) {
* @param client the OkHttpClient
*/
public static void setOkHttpClient(OkHttpClient client) {
- HTTPRequest.setOKHttpClient(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/MapboxGLAndroidModuleTelemetry/.gitignore b/platform/android/MapboxGLAndroidModuleTelemetry/.gitignore
new file mode 100644
index 00000000000..796b96d1c40
--- /dev/null
+++ b/platform/android/MapboxGLAndroidModuleTelemetry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/platform/android/MapboxGLAndroidModuleTelemetry/build.gradle b/platform/android/MapboxGLAndroidModuleTelemetry/build.gradle
new file mode 100644
index 00000000000..41c3c6f6ddb
--- /dev/null
+++ b/platform/android/MapboxGLAndroidModuleTelemetry/build.gradle
@@ -0,0 +1,19 @@
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion 28
+
+ defaultConfig {
+ minSdkVersion 14
+ targetSdkVersion 28
+ versionCode 1
+ versionName "1.0"
+ }
+}
+
+dependencies {
+ api(project(':MapboxGLAndroidModuleBase'))
+ api (dependenciesList.mapboxAndroidTelemetry) {
+ exclude group: 'com.android.support', module: 'appcompat-v7'
+ }
+}
diff --git a/platform/android/MapboxGLAndroidModuleTelemetry/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidModuleTelemetry/src/main/AndroidManifest.xml
new file mode 100644
index 00000000000..9ae6d017cfc
--- /dev/null
+++ b/platform/android/MapboxGLAndroidModuleTelemetry/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/platform/android/MapboxGLAndroidModuleTelemetry/src/main/java/com/mapbox/mapboxsdk/telemetry/Telemetry.java b/platform/android/MapboxGLAndroidModuleTelemetry/src/main/java/com/mapbox/mapboxsdk/telemetry/Telemetry.java
new file mode 100644
index 00000000000..5bb3c38dac7
--- /dev/null
+++ b/platform/android/MapboxGLAndroidModuleTelemetry/src/main/java/com/mapbox/mapboxsdk/telemetry/Telemetry.java
@@ -0,0 +1,66 @@
+package com.mapbox.mapboxsdk.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.module.BuildConfig;
+import com.mapbox.mapboxsdk.utils.MapboxConfigurationWrapper;
+
+public class Telemetry implements TelemetryBase {
+
+ private MapboxTelemetry telemetry;
+
+ public Telemetry() {
+ Context appContext = MapboxConfigurationWrapper.getContext();
+ String accessToken = MapboxConfigurationWrapper.getAccessToken();
+ telemetry = new MapboxTelemetry(appContext, accessToken, BuildConfig.MAPBOX_EVENTS_USER_AGENT);
+ TelemetryEnabler.State telemetryState = TelemetryEnabler.retrieveTelemetryStateFromPreferences();
+ if (TelemetryEnabler.State.ENABLED.equals(telemetryState)) {
+ telemetry.enable();
+ }
+ }
+
+ @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));
+ }
+
+ @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));
+ }
+
+ @Override
+ public void enableOnUserRequest() {
+ TelemetryEnabler.updateTelemetryState(TelemetryEnabler.State.ENABLED);
+ telemetry.enable();
+ }
+
+ @Override
+ public void disableOnUserRequest() {
+ telemetry.disable();
+ TelemetryEnabler.updateTelemetryState(TelemetryEnabler.State.DISABLED);
+ }
+
+ @Override
+ public void setDebugLoggingEnabled(boolean debugLoggingEnabled) {
+ telemetry.updateDebugLoggingEnabled(debugLoggingEnabled);
+ }
+
+ @Override
+ public void setSessionIdRotationInterval(int interval) {
+ telemetry.updateSessionIdRotationInterval(new SessionInterval(interval));
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/build.gradle b/platform/android/MapboxGLAndroidSDK/build.gradle
index 35b4de003be..b14477d4811 100644
--- a/platform/android/MapboxGLAndroidSDK/build.gradle
+++ b/platform/android/MapboxGLAndroidSDK/build.gradle
@@ -2,17 +2,17 @@ apply plugin: 'com.android.library'
apply plugin: "com.jaredsburrows.license"
dependencies {
- api (dependenciesList.mapboxAndroidTelemetry) {
- exclude group: 'com.android.support', module: 'appcompat-v7'
- }
+ api(project(':MapboxGLAndroidModuleBase'))
+ api(project(':MapboxGLAndroidModuleHttp'))
+ api(project(':MapboxGLAndroidModuleTelemetry'))
+
api dependenciesList.mapboxJavaGeoJSON
api (dependenciesList.mapboxAndroidGestures) {
exclude group: 'com.android.support', module: 'appcompat-v7'
}
implementation dependenciesList.supportAnnotations
implementation dependenciesList.supportFragmentV4
- implementation dependenciesList.timber
- implementation dependenciesList.okhttp3
+ implementation dependenciesList.supportUtilV4
testImplementation dependenciesList.junit
testImplementation dependenciesList.mockito
testImplementation dependenciesList.robolectric
@@ -25,15 +25,11 @@ android {
defaultConfig {
minSdkVersion androidVersions.minSdkVersion
targetSdkVersion androidVersions.targetSdkVersion
- buildConfigField "String", "GIT_REVISION_SHORT", String.format("\"%s\"", getGitRevision())
- buildConfigField "String", "MAPBOX_SDK_IDENTIFIER", String.format("\"%s\"", "mapbox-maps-android")
- buildConfigField "String", "MAPBOX_SDK_VERSION", String.format("\"%s\"", project.VERSION_NAME)
- buildConfigField "String", "MAPBOX_VERSION_STRING", String.format("\"Mapbox/%s\"", project.VERSION_NAME)
- buildConfigField "String", "MAPBOX_EVENTS_USER_AGENT", String.format("\"MapboxEventsAndroid/%s\"", project.VERSION_NAME)
}
defaultPublishConfig project.hasProperty("mapbox.buildtype") ? project.getProperty("mapbox.buildtype") : "debug"
+
// We sometimes want to invoke Gradle without building a native dependency, e.g. when we just want
// to invoke the Java tests. When we explicitly specify an ABI of 'none', no native dependencies are
// added. When another ABI is specified explicitly, we're just going to build that ABI. In all other
@@ -142,13 +138,6 @@ licenseReport {
copyJsonReportToAssets = false
}
-def static getGitRevision() {
- def cmd = "git rev-parse --short HEAD"
- def proc = cmd.execute()
- def ref = proc.text.trim()
- return ref
-}
-
configurations {
all*.exclude group: 'commons-logging', module: 'commons-logging'
all*.exclude group: 'commons-collections', module: 'commons-collections'
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/LibraryLoader.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/LibraryLoader.java
index 6633d5d9525..a91e4bdf140 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/LibraryLoader.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/LibraryLoader.java
@@ -1,6 +1,6 @@
package com.mapbox.mapboxsdk;
-import timber.log.Timber;
+import com.mapbox.mapboxsdk.log.Logger;
/**
* Loads the mapbox-gl shared library
@@ -11,6 +11,8 @@
*/
public abstract class LibraryLoader {
+ private static final String TAG = "LibraryLoader";
+
private static final LibraryLoader DEFAULT = new LibraryLoader() {
@Override
public void load(String name) {
@@ -39,7 +41,7 @@ public static void load() {
try {
loader.load("mapbox-gl");
} catch (UnsatisfiedLinkError error) {
- Timber.e(error, "Failed to load native shared library.");
+ Logger.e(TAG, "Failed to load native shared library.", error);
}
}
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 a8094603755..5db824967d0 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,5 @@
package com.mapbox.mapboxsdk;
-import android.annotation.SuppressLint;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
@@ -10,9 +9,10 @@
import android.text.TextUtils;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.exceptions.MapboxConfigurationException;
-import com.mapbox.mapboxsdk.maps.Telemetry;
+import com.mapbox.mapboxsdk.log.Logger;
import com.mapbox.mapboxsdk.net.ConnectivityReceiver;
-import timber.log.Timber;
+import com.mapbox.mapboxsdk.telemetry.Telemetry;
+import com.mapbox.mapboxsdk.utils.MapboxConfigurationWrapper;
/**
* The entry point to initialize the Mapbox Android SDK.
@@ -25,10 +25,10 @@
@UiThread
public final class Mapbox {
- @SuppressLint("StaticFieldLeak")
+ private static final String TAG = "Mapbox";
+
private static Mapbox INSTANCE;
- private Context context;
- private String accessToken;
+ private Telemetry telemetry;
private Boolean connected;
/**
@@ -41,22 +41,20 @@ public final class Mapbox {
* @param accessToken Mapbox access token
* @return the single instance of Mapbox
*/
- @UiThread
public static synchronized Mapbox getInstance(@NonNull Context context, @Nullable String accessToken) {
if (INSTANCE == null) {
- Context appContext = context.getApplicationContext();
- INSTANCE = new Mapbox(appContext, accessToken);
- if (isAccessTokenValid(accessToken)) {
- initializeTelemetry();
- }
- ConnectivityReceiver.instance(appContext);
+ INSTANCE = new Mapbox(context, accessToken);
}
return INSTANCE;
}
Mapbox(@NonNull Context context, @Nullable String accessToken) {
- this.context = context;
- this.accessToken = accessToken;
+ Context appContext = context.getApplicationContext();
+ MapboxConfigurationWrapper.initialize(appContext, accessToken);
+ if (isAccessTokenValid(accessToken)) {
+ initializeTelemetry();
+ }
+ ConnectivityReceiver.instance(appContext);
}
/**
@@ -67,7 +65,7 @@ public static synchronized Mapbox getInstance(@NonNull Context context, @Nullabl
@Nullable
public static String getAccessToken() {
validateMapbox();
- return INSTANCE.accessToken;
+ return MapboxConfigurationWrapper.getAccessToken();
}
/**
@@ -78,7 +76,21 @@ public static String getAccessToken() {
@NonNull
public static Context getApplicationContext() {
validateMapbox();
- return INSTANCE.context;
+ return MapboxConfigurationWrapper.getContext();
+ }
+
+ /**
+ * Telemetry instance
+ *
+ * If no valid mapbox accesstoken was provided, this method returns null.
+ *
+ *
+ * @return the telemetry instance;
+ */
+ @Nullable
+ public static Telemetry getTelemetry() {
+ validateMapbox();
+ return INSTANCE.telemetry;
}
/**
@@ -107,7 +119,8 @@ public static synchronized Boolean isConnected() {
return INSTANCE.connected;
}
- ConnectivityManager cm = (ConnectivityManager) INSTANCE.context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ Context context = MapboxConfigurationWrapper.getContext();
+ ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return (activeNetwork != null && activeNetwork.isConnected());
}
@@ -117,9 +130,9 @@ public static synchronized Boolean isConnected() {
*/
private static void initializeTelemetry() {
try {
- Telemetry.initialize();
+ INSTANCE.telemetry = new Telemetry();
} catch (Exception exception) {
- Timber.e(exception);
+ Logger.e(TAG, "Error occured while initializing telemetry", exception);
}
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/attribution/Attribution.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/attribution/Attribution.java
index 0877b3ab978..b5030c8677e 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/attribution/Attribution.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/attribution/Attribution.java
@@ -4,7 +4,7 @@ public class Attribution {
private static final String OPENSTREETMAP = "OpenStreetMap";
private static final String OPENSTREETMAP_ABBR = "OSM";
- static final String TELEMETRY = "Telemetry Settings";
+ static final String TELEMETRY = "TelemetryBase Settings";
static final String IMPROVE_MAP_URL = "https://www.mapbox.com/map-feedback/";
static final String MAPBOX_URL = "https://www.mapbox.com/about/maps/";
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/MapboxConfigurationException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/MapboxConfigurationException.java
index 86032aa2b5b..1add1bf0a93 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/MapboxConfigurationException.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/MapboxConfigurationException.java
@@ -17,7 +17,7 @@ public class MapboxConfigurationException extends RuntimeException {
* Creates a Mapbox configuration exception thrown by MapboxMap when the SDK hasn't been properly initialised.
*/
public MapboxConfigurationException() {
- super("\nUsing MapView requires calling Mapbox.getInstance(Context context, String accessToken) before "
+ super("\nUsing MapView requires calling Mapbox.initialize(Context context, String accessToken) before "
+ "inflating or creating the view. The access token parameter is required when using a Mapbox service."
+ "\nPlease see https://www.mapbox.com/help/create-api-access-token/ to learn how to create one."
+ "\nMore information in this guide https://www.mapbox.com/help/first-steps-android-sdk/#access-tokens.");
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
deleted file mode 100644
index e0c63944b90..00000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java
+++ /dev/null
@@ -1,273 +0,0 @@
-package com.mapbox.mapboxsdk.http;
-
-import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.os.Build;
-import android.support.annotation.NonNull;
-import android.text.TextUtils;
-import android.util.Log;
-import com.mapbox.android.telemetry.TelemetryUtils;
-import com.mapbox.mapboxsdk.BuildConfig;
-import com.mapbox.mapboxsdk.Mapbox;
-import com.mapbox.mapboxsdk.constants.MapboxConstants;
-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 timber.log.Timber;
-
-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 java.util.concurrent.locks.ReentrantLock;
-
-import static android.util.Log.DEBUG;
-import static android.util.Log.ERROR;
-import static android.util.Log.INFO;
-import static android.util.Log.VERBOSE;
-import static android.util.Log.WARN;
-
-class HTTPRequest implements Callback {
-
- private static final int CONNECTION_ERROR = 0;
- private static final int TEMPORARY_ERROR = 1;
- private static final int PERMANENT_ERROR = 2;
-
- private static OkHttpClient client = new OkHttpClient.Builder().dispatcher(getDispatcher()).build();
- private static boolean logEnabled = true;
- private static boolean logRequestUrl = false;
-
- // Reentrancy is not needed, but "Lock" is an abstract class.
- private ReentrantLock lock = new ReentrantLock();
- private String userAgentString;
- private long nativePtr = 0;
- private Call call;
-
- private HTTPRequest(long nativePtr, String resourceUrl, String etag, String modified) {
- this.nativePtr = nativePtr;
-
- if (resourceUrl.startsWith("local://")) {
- // used by render test to serve files from assets
- executeLocalRequest(resourceUrl);
- return;
- }
- executeRequest(resourceUrl, etag, modified);
- }
-
- public void cancel() {
- // call can be null if the constructor gets aborted (e.g, under a NoRouteToHostException).
- if (call != null) {
- call.cancel();
- }
-
- // TODO: We need a lock here because we can try
- // to cancel at the same time the request is getting
- // answered on the OkHTTP thread. We could get rid of
- // this lock by using Runnable when we move Android
- // implementation of mbgl::RunLoop to Looper.
- lock.lock();
- nativePtr = 0;
- lock.unlock();
- }
-
- @Override
- public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
- if (response.isSuccessful()) {
- 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";
- log(DEBUG, String.format("[HTTP] Request with response code = %s: %s", response.code(), message));
- }
-
- ResponseBody responseBody = response.body();
- if (responseBody == null) {
- 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();
- }
-
- lock.lock();
- if (nativePtr != 0) {
- nativeOnResponse(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);
- }
- lock.unlock();
- }
-
- @Override
- public void onFailure(@NonNull Call call, @NonNull IOException e) {
- handleFailure(call, e);
- }
-
- static void enableLog(boolean enabled) {
- logEnabled = enabled;
- }
-
- static void enablePrintRequestUrlOnFailure(boolean enabled) {
- logRequestUrl = enabled;
- }
-
- static void setOKHttpClient(OkHttpClient client) {
- HTTPRequest.client = client;
- }
-
- 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;
- }
-
- private void executeRequest(String resourceUrl, String etag, String modified) {
- try {
- HttpUrl httpUrl = HttpUrl.parse(resourceUrl);
- if (httpUrl == null) {
- log(Log.ERROR, String.format("[HTTP] Unable to parse resourceUrl %s", resourceUrl));
- }
-
- final String host = httpUrl.host().toLowerCase(MapboxConstants.MAPBOX_LOCALE);
- // Don't try a request to remote server if we aren't connected
- if (!Mapbox.isConnected() && !host.equals("127.0.0.1") && !host.equals("localhost")) {
- throw new NoRouteToHostException("No Internet connection available.");
- }
-
- if (host.equals("mapbox.com") || host.endsWith(".mapbox.com") || host.equals("mapbox.cn")
- || host.endsWith(".mapbox.cn")) {
- if (httpUrl.querySize() == 0) {
- resourceUrl = resourceUrl + "?";
- } else {
- resourceUrl = resourceUrl + "&";
- }
- resourceUrl = resourceUrl + "events=true";
- }
-
- Request.Builder builder = new Request.Builder()
- .url(resourceUrl)
- .tag(resourceUrl.toLowerCase(MapboxConstants.MAPBOX_LOCALE))
- .addHeader("User-Agent", getUserAgent());
- if (etag.length() > 0) {
- builder = builder.addHeader("If-None-Match", etag);
- } else if (modified.length() > 0) {
- builder = builder.addHeader("If-Modified-Since", modified);
- }
- Request request = builder.build();
- call = client.newCall(request);
- call.enqueue(this);
- } catch (Exception exception) {
- handleFailure(call, exception);
- }
- }
-
- private void executeLocalRequest(String resourceUrl) {
- new LocalRequestTask(new LocalRequestTask.OnLocalRequestResponse() {
- @Override
- public void onResponse(byte[] bytes) {
- if (bytes != null) {
- lock.lock();
- if (nativePtr != 0) {
- nativeOnResponse(200, null, null, null, null, null, null, bytes);
- }
- lock.unlock();
- }
- }
- }).execute(resourceUrl);
- }
-
- private void handleFailure(Call call, Exception e) {
- String errorMessage = e.getMessage() != null ? e.getMessage() : "Error processing the request";
- int type = getFailureType(e);
-
- if (logEnabled && call != null && call.request() != null) {
- String requestUrl = call.request().url().toString();
- logFailure(type, errorMessage, requestUrl);
- }
-
- lock.lock();
- if (nativePtr != 0) {
- nativeOnFailure(type, errorMessage);
- }
- lock.unlock();
- }
-
- 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 void log(int type, String errorMessage) {
- if (logEnabled) {
- Timber.log(type, errorMessage);
- }
- }
-
- private void logFailure(int type, String errorMessage, String requestUrl) {
- log(type == TEMPORARY_ERROR ? DEBUG : type == CONNECTION_ERROR ? INFO : WARN,
- String.format(
- "Request failed due to a %s error: %s %s",
- type == TEMPORARY_ERROR ? "temporary" : type == CONNECTION_ERROR ? "connection" : "permanent",
- errorMessage,
- logRequestUrl ? requestUrl : ""
- )
- );
- }
-
- private String getUserAgent() {
- if (userAgentString == null) {
- userAgentString = TelemetryUtils.toHumanReadableAscii(
- String.format("%s %s (%s) Android/%s (%s)",
- getApplicationIdentifier(),
- BuildConfig.MAPBOX_VERSION_STRING,
- BuildConfig.GIT_REVISION_SHORT,
- Build.VERSION.SDK_INT,
- Build.CPU_ABI)
- );
- }
- return userAgentString;
- }
-
- private String getApplicationIdentifier() {
- try {
- Context context = Mapbox.getApplicationContext();
- PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
- return String.format("%s/%s (%s)", context.getPackageName(), packageInfo.versionName, packageInfo.versionCode);
- } catch (Exception exception) {
- return "";
- }
- }
-
- private native void nativeOnFailure(int type, String message);
-
- private native void nativeOnResponse(int code, String etag, String modified, String cacheControl, String expires,
- String retryAfter, String xRateLimitReset, byte[] body);
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/LocalRequestTask.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/LocalRequestTask.java
index 8f31364c391..61dc367ab77 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/LocalRequestTask.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/LocalRequestTask.java
@@ -3,13 +3,15 @@
import android.content.res.AssetManager;
import android.os.AsyncTask;
import com.mapbox.mapboxsdk.Mapbox;
-import timber.log.Timber;
+import com.mapbox.mapboxsdk.log.Logger;
import java.io.IOException;
import java.io.InputStream;
class LocalRequestTask extends AsyncTask {
+ private static final String TAG = "LocalRequestTask";
+
private OnLocalRequestResponse requestResponse;
LocalRequestTask(OnLocalRequestResponse requestResponse) {
@@ -40,7 +42,7 @@ private static byte[] loadFile(AssetManager assets, String path) {
buffer = new byte[size];
input.read(buffer);
} catch (IOException exception) {
- Timber.e(exception);
+ Logger.e(TAG, "Load file failed", exception);
}
return buffer;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/NativeHttpRequest.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/NativeHttpRequest.java
new file mode 100644
index 00000000000..eb4a7261630
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/NativeHttpRequest.java
@@ -0,0 +1,77 @@
+package com.mapbox.mapboxsdk.http;
+
+import java.util.concurrent.locks.ReentrantLock;
+
+public class NativeHttpRequest implements HttpRequestResponder {
+
+ private final HttpRequestImpl httpRequestImpl = new HttpRequestImpl();
+
+ // Reentrancy is not needed, but "Lock" is an abstract class.
+ private ReentrantLock lock = new ReentrantLock();
+ private long nativePtr = 0;
+
+ private NativeHttpRequest(long nativePtr, String resourceUrl, String etag, String modified) {
+ this.nativePtr = nativePtr;
+
+ if (resourceUrl.startsWith("local://")) {
+ // used by render test to serve files from assets
+ executeLocalRequest(resourceUrl);
+ return;
+ }
+ httpRequestImpl.executeRequest(this, nativePtr, resourceUrl, etag, modified);
+ }
+
+ public void cancel() {
+ httpRequestImpl.cancelRequest();
+
+ // TODO: We need a lock here because we can try
+ // to cancel at the same time the request is getting
+ // answered on the OkHTTP thread. We could get rid of
+ // this lock by using Runnable when we move Android
+ // implementation of mbgl::RunLoop to Looper.
+ lock.lock();
+ nativePtr = 0;
+ lock.unlock();
+ }
+
+ public void onResponse(int responseCode, String etag, String lastModified, String cacheControl, String expires,
+ String retryAfter, String xRateLimitReset, byte[] body) {
+ lock.lock();
+ if (nativePtr != 0) {
+ nativeOnResponse(responseCode,
+ etag,
+ lastModified,
+ cacheControl,
+ expires,
+ retryAfter,
+ xRateLimitReset,
+ body);
+ }
+ lock.unlock();
+ }
+
+ private void executeLocalRequest(String resourceUrl) {
+ new LocalRequestTask(bytes -> {
+ if (bytes != null) {
+ lock.lock();
+ if (nativePtr != 0) {
+ nativeOnResponse(200, null, null, null, null, null, null, bytes);
+ }
+ lock.unlock();
+ }
+ }).execute(resourceUrl);
+ }
+
+ public void handleFailure(int type, String errorMessage) {
+ lock.lock();
+ if (nativePtr != 0) {
+ nativeOnFailure(type, errorMessage);
+ }
+ lock.unlock();
+ }
+
+ private native void nativeOnFailure(int type, String message);
+
+ private native void nativeOnResponse(int code, String etag, String modified, String cacheControl, String expires,
+ String retryAfter, String xRateLimitReset, byte[] body);
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java
index 64b33ad5986..b80af49e7be 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java
@@ -8,7 +8,6 @@
import android.support.annotation.Nullable;
import android.support.v4.util.LongSparseArray;
import android.view.View;
-
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.annotations.Annotation;
@@ -21,12 +20,11 @@
import com.mapbox.mapboxsdk.annotations.PolygonOptions;
import com.mapbox.mapboxsdk.annotations.Polyline;
import com.mapbox.mapboxsdk.annotations.PolylineOptions;
+import com.mapbox.mapboxsdk.log.Logger;
import java.util.ArrayList;
import java.util.List;
-import timber.log.Timber;
-
/**
* Responsible for managing and tracking state of Annotations linked to Map. All events related to
* annotations that occur on {@link MapboxMap} are forwarded to this class.
@@ -40,6 +38,8 @@
*/
class AnnotationManager {
+ private final static String TAG = "AnnotationManager";
+
private static final long NO_ANNOTATION_ID = -1;
private final MapView mapView;
@@ -369,7 +369,9 @@ private boolean isAddedToMap(Annotation annotation) {
}
private void logNonAdded(Annotation annotation) {
- Timber.w("Attempting to update non-added %s with value %s", annotation.getClass().getCanonicalName(), annotation);
+ Logger.w(TAG, String.format(
+ "Attempting to update non-added %s with value %s", annotation.getClass().getCanonicalName(), annotation)
+ );
}
//
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AttributionDialogManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AttributionDialogManager.java
index 546ee628048..7cddaaa9525 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AttributionDialogManager.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AttributionDialogManager.java
@@ -11,6 +11,7 @@
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Toast;
+import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.attribution.Attribution;
import com.mapbox.mapboxsdk.attribution.AttributionParser;
@@ -97,7 +98,7 @@ private void showTelemetryDialog() {
builder.setPositiveButton(R.string.mapbox_attributionTelemetryPositive, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- Telemetry.enableOnUserRequest();
+ Mapbox.getTelemetry().enableOnUserRequest();
dialog.cancel();
}
});
@@ -111,7 +112,7 @@ public void onClick(DialogInterface dialog, int which) {
builder.setNegativeButton(R.string.mapbox_attributionTelemetryNegative, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- Telemetry.disableOnUserRequest();
+ Mapbox.getTelemetry().disableOnUserRequest();
dialog.cancel();
}
});
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java
index fc4b13a293c..1f10e023a44 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java
@@ -10,7 +10,6 @@
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.animation.DecelerateInterpolator;
-
import com.mapbox.android.gestures.AndroidGesturesManager;
import com.mapbox.android.gestures.Constants;
import com.mapbox.android.gestures.MoveGestureDetector;
@@ -19,14 +18,13 @@
import com.mapbox.android.gestures.ShoveGestureDetector;
import com.mapbox.android.gestures.StandardGestureDetector;
import com.mapbox.android.gestures.StandardScaleGestureDetector;
-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.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
+import com.mapbox.mapboxsdk.constants.TelemetryConstants;
import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.telemetry.Telemetry;
import com.mapbox.mapboxsdk.utils.MathUtils;
import java.util.ArrayList;
@@ -346,7 +344,7 @@ public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
notifyOnMapClickListeners(tapPoint);
}
- sendTelemetryEvent(Telemetry.SINGLE_TAP, new PointF(motionEvent.getX(), motionEvent.getY()));
+ sendTelemetryEvent(TelemetryConstants.SINGLE_TAP, new PointF(motionEvent.getX(), motionEvent.getY()));
return true;
}
@@ -377,7 +375,7 @@ public boolean onDoubleTapEvent(MotionEvent motionEvent) {
zoomInAnimated(zoomFocalPoint, false);
- sendTelemetryEvent(Telemetry.DOUBLE_TAP, new PointF(motionEvent.getX(), motionEvent.getY()));
+ sendTelemetryEvent(TelemetryConstants.DOUBLE_TAP, new PointF(motionEvent.getX(), motionEvent.getY()));
return true;
}
@@ -439,7 +437,7 @@ public boolean onMoveBegin(MoveGestureDetector detector) {
}
transform.cancelTransitions();
- sendTelemetryEvent(Telemetry.PAN, detector.getFocalPoint());
+ sendTelemetryEvent(TelemetryConstants.PAN, detector.getFocalPoint());
notifyOnMoveBeginListeners(detector);
return true;
}
@@ -504,7 +502,7 @@ public boolean onScaleBegin(StandardScaleGestureDetector detector) {
// setting focalPoint in #onScaleBegin() as well, because #onScale() might not get called before #onScaleEnd()
setScaleFocalPoint(detector);
- sendTelemetryEvent(Telemetry.PINCH, scaleFocalPoint);
+ sendTelemetryEvent(TelemetryConstants.PINCH, scaleFocalPoint);
notifyOnScaleBeginListeners(detector);
@@ -625,7 +623,7 @@ public boolean onRotateBegin(RotateGestureDetector detector) {
// setting in #onRotateBegin() as well, because #onRotate() might not get called before #onRotateEnd()
setRotateFocalPoint(detector);
- sendTelemetryEvent(Telemetry.ROTATION, rotateFocalPoint);
+ sendTelemetryEvent(TelemetryConstants.ROTATION, rotateFocalPoint);
notifyOnRotateBeginListeners(detector);
@@ -742,7 +740,7 @@ public boolean onShoveBegin(ShoveGestureDetector detector) {
transform.cancelTransitions();
- sendTelemetryEvent(Telemetry.PITCH, detector.getFocalPoint());
+ sendTelemetryEvent(TelemetryConstants.PITCH, detector.getFocalPoint());
// disabling move gesture during shove
gesturesManager.getMoveGestureDetector().setEnabled(false);
@@ -791,7 +789,7 @@ public boolean onMultiFingerTap(MultiFingerTapGestureDetector detector, int poin
transform.cancelTransitions();
cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE);
- sendTelemetryEvent(Telemetry.TWO_FINGER_TAP, detector.getFocalPoint());
+ sendTelemetryEvent(TelemetryConstants.TWO_FINGER_TAP, detector.getFocalPoint());
PointF zoomFocalPoint;
// Single finger double tap
@@ -883,16 +881,15 @@ private void zoomAnimated(boolean zoomIn, PointF zoomFocalPoint, boolean runImme
}
private void sendTelemetryEvent(String eventType, PointF focalPoint) {
- CameraPosition cameraPosition = transform.getCameraPosition();
- if (cameraPosition != null) {
- double zoom = cameraPosition.zoom;
- if (isZoomValid(zoom)) {
- MapboxTelemetry telemetry = Telemetry.obtainTelemetry();
- MapEventFactory mapEventFactory = new MapEventFactory();
- LatLng latLng = projection.fromScreenLocation(focalPoint);
- MapState state = new MapState(latLng.getLatitude(), latLng.getLongitude(), zoom);
- state.setGesture(eventType);
- telemetry.push(mapEventFactory.createMapGestureEvent(Event.Type.MAP_CLICK, state));
+ Telemetry telemetry = Mapbox.getTelemetry();
+ if (telemetry != null) {
+ CameraPosition cameraPosition = transform.getCameraPosition();
+ if (cameraPosition != null) {
+ double zoom = cameraPosition.zoom;
+ if (isZoomValid(zoom)) {
+ LatLng latLng = projection.fromScreenLocation(focalPoint);
+ telemetry.onGestureInteraction(eventType, latLng.getLatitude(), latLng.getLongitude(), zoom);
+ }
}
}
}
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 0fa1072cd2c..5fb682ef3b4 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
@@ -24,11 +24,7 @@
import android.widget.ImageView;
import android.widget.ZoomButtonsController;
import com.mapbox.android.gestures.AndroidGesturesManager;
-import com.mapbox.android.telemetry.AppUserTurnstile;
-import com.mapbox.android.telemetry.Event;
-import com.mapbox.android.telemetry.MapEventFactory;
-import com.mapbox.android.telemetry.MapboxTelemetry;
-import com.mapbox.mapboxsdk.BuildConfig;
+import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.annotations.Annotation;
import com.mapbox.mapboxsdk.annotations.MarkerViewManager;
@@ -44,6 +40,7 @@
import com.mapbox.mapboxsdk.offline.OfflineRegionDefinition;
import com.mapbox.mapboxsdk.offline.OfflineTilePyramidRegionDefinition;
import com.mapbox.mapboxsdk.storage.FileSource;
+import com.mapbox.mapboxsdk.telemetry.Telemetry;
import com.mapbox.mapboxsdk.utils.BitmapUtils;
import javax.microedition.khronos.egl.EGLConfig;
@@ -271,12 +268,10 @@ public void onClick(View v) {
@UiThread
public void onCreate(@Nullable Bundle savedInstanceState) {
if (savedInstanceState == null) {
- MapboxTelemetry telemetry = Telemetry.obtainTelemetry();
- 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));
+ Telemetry telemetry = Mapbox.getTelemetry();
+ if (telemetry != null) {
+ telemetry.onAppUserTurnstileEvent();
+ }
} else if (savedInstanceState.getBoolean(MapboxConstants.STATE_HAS_SAVED_STATE)) {
this.savedInstanceState = savedInstanceState;
}
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 64ad0d29b35..b58ea601df6 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
@@ -40,11 +40,11 @@
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
+import com.mapbox.mapboxsdk.log.Logger;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.mapboxsdk.style.layers.Layer;
import com.mapbox.mapboxsdk.style.light.Light;
import com.mapbox.mapboxsdk.style.sources.Source;
-import timber.log.Timber;
import java.util.HashMap;
import java.util.List;
@@ -61,6 +61,8 @@
@UiThread
public final class MapboxMap {
+ private static final String TAG = "MapboxMap";
+
private final NativeMapView nativeMapView;
private final UiSettings uiSettings;
@@ -293,7 +295,7 @@ public T getLayerAs(@NonNull String layerId) {
// noinspection unchecked
return (T) nativeMapView.getLayer(layerId);
} catch (ClassCastException exception) {
- Timber.e(exception, "Layer: %s is a different type: ", layerId);
+ Logger.e(TAG, String.format("Layer: %s is a different type: ", layerId), exception);
return null;
}
}
@@ -405,7 +407,7 @@ public T getSourceAs(@NonNull String sourceId) {
// noinspection unchecked
return (T) nativeMapView.getSource(sourceId);
} catch (ClassCastException exception) {
- Timber.e(exception, "Source: %s is a different type: ", sourceId);
+ Logger.e(TAG, String.format("Source: %s is a different type: ", sourceId), exception);
return null;
}
}
@@ -1462,7 +1464,7 @@ public void setOnPolylineClickListener(@Nullable OnPolylineClickListener listene
*/
public void selectMarker(@NonNull Marker marker) {
if (marker == null) {
- Timber.w("marker was null, so just returning");
+ Logger.w(TAG, "marker was null, so just returning");
return;
}
annotationManager.selectMarker(marker);
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 31910b206e6..ce2bf82aa73 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
@@ -23,6 +23,7 @@
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
import com.mapbox.mapboxsdk.geometry.ProjectedMeters;
+import com.mapbox.mapboxsdk.log.Logger;
import com.mapbox.mapboxsdk.maps.renderer.MapRenderer;
import com.mapbox.mapboxsdk.storage.FileSource;
import com.mapbox.mapboxsdk.style.expressions.Expression;
@@ -32,7 +33,6 @@
import com.mapbox.mapboxsdk.style.sources.CannotAddSourceException;
import com.mapbox.mapboxsdk.style.sources.Source;
import com.mapbox.mapboxsdk.utils.BitmapUtils;
-import timber.log.Timber;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@@ -45,6 +45,8 @@
// Class that wraps the native methods for convenience
final class NativeMapView {
+ private final static String TAG = "NativeMapView";
+
//Hold a reference to prevent it from being GC'd as long as it's used on the native side
private final FileSource fileSource;
@@ -109,9 +111,9 @@ private boolean checkState(String callingMethod) {
// validate if map has already been destroyed
if (destroyed && !TextUtils.isEmpty(callingMethod)) {
- Timber.e(
+ Logger.e(TAG, String.format(
"You're calling `%s` after the `MapView` was destroyed, were you invoking it after `onDestroy()`?",
- callingMethod
+ callingMethod)
);
}
return destroyed;
@@ -149,15 +151,17 @@ public void resizeView(int width, int height) {
if (width > 65535) {
// we have seen edge cases where devices return incorrect values #6111
- Timber.e("Device returned an out of range width size, "
- + "capping value at 65535 instead of %s", width);
+ Logger.e(TAG, String.format("Device returned an out of range width size, "
+ + "capping value at 65535 instead of %s", width)
+ );
width = 65535;
}
if (height > 65535) {
// we have seen edge cases where devices return incorrect values #6111
- Timber.e("Device returned an out of range height size, "
- + "capping value at 65535 instead of %s", height);
+ Logger.e(TAG, String.format("Device returned an out of range height size, "
+ + "capping value at 65535 instead of %s", height)
+ );
height = 65535;
}
@@ -899,7 +903,7 @@ protected void onMapChanged(int rawChange) {
try {
onMapChangedListener.onMapChanged(rawChange);
} catch (RuntimeException err) {
- Timber.e(err, "Exception in MapView.OnMapChangedListener");
+ Logger.e(TAG, "Exception in MapView.OnMapChangedListener", err);
}
}
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Telemetry.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Telemetry.java
deleted file mode 100644
index 10c9ce9c832..00000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Telemetry.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package com.mapbox.mapboxsdk.maps;
-
-
-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;
-
-public class Telemetry {
- static final String TWO_FINGER_TAP = "TwoFingerTap";
- static final String DOUBLE_TAP = "DoubleTap";
- static final String SINGLE_TAP = "SingleTap";
- static final String PAN = "Pan";
- static final String PINCH = "Pinch";
- static final String ROTATION = "Rotation";
- static final String PITCH = "Pitch";
- private MapboxTelemetry telemetry;
-
- private Telemetry() {
- telemetry = new MapboxTelemetry(Mapbox.getApplicationContext(), Mapbox.getAccessToken(),
- BuildConfig.MAPBOX_EVENTS_USER_AGENT);
- TelemetryEnabler.State telemetryState = TelemetryEnabler.retrieveTelemetryStateFromPreferences();
- if (TelemetryEnabler.State.ENABLED.equals(telemetryState)) {
- telemetry.enable();
- }
- }
-
- public static void initialize() {
- obtainTelemetry();
- }
-
- /**
- * Set the debug logging state of telemetry.
- *
- * @param debugLoggingEnabled true to enable logging
- */
- public static void updateDebugLoggingEnabled(boolean debugLoggingEnabled) {
- TelemetryHolder.INSTANCE.telemetry.updateDebugLoggingEnabled(debugLoggingEnabled);
- }
-
- /**
- * Update the telemetry rotation session id interval
- *
- * @param interval the selected session interval
- * @return true if rotation session id was updated
- */
- public static boolean updateSessionIdRotationInterval(SessionInterval interval) {
- return TelemetryHolder.INSTANCE.telemetry.updateSessionIdRotationInterval(interval);
- }
-
- /**
- * Method to be called when an end-user has selected to participate in telemetry collection.
- */
- public static void enableOnUserRequest() {
- TelemetryEnabler.updateTelemetryState(TelemetryEnabler.State.ENABLED);
- TelemetryHolder.INSTANCE.telemetry.enable();
- }
-
- /**
- * Method to be called when an end-user has selected to opt-out of telemetry collection.
- */
- public static void disableOnUserRequest() {
- Telemetry.obtainTelemetry().disable();
- TelemetryEnabler.updateTelemetryState(TelemetryEnabler.State.DISABLED);
- }
-
- private static class TelemetryHolder {
- private static final Telemetry INSTANCE = new Telemetry();
- }
-
- static MapboxTelemetry obtainTelemetry() {
- return TelemetryHolder.INSTANCE.telemetry;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java
index c827e5e6366..15af8f3378b 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java
@@ -5,15 +5,13 @@
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
-
import com.mapbox.mapboxsdk.annotations.MarkerViewManager;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdate;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.geometry.LatLng;
-
-import timber.log.Timber;
+import com.mapbox.mapboxsdk.log.Logger;
import static com.mapbox.mapboxsdk.maps.MapView.REGION_DID_CHANGE_ANIMATED;
import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveStartedListener;
@@ -27,6 +25,8 @@
*/
final class Transform implements MapView.OnMapChangedListener {
+ private static final String TAG = "Transform";
+
private final NativeMapView mapView;
private final MarkerViewManager markerViewManager;
private final Handler handler = new Handler();
@@ -339,7 +339,7 @@ public void onMapChanged(int change) {
void setMinZoom(double minZoom) {
if ((minZoom < MapboxConstants.MINIMUM_ZOOM) || (minZoom > MapboxConstants.MAXIMUM_ZOOM)) {
- Timber.e("Not setting minZoomPreference, value is in unsupported range: %s", minZoom);
+ Logger.e(TAG, String.format("Not setting minZoomPreference, value is in unsupported range: %s", minZoom));
return;
}
mapView.setMinZoom(minZoom);
@@ -351,7 +351,7 @@ void setMinZoom(double minZoom) {
void setMaxZoom(double maxZoom) {
if ((maxZoom < MapboxConstants.MINIMUM_ZOOM) || (maxZoom > MapboxConstants.MAXIMUM_ZOOM)) {
- Timber.e("Not setting maxZoomPreference, value is in unsupported range: %s", maxZoom);
+ Logger.e(TAG, String.format("Not setting maxZoomPreference, value is in unsupported range: %s", maxZoom));
return;
}
mapView.setMaxZoom(maxZoom);
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/egl/EGLConfigChooser.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/egl/EGLConfigChooser.java
index 46238ee7890..de759952788 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/egl/EGLConfigChooser.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/egl/EGLConfigChooser.java
@@ -3,16 +3,15 @@
import android.opengl.GLSurfaceView;
import android.os.Build;
import android.support.annotation.NonNull;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
+import com.mapbox.mapboxsdk.log.Logger;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLDisplay;
-
-import timber.log.Timber;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import static com.mapbox.mapboxsdk.utils.Compare.compare;
import static javax.microedition.khronos.egl.EGL10.EGL_ALPHA_MASK_SIZE;
@@ -38,6 +37,8 @@
*/
public class EGLConfigChooser implements GLSurfaceView.EGLConfigChooser {
+ private static final String TAG = "EGLConfigChooser";
+
/**
* Requires API level 17
*
@@ -72,7 +73,7 @@ public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
// Determine number of possible configurations
int[] numConfigs = getNumberOfConfigurations(egl, display, configAttribs);
if (numConfigs[0] < 1) {
- Timber.e("eglChooseConfig() returned no configs.");
+ Logger.e(TAG, "eglChooseConfig() returned no configs.");
throw new EGLConfigException("eglChooseConfig() failed");
}
@@ -82,7 +83,7 @@ public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
// Choose best match
EGLConfig config = chooseBestMatchConfig(egl, display, possibleConfigurations);
if (config == null) {
- Timber.e("No config chosen");
+ Logger.e(TAG, "No config chosen");
throw new EGLConfigException("No config chosen");
}
@@ -92,7 +93,9 @@ public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
private int[] getNumberOfConfigurations(EGL10 egl, EGLDisplay display, int[] configAttributes) {
int[] numConfigs = new int[1];
if (!egl.eglChooseConfig(display, configAttributes, null, 0, numConfigs)) {
- Timber.e("eglChooseConfig(NULL) returned error %d", egl.eglGetError());
+ Logger.e(TAG, String.format(
+ MapboxConstants.MAPBOX_LOCALE, "eglChooseConfig(NULL) returned error %d", egl.eglGetError())
+ );
throw new EGLConfigException("eglChooseConfig() failed");
}
return numConfigs;
@@ -102,7 +105,9 @@ private EGLConfig[] getPossibleConfigurations(EGL10 egl, EGLDisplay display,
int[] configAttributes, int[] numConfigs) {
EGLConfig[] configs = new EGLConfig[numConfigs[0]];
if (!egl.eglChooseConfig(display, configAttributes, configs, numConfigs[0], numConfigs)) {
- Timber.e("eglChooseConfig() returned error %d", egl.eglGetError());
+ Logger.e(TAG, String.format(
+ MapboxConstants.MAPBOX_LOCALE, "eglChooseConfig() returned error %d", egl.eglGetError())
+ );
throw new EGLConfigException("eglChooseConfig() failed");
}
return configs;
@@ -254,11 +259,11 @@ public int compareTo(@NonNull Config other) {
Config bestMatch = matches.get(0);
if (bestMatch.isCaveat) {
- Timber.w("Chosen config has a caveat.");
+ Logger.w(TAG, "Chosen config has a caveat.");
}
if (bestMatch.isNotConformant) {
- Timber.w("Chosen config is not conformant.");
+ Logger.w(TAG, "Chosen config is not conformant.");
}
return bestMatch.config;
@@ -267,7 +272,9 @@ public int compareTo(@NonNull Config other) {
private int getConfigAttr(EGL10 egl, EGLDisplay display, EGLConfig config, int attributeName) {
int[] attributevalue = new int[1];
if (!egl.eglGetConfigAttrib(display, config, attributeName, attributevalue)) {
- Timber.e("eglGetConfigAttrib(%d) returned error %d", attributeName, egl.eglGetError());
+ Logger.e(TAG, String.format(
+ MapboxConstants.MAPBOX_LOCALE, "eglGetConfigAttrib(%d) returned error %d", attributeName, egl.eglGetError())
+ );
throw new EGLConfigException("eglGetConfigAttrib() failed");
}
return attributevalue[0];
@@ -275,7 +282,7 @@ private int getConfigAttr(EGL10 egl, EGLDisplay display, EGLConfig config, int a
private int[] getConfigAttributes() {
boolean emulator = inEmulator() || inGenymotion();
- Timber.i("In emulator: %s", emulator);
+ Logger.i(TAG, String.format("In emulator: %s", emulator));
// Get all configs at least RGB 565 with 16 depth and 8 stencil
return new int[] {
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/textureview/TextureViewRenderThread.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/textureview/TextureViewRenderThread.java
index 4bba160993d..0c7c16bad2f 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/textureview/TextureViewRenderThread.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/textureview/TextureViewRenderThread.java
@@ -4,11 +4,9 @@
import android.support.annotation.NonNull;
import android.support.annotation.UiThread;
import android.view.TextureView;
+import com.mapbox.mapboxsdk.log.Logger;
import com.mapbox.mapboxsdk.maps.renderer.egl.EGLConfigChooser;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGL11;
import javax.microedition.khronos.egl.EGLConfig;
@@ -16,8 +14,8 @@
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;
import javax.microedition.khronos.opengles.GL10;
-
-import timber.log.Timber;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
/**
* The render thread is responsible for managing the communication between the
@@ -26,6 +24,8 @@
*/
class TextureViewRenderThread extends Thread implements TextureView.SurfaceTextureListener {
+ private static final String TAG = "TextureViewRenderThread";
+
private final TextureViewMapRenderer mapRenderer;
private final EGLHolder eglHolder;
@@ -286,7 +286,7 @@ public void run() {
case EGL10.EGL_SUCCESS:
break;
case EGL11.EGL_CONTEXT_LOST:
- Timber.w("Context lost. Waiting for re-aquire");
+ Logger.w(TAG, "Context lost. Waiting for re-aquire");
synchronized (lock) {
surface = null;
destroySurface = true;
@@ -294,7 +294,7 @@ public void run() {
}
break;
default:
- Timber.w("eglSwapBuffer error: %s. Waiting or new surface", swapError);
+ Logger.w(TAG, String.format("eglSwapBuffer error: %s. Waiting or new surface", swapError));
// Probably lost the surface. Clear the current one and
// wait for a new one to be set
synchronized (lock) {
@@ -390,7 +390,7 @@ boolean createSurface() {
if (eglSurface == null || eglSurface == EGL10.EGL_NO_SURFACE) {
int error = egl.eglGetError();
if (error == EGL10.EGL_BAD_NATIVE_WINDOW) {
- Timber.e("createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
+ Logger.e(TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
}
return false;
}
@@ -402,7 +402,7 @@ boolean makeCurrent() {
if (!egl.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) {
// Could not make the context current, probably because the underlying
// SurfaceView surface has been destroyed.
- Timber.w("eglMakeCurrent: %s", egl.eglGetError());
+ Logger.w(TAG, String.format("eglMakeCurrent: %s", egl.eglGetError()));
return false;
}
@@ -422,7 +422,7 @@ private void destroySurface() {
}
if (!egl.eglDestroySurface(eglDisplay, eglSurface)) {
- Timber.w("Could not destroy egl surface. Display %s, Surface %s", eglDisplay, eglSurface);
+ Logger.w(TAG, String.format("Could not destroy egl surface. Display %s, Surface %s", eglDisplay, eglSurface));
}
eglSurface = EGL10.EGL_NO_SURFACE;
@@ -434,7 +434,7 @@ private void destroyContext() {
}
if (!egl.eglDestroyContext(eglDisplay, eglContext)) {
- Timber.w("Could not destroy egl context. Display %s, Context %s", eglDisplay, eglContext);
+ Logger.w(TAG, String.format("Could not destroy egl context. Display %s, Context %s", eglDisplay, eglContext));
}
eglContext = EGL10.EGL_NO_CONTEXT;
@@ -446,7 +446,7 @@ private void terminate() {
}
if (!egl.eglTerminate(eglDisplay)) {
- Timber.w("Could not terminate egl. Display %s", eglDisplay);
+ Logger.w(TAG, String.format("Could not terminate egl. Display %s", eglDisplay));
}
eglDisplay = EGL10.EGL_NO_DISPLAY;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityReceiver.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityReceiver.java
index 817dcdb4384..cb904b13c97 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityReceiver.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityReceiver.java
@@ -9,19 +9,20 @@
import android.net.NetworkInfo;
import android.support.annotation.NonNull;
import android.support.annotation.UiThread;
-
import com.mapbox.mapboxsdk.Mapbox;
+import com.mapbox.mapboxsdk.log.Logger;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
-import timber.log.Timber;
-
/**
* Interface definition for a callback to be invoked when connectivity changes.
* Not public api.
*/
public class ConnectivityReceiver extends BroadcastReceiver {
+
+ private static final String TAG = "ConnectivityReceiver";
+
@SuppressLint("StaticFieldLeak")
private static ConnectivityReceiver INSTANCE;
@@ -84,7 +85,7 @@ public void deactivate() {
@Override
public void onReceive(Context context, Intent intent) {
boolean connected = isConnected(context);
- Timber.v("Connected: %s", connected);
+ Logger.v(TAG, String.format("Connected: %s", connected));
// Loop over listeners
for (ConnectivityListener listener : listeners) {
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 f2faabd63b1..3a8e03116e6 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
@@ -5,23 +5,23 @@
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
-
import com.mapbox.mapboxsdk.LibraryLoader;
import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
+import com.mapbox.mapboxsdk.log.Logger;
import com.mapbox.mapboxsdk.net.ConnectivityReceiver;
import com.mapbox.mapboxsdk.storage.FileSource;
import java.io.File;
-import timber.log.Timber;
-
/**
* The offline manager is the main entry point for offline-related functionality.
* It'll help you list and create offline regions.
*/
public class OfflineManager {
+ private final static String TAG = "OfflineManager";
+
//
// Static methods
//
@@ -109,10 +109,10 @@ public void run() {
File file = new File(path);
if (file.exists()) {
file.delete();
- Timber.d("Old ambient cache database deleted to save space: %s", path);
+ Logger.d(TAG, String.format("Old ambient cache database deleted to save space: %s", path));
}
} catch (Exception exception) {
- Timber.e(exception, "Failed to delete old ambient cache database: ");
+ Logger.e(TAG, "Failed to delete old ambient cache database: ", exception);
}
}
}).start();
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java
index a2c7ed5dfd9..b20feeea3f9 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java
@@ -23,9 +23,9 @@
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
+import com.mapbox.mapboxsdk.log.Logger;
import com.mapbox.mapboxsdk.storage.FileSource;
import com.mapbox.mapboxsdk.utils.ThreadUtils;
-import timber.log.Timber;
/**
* The map snapshotter creates a large of the map, rendered
@@ -35,6 +35,8 @@
@UiThread
public class MapSnapshotter {
+ private static final String TAG = "MapSnapshotter";
+
/**
* Get notified on snapshot completion.
*
@@ -350,9 +352,10 @@ private void drawAttribution(MapSnapshot mapSnapshot, Canvas canvas,
drawAttribution(canvas, measure, anchorPoint);
} else {
Bitmap snapshot = mapSnapshot.getBitmap();
- Timber.e("Could not generate attribution for snapshot size: %s x %s."
+ Logger.e(TAG, String.format("Could not generate attribution for snapshot size: %s x %s."
+ " You are required to provide your own attribution for the used sources: %s",
- snapshot.getWidth(), snapshot.getHeight(), mapSnapshot.getAttributions());
+ snapshot.getWidth(), snapshot.getHeight(), mapSnapshot.getAttributions())
+ );
}
}
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 929e4b42797..6f18623f919 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
@@ -7,10 +7,9 @@
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.annotation.UiThread;
-
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
-import timber.log.Timber;
+import com.mapbox.mapboxsdk.log.Logger;
/**
* Holds a central reference to the core's DefaultFileSource for as long as
@@ -18,6 +17,8 @@
*/
public class FileSource {
+ private static final String TAG = "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
@@ -73,9 +74,9 @@ public static String getCachePath(Context context) {
MapboxConstants.KEY_META_DATA_SET_STORAGE_EXTERNAL,
MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL);
} catch (PackageManager.NameNotFoundException exception) {
- Timber.e(exception, "Failed to read the package metadata: ");
+ Logger.e(TAG, "Failed to read the package metadata: ", exception);
} catch (Exception exception) {
- Timber.e(exception, "Failed to read the storage key: ");
+ Logger.e(TAG, "Failed to read the storage key: ", exception);
}
String cachePath = null;
@@ -84,7 +85,7 @@ public static String getCachePath(Context context) {
// Try getting the external storage path
cachePath = context.getExternalFilesDir(null).getAbsolutePath();
} catch (NullPointerException exception) {
- Timber.e(exception, "Failed to obtain the external storage path: ");
+ Logger.e(TAG, "Failed to obtain the external storage path: ", exception);
}
}
@@ -112,7 +113,7 @@ public static boolean isExternalStorageReadable() {
return true;
}
- Timber.w("External storage was requested but it isn't readable. For API level < 18"
+ Logger.w(TAG, "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).");
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java
index fa1779a6c75..44e33fcd873 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java
@@ -3,19 +3,19 @@
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-
import com.google.gson.JsonArray;
import com.mapbox.mapboxsdk.exceptions.ConversionException;
+import com.mapbox.mapboxsdk.log.Logger;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.mapboxsdk.utils.ColorUtils;
-import timber.log.Timber;
-
/**
* Properties for Layer
*/
public class PropertyValue {
+ private static final String TAG = "PropertyValue";
+
public final String name;
public final T value;
@@ -59,7 +59,7 @@ public Expression getExpression() {
if (isExpression()) {
return Expression.Converter.convert((JsonArray) value);
} else {
- Timber.w("not a expression, try value");
+ Logger.w(TAG, "not a expression, try value");
return null;
}
}
@@ -84,7 +84,7 @@ public T getValue() {
// noinspection unchecked
return value;
} else {
- Timber.w("not a value, try function");
+ Logger.w(TAG, "not a value, try function");
return null;
}
}
@@ -98,14 +98,14 @@ public T getValue() {
@Nullable
public Integer getColorInt() {
if (!isValue() || !(value instanceof String)) {
- Timber.e("%s is not a String value and can not be converted to a color it", name);
+ Logger.e(TAG, String.format("%s is not a String value and can not be converted to a color it", name));
return null;
}
try {
return ColorUtils.rgbaToColor((String) value);
} catch (ConversionException ex) {
- Timber.e("%s could not be converted to a Color int: %s", name, ex.getMessage());
+ Logger.e(TAG, String.format("%s could not be converted to a Color int: %s", name, ex.getMessage()));
return null;
}
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
index d21eb73382d..50660a8c527 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
+++ b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
@@ -54,10 +54,17 @@ android {
dependencies {
implementation dependenciesList.kotlinLib
- api(project(':MapboxGLAndroidSDK'))
- implementation dependenciesList.mapboxJavaServices
- implementation dependenciesList.mapboxJavaTurf
+ implementation(project(':MapboxGLAndroidSDK')) {
+ exclude module: 'MapboxGLAndroidModuleHttp'
+ }
+
+ implementation(dependenciesList.mapboxJavaTurf) {
+ exclude group: 'com.squareup.okhttp3', module: 'okhttp'
+ exclude group: 'com.squareup.okhttp3', module: 'logging-interceptor'
+ }
+
+ implementation 'com.koushikdutta.ion:ion:2.2.1'
implementation dependenciesList.supportAppcompatV7
implementation dependenciesList.supportRecyclerView
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/http/HttpRequestImpl.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/http/HttpRequestImpl.java
new file mode 100644
index 00000000000..1653e1394e1
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/http/HttpRequestImpl.java
@@ -0,0 +1,39 @@
+package com.mapbox.mapboxsdk.http;
+
+import com.koushikdutta.async.future.Future;
+import com.koushikdutta.ion.Ion;
+import com.koushikdutta.ion.Response;
+import com.koushikdutta.ion.builder.Builders;
+import com.mapbox.mapboxsdk.Mapbox;
+
+import java.util.concurrent.ExecutionException;
+
+public class HttpRequestImpl extends HttpRequest {
+
+ @Override
+ public void executeRequest(HttpRequestResponder httpRequest, long nativePtr, String resourceUrl,
+ String etag, String modified) {
+ Builders.Any.B loadBuilder = Ion.with(Mapbox.getApplicationContext()).load(resourceUrl);
+ if (etag.length() > 0) {
+ loadBuilder.addHeader("If-None-Match", etag);
+ } else if (modified.length() > 0) {
+ loadBuilder.addHeader("If-Modified-Since", modified);
+ }
+ Future> future = loadBuilder.asByteArray().withResponse();
+ try {
+ Response result = future.get();
+ int statusCode = result.getHeaders().code();
+ httpRequest.onResponse(statusCode, null, null, null, null, null, null, result.getResult());
+ } catch (InterruptedException interruptedException) {
+ interruptedException.printStackTrace();
+ } catch (ExecutionException executionException) {
+ executionException.printStackTrace();
+ }
+ }
+
+ @Override
+ public void cancelRequest() {
+ // do nothing
+ // TODO manage Future objects and execute Future#cancel
+ }
+}
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 a06a4893887..2060d576750 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
@@ -3,10 +3,11 @@
import android.app.Application;
import android.os.StrictMode;
import android.text.TextUtils;
+
import com.mapbox.mapboxsdk.Mapbox;
-import com.mapbox.mapboxsdk.maps.Telemetry;
import com.mapbox.mapboxsdk.testapp.utils.TokenUtils;
import com.squareup.leakcanary.LeakCanary;
+
import timber.log.Timber;
import static timber.log.Timber.DebugTree;
@@ -70,7 +71,7 @@ private void initializeMapbox() {
String accessToken = TokenUtils.getMapboxAccessToken(getApplicationContext());
validateAccessToken(accessToken);
Mapbox.getInstance(getApplicationContext(), accessToken);
- Telemetry.updateDebugLoggingEnabled(true);
+ //TelemetryBase.updateDebugLoggingEnabled(true);
}
private static void validateAccessToken(String accessToken) {
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java
index ac4c6ff9df7..686f564c5c0 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java
@@ -10,7 +10,6 @@
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
-import com.mapbox.mapboxsdk.http.HttpRequestUtil;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.testapp.R;
@@ -52,7 +51,6 @@ public class LatLngBoundsActivity extends AppCompatActivity implements View.OnCl
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- HttpRequestUtil.setLogEnabled(false);
setContentView(R.layout.activity_latlngbounds);
mapView = (MapView) findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
@@ -151,7 +149,6 @@ public void onLowMemory() {
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
- HttpRequestUtil.setLogEnabled(true);
}
@Override
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DebugModeActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DebugModeActivity.java
index 44d27a41abd..22da952560c 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DebugModeActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DebugModeActivity.java
@@ -16,7 +16,6 @@
import android.widget.TextView;
import com.mapbox.mapboxsdk.constants.Style;
-import com.mapbox.mapboxsdk.http.HttpRequestUtil;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
@@ -55,7 +54,6 @@ public class DebugModeActivity extends AppCompatActivity implements OnMapReadyCa
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- HttpRequestUtil.setPrintRequestUrlOnFailure(true);
setContentView(R.layout.activity_debug_mode);
setupToolbar();
setupMapView(savedInstanceState);
@@ -206,7 +204,6 @@ protected void onSaveInstanceState(Bundle outState) {
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
- HttpRequestUtil.setPrintRequestUrlOnFailure(false);
}
@Override
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java
index 79e76168d5c..4604d20b8a7 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java
@@ -70,7 +70,7 @@ protected void onCreate(Bundle savedInstanceState) {
// You can use Mapbox.setConnected(Boolean) to manually set the connectivity
// state of your app. This will override any checks performed via the ConnectivityManager.
- // Mapbox.getInstance().setConnected(false);
+ // Mapbox.initialize().setConnected(false);
Boolean connected = Mapbox.isConnected();
Timber.d("Mapbox is connected: %s", connected);
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/render/RenderTestActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/render/RenderTestActivity.java
index e3c5254805a..6c37f3d5ea4 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/render/RenderTestActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/render/RenderTestActivity.java
@@ -12,11 +12,8 @@
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.google.gson.Gson;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
import com.mapbox.mapboxsdk.snapshotter.MapSnapshotter;
-import okio.BufferedSource;
-import okio.Okio;
+
import timber.log.Timber;
import java.io.File;
@@ -24,7 +21,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
-import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -167,13 +163,13 @@ protected void onPostExecute(List renderTestDefinitions) {
private static List loadIgnoreList(AssetManager assets) {
List ignores = new ArrayList<>();
try (InputStream input = assets.open(String.format("%s/ignores.json", TEST_BASE_PATH))) {
- BufferedSource source = Okio.buffer(Okio.source(input));
- String styleJson = source.readByteString().string(Charset.forName("utf-8"));
- JsonObject object = new Gson().fromJson(styleJson, JsonObject.class);
- for (Map.Entry stringJsonElementEntry : object.entrySet()) {
- String[] parts = stringJsonElementEntry.getKey().split("/");
- ignores.add(String.format("%s,%s", parts[2], parts[1]));
- }
+ // BufferedSource source = Okio.buffer(Okio.source(input));
+ // String styleJson = source.readByteString().string(Charset.forName("utf-8"));
+ // JsonObject object = new Gson().fromJson(styleJson, JsonObject.class);
+ // for (Map.Entry stringJsonElementEntry : object.entrySet()) {
+ // String[] parts = stringJsonElementEntry.getKey().split("/");
+ // ignores.add(String.format("%s,%s", parts[2], parts[1]));
+ // }
} catch (IOException exception) {
Timber.e(exception);
}
@@ -183,8 +179,8 @@ private static List loadIgnoreList(AssetManager assets) {
private static String loadStyleJson(AssetManager assets, String category, String test) {
String styleJson = null;
try (InputStream input = assets.open(String.format("%s/%s/%s/style.json", RENDER_TEST_BASE_PATH, category, test))) {
- BufferedSource source = Okio.buffer(Okio.source(input));
- styleJson = source.readByteString().string(Charset.forName("utf-8"));
+ // BufferedSource source = Okio.buffer(Okio.source(input));
+ // styleJson = source.readByteString().string(Charset.forName("utf-8"));
} catch (IOException exception) {
Timber.e(exception);
}
diff --git a/platform/android/config.cmake b/platform/android/config.cmake
index 21ec6a9e0ca..cfa1ef54267 100644
--- a/platform/android/config.cmake
+++ b/platform/android/config.cmake
@@ -73,6 +73,10 @@ macro(mbgl_platform_core)
PRIVATE platform/default/mbgl/map/map_snapshotter.cpp
PRIVATE platform/default/mbgl/map/map_snapshotter.hpp
PRIVATE platform/linux/src/headless_backend_egl.cpp
+
+ # Logger
+ PRIVATE platform/android/src/logger.cpp
+ PRIVATE platform/android/src/logger.hpp
)
target_include_directories(mbgl-core
diff --git a/platform/android/MapboxGLAndroidSDK/gradle.properties b/platform/android/gradle.properties
similarity index 100%
rename from platform/android/MapboxGLAndroidSDK/gradle.properties
rename to platform/android/gradle.properties
diff --git a/platform/android/gradle/dependencies.gradle b/platform/android/gradle/dependencies.gradle
index fccaea9f719..01b92fe1c64 100644
--- a/platform/android/gradle/dependencies.gradle
+++ b/platform/android/gradle/dependencies.gradle
@@ -46,6 +46,7 @@ ext {
supportAnnotations : "com.android.support:support-annotations:${versions.supportLib}",
supportAppcompatV7 : "com.android.support:appcompat-v7:${versions.supportLib}",
supportFragmentV4 : "com.android.support:support-fragment:${versions.supportLib}",
+ supportUtilV4 : "com.android.support:support-core-utils:${versions.supportLib}",
supportDesign : "com.android.support:design:${versions.supportLib}",
supportRecyclerView : "com.android.support:recyclerview-v7:${versions.supportLib}",
diff --git a/platform/android/gradle/gradle-checkstyle.gradle b/platform/android/gradle/gradle-checkstyle.gradle
index 41a68f90ce3..8eb4baa858d 100644
--- a/platform/android/gradle/gradle-checkstyle.gradle
+++ b/platform/android/gradle/gradle-checkstyle.gradle
@@ -18,7 +18,9 @@ task checkstyle(type: Checkstyle) {
exclude '**/style/layers/PropertyFactory.java'
exclude '**/style/layers/*Layer.java'
exclude '**/style/light/Light.java'
- exclude '**/Expression.java' // allowing single character signature as e()
+ exclude '**/log/LoggerDefinition.java'
+ exclude '**/log/Logger.java'
+ exclude '**/Expression.java'
classpath = files()
ignoreFailures = false
}
diff --git a/platform/android/settings.gradle b/platform/android/settings.gradle
index b5ab80b5ec3..44b0ab27c84 100644
--- a/platform/android/settings.gradle
+++ b/platform/android/settings.gradle
@@ -1 +1 @@
-include ':MapboxGLAndroidSDK', ':MapboxGLAndroidSDKTestApp'
\ No newline at end of file
+include ':MapboxGLAndroidSDK', ':MapboxGLAndroidSDKTestApp', ':MapboxGLAndroidModuleBase', ':MapboxGLAndroidModuleHttp', ':MapboxGLAndroidModuleTelemetry'
\ No newline at end of file
diff --git a/platform/android/src/http_file_source.cpp b/platform/android/src/http_file_source.cpp
index cda84209ea3..fc7ffbec8c1 100644
--- a/platform/android/src/http_file_source.cpp
+++ b/platform/android/src/http_file_source.cpp
@@ -20,7 +20,7 @@ class HTTPFileSource::Impl {
class HTTPRequest : public AsyncRequest {
public:
- static constexpr auto Name() { return "com/mapbox/mapboxsdk/http/HTTPRequest"; };
+ static constexpr auto Name() { return "com/mapbox/mapboxsdk/http/NativeHttpRequest"; };
HTTPRequest(jni::JNIEnv&, const Resource&, FileSource::Callback);
~HTTPRequest();
diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp
index beb2c14eb3e..f1d693ea109 100755
--- a/platform/android/src/jni.cpp
+++ b/platform/android/src/jni.cpp
@@ -49,6 +49,7 @@
#include "text/collator_jni.hpp"
#include "text/local_glyph_rasterizer_jni.hpp"
#include "java/lang.hpp"
+#include "logger.hpp"
namespace mbgl {
namespace android {
@@ -191,6 +192,9 @@ void registerNatives(JavaVM *vm) {
LocalGlyphRasterizer::registerNative(env);
Locale::registerNative(env);
Collator::registerNative(env);
+
+ // Logger
+ Logger::registerNative(env);
}
} // namespace android
diff --git a/platform/android/src/logger.cpp b/platform/android/src/logger.cpp
new file mode 100644
index 00000000000..18a390b3e61
--- /dev/null
+++ b/platform/android/src/logger.cpp
@@ -0,0 +1,34 @@
+#include "logger.hpp"
+#include "java_types.hpp"
+
+namespace mbgl {
+namespace android {
+
+void Logger::registerNative(jni::JNIEnv& env) {
+ _class = *jni::Class::Find(env).NewGlobalRef(env).release();
+}
+
+jni::Class Logger::_class;
+
+void Logger::log(jni::JNIEnv& env, EventSeverity severity, const std::string &msg) {
+ auto tag = jni::Make(env, "MBGL");
+ auto message = jni::Make(env, msg);
+ using Signature = void(jni::String, jni::String);
+
+ if(severity == EventSeverity::Debug){
+ auto method = _class.GetStaticMethod(env, "d");
+ _class.Call(env, method, tag, message);
+ }else if(severity == EventSeverity::Info){
+ auto method = _class.GetStaticMethod(env, "i");
+ _class.Call(env, method, tag, message);
+ }else if(severity == EventSeverity::Warning){
+ auto method = _class.GetStaticMethod(env, "w");
+ _class.Call(env, method, tag, message);
+ }else{
+ auto method = _class.GetStaticMethod(env, "e");
+ _class.Call(env, method, tag, message);
+ }
+}
+
+} // namespace android
+} // namespace mbgl
\ No newline at end of file
diff --git a/platform/android/src/logger.hpp b/platform/android/src/logger.hpp
new file mode 100644
index 00000000000..d4805fccd8c
--- /dev/null
+++ b/platform/android/src/logger.hpp
@@ -0,0 +1,24 @@
+#pragma once
+
+#include
+#include
+#include "bitmap.hpp"
+
+namespace mbgl {
+namespace android {
+
+class Logger {
+public:
+ static constexpr auto Name() {
+ return "com/mapbox/mapboxsdk/log/Logger";
+ };
+ static void registerNative(jni::JNIEnv&);
+
+ static void log(jni::JNIEnv&, EventSeverity severity, const std::string &msg);
+
+private:
+ static jni::Class _class;
+};
+
+} // namespace android
+} // namespace mbgl
\ No newline at end of file
diff --git a/platform/android/src/logging_android.cpp b/platform/android/src/logging_android.cpp
index 2e025c059fb..1301367280c 100644
--- a/platform/android/src/logging_android.cpp
+++ b/platform/android/src/logging_android.cpp
@@ -1,34 +1,13 @@
#include
-#include
+#include "logger.hpp"
+#include "attach_env.hpp"
namespace mbgl {
-namespace {
-
-int severityToPriority(EventSeverity severity) {
- switch(severity) {
- case EventSeverity::Debug:
- return ANDROID_LOG_DEBUG;
-
- case EventSeverity::Info:
- return ANDROID_LOG_INFO;
-
- case EventSeverity::Warning:
- return ANDROID_LOG_WARN;
-
- case EventSeverity::Error:
- return ANDROID_LOG_ERROR;
-
- default:
- return ANDROID_LOG_VERBOSE;
- }
-}
-
-} // namespace
-
void Log::platformRecord(EventSeverity severity, const std::string &msg) {
- __android_log_print(severityToPriority(severity), "mbgl", "%s", msg.c_str());
+ auto env{ android::AttachEnv() };
+ android::Logger::log(*env, severity, msg);
}
-}
+}
\ No newline at end of file