summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOsana Babayan <32496536+osana@users.noreply.github.com>2019-04-18 11:40:58 -0400
committerGitHub <noreply@github.com>2019-04-18 11:40:58 -0400
commitec8cf0ce8b56086c990fdf0c95b7a11d159481f4 (patch)
tree19e0b352feec2a980c0391a6eccda561f6ea3397
parent8bbd38093ce8ec703c26fbeac4c7fb7c8d208934 (diff)
downloadqtlocation-mapboxgl-ec8cf0ce8b56086c990fdf0c95b7a11d159481f4.tar.gz
[android] Measure TileLoading performance (elapsedMS & responseCode) (#14420)
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java10
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml6
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxApplication.java3
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/TileLoadingMeasurementUtils.java168
4 files changed, 187 insertions, 0 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java
index 73c8201454..2b69646fcc 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java
@@ -23,6 +23,16 @@ public class MapboxConstants {
public static final boolean DEFAULT_SET_STORAGE_EXTERNAL = false;
/**
+ * Key used to switch Tile Download Measuring on/off in AndroidManifest.xml
+ */
+ public static final String KEY_META_DATA_MEASURE_TILE_DOWNLOAD_ON = "com.mapbox.MeasureTileDownloadOn";
+
+ /**
+ * Default value for KEY_META_DATA_MEASURE_TILE_DOWNLOAD_ON (default is off)
+ */
+ public static final boolean DEFAULT_MEASURE_TILE_DOWNLOAD_ON = false;
+
+ /**
* Unmeasured state
*/
public static final float UNMEASURED = -1f;
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
index 326acabdb3..53f6076a60 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
@@ -985,6 +985,12 @@
<!-- <meta-data -->
<!-- android:name="com.mapbox.SetStorageExternal" -->
<!-- android:value="true" /> -->
+
+ <!-- Set value to true to have tile loading measurements on -->
+ <meta-data
+ android:name="com.mapbox.MeasureTileDownloadOn"
+ android:value="false" />
+
</application>
</manifest> \ No newline at end of file
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 d5cff301db..71762c1e5f 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
@@ -8,9 +8,11 @@ import com.mapbox.mapboxsdk.MapStrictMode;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.log.Logger;
import com.mapbox.mapboxsdk.maps.TelemetryDefinition;
+import com.mapbox.mapboxsdk.testapp.utils.TileLoadingMeasurementUtils;
import com.mapbox.mapboxsdk.testapp.utils.TimberLogger;
import com.mapbox.mapboxsdk.testapp.utils.TokenUtils;
import com.squareup.leakcanary.LeakCanary;
+
import timber.log.Timber;
import static timber.log.Timber.DebugTree;
@@ -80,6 +82,7 @@ public class MapboxApplication extends Application {
throw new IllegalStateException("Telemetry was unavailable during test application start.");
}
telemetry.setDebugLoggingEnabled(true);
+ TileLoadingMeasurementUtils.setUpTileLoadingMeasurement();
MapStrictMode.setStrictModeEnabled(true);
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/TileLoadingMeasurementUtils.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/TileLoadingMeasurementUtils.java
new file mode 100644
index 0000000000..3247f30839
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/TileLoadingMeasurementUtils.java
@@ -0,0 +1,168 @@
+package com.mapbox.mapboxsdk.testapp.utils;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.WindowManager;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import com.mapbox.mapboxsdk.MapStrictMode;
+import com.mapbox.mapboxsdk.Mapbox;
+import com.mapbox.mapboxsdk.module.http.HttpRequestUtil;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+import okhttp3.Interceptor;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import timber.log.Timber;
+
+import static com.mapbox.mapboxsdk.constants.MapboxConstants.DEFAULT_MEASURE_TILE_DOWNLOAD_ON;
+import static com.mapbox.mapboxsdk.constants.MapboxConstants.KEY_META_DATA_MEASURE_TILE_DOWNLOAD_ON;
+
+public class TileLoadingMeasurementUtils {
+
+ private static final String ATTRIBUTE_REQUEST_URL = "requestUrl";
+
+
+ public static void setUpTileLoadingMeasurement() {
+ if (isTileLoadingMeasurementOn()) {
+ OkHttpClient okHttpClient = new OkHttpClient.Builder()
+ .addNetworkInterceptor(new TileLoadingInterceptor())
+ .build();
+ HttpRequestUtil.setOkHttpClient(okHttpClient);
+ }
+ }
+
+ private static boolean isTileLoadingMeasurementOn() {
+ return isBooleanMetaDataValueOn(KEY_META_DATA_MEASURE_TILE_DOWNLOAD_ON,
+ DEFAULT_MEASURE_TILE_DOWNLOAD_ON);
+ }
+
+ private static boolean isBooleanMetaDataValueOn(@NonNull String propKey, boolean defaultValue) {
+
+ try {
+ // Try getting a custom value from the app Manifest
+ Context context = Mapbox.getApplicationContext();
+ ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(),
+ PackageManager.GET_META_DATA);
+ if (appInfo.metaData != null) {
+ return appInfo.metaData.getBoolean(propKey, defaultValue);
+ }
+ } catch (PackageManager.NameNotFoundException exception) {
+ Timber.e("Failed to read the package metadata: " + exception);
+ MapStrictMode.strictModeViolation(exception);
+ } catch (Exception exception) {
+ Timber.e("Failed to read key: " + propKey + " " + exception);
+ MapStrictMode.strictModeViolation(exception);
+ }
+ return defaultValue;
+ }
+
+
+ /**
+ * This Interceptor allows to measure time spent getting a response object over network.
+ * The following data will be collected:
+ * responseCode, elapsedMS
+ * requestUrl (request string till the question mark),
+ * and device metadata.
+ */
+ static class TileLoadingInterceptor implements Interceptor {
+
+ private static String metadata = null;
+
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Request request = chain.request();
+ long elapsed = System.nanoTime();
+
+ Response response = chain.proceed(request);
+ elapsed = System.nanoTime() - elapsed;
+
+ triggerPerformanceEvent(response, elapsed / 1000000);
+
+ return response;
+ }
+
+ private void triggerPerformanceEvent(Response response, long elapsedMs) {
+ List<Attribute<String>> attributes = new ArrayList<>();
+ String request = getUrl(response.request());
+ attributes.add(new Attribute<>("requestUrl", request));
+ attributes.add(new Attribute<>("responseCode", String.valueOf(response.code())));
+
+ List<Attribute<Long>> counters = new ArrayList();
+ counters.add(new Attribute<>("elapsedMS", elapsedMs));
+
+ Bundle bundle = new Bundle();
+ Gson gson = new Gson();
+ bundle.putString("attributes", gson.toJson(attributes));
+ bundle.putString("counters", gson.toJson(counters));
+ bundle.putString("metadata", getMetadata());
+
+ Mapbox.getTelemetry().onPerformanceEvent(bundle);
+ }
+
+ private static String getUrl(Request request) {
+ String url = request.url().toString();
+ return url.substring(0, url.indexOf('?'));
+ }
+
+ private static String getMetadata() {
+ if (metadata == null) {
+ JsonObject metaData = new JsonObject();
+ metaData.addProperty("os", "android");
+ metaData.addProperty("manufacturer", Build.MANUFACTURER);
+ metaData.addProperty("brand", Build.BRAND);
+ metaData.addProperty("device", Build.MODEL);
+ metaData.addProperty("version", Build.VERSION.RELEASE);
+ metaData.addProperty("abi", Build.CPU_ABI);
+ metaData.addProperty("country", Locale.getDefault().getISO3Country());
+ metaData.addProperty("ram", getRam());
+ metaData.addProperty("screenSize", getWindowSize());
+
+ metadata = metaData.toString();
+ }
+ return metadata;
+ }
+
+ private static String getRam() {
+ ActivityManager actManager =
+ (ActivityManager) Mapbox.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
+ ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
+ actManager.getMemoryInfo(memInfo);
+ return String.valueOf(memInfo.totalMem);
+ }
+
+ private static String getWindowSize() {
+ WindowManager windowManager =
+ (WindowManager) Mapbox.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
+ Display display = windowManager.getDefaultDisplay();
+ DisplayMetrics metrics = new DisplayMetrics();
+ display.getMetrics(metrics);
+ int width = metrics.widthPixels;
+ int height = metrics.heightPixels;
+ return "{" + width + "," + height + "}";
+ }
+ }
+
+ private static class Attribute<T> {
+ private String name;
+ private T value;
+
+ Attribute(String name, T value) {
+ this.name = name;
+ this.value = value;
+ }
+ }
+}