summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/PerformanceEvent.java94
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/TelemetryImpl.java5
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/module/telemetry/PerformanceEventTest.java188
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml11
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/telemetry/PerformanceMeasurementActivity.java187
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/categories.xml1
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml1
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/titles.xml1
-rw-r--r--platform/android/scripts/exclude-activity-gen.json3
9 files changed, 482 insertions, 9 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/PerformanceEvent.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/PerformanceEvent.java
index b88e1885ca..12d1fe46cf 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/PerformanceEvent.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/PerformanceEvent.java
@@ -1,20 +1,55 @@
package com.mapbox.mapboxsdk.module.telemetry;
+import com.google.gson.Gson;
+
+import com.google.gson.JsonObject;
+
+import com.google.gson.reflect.TypeToken;
import com.mapbox.android.telemetry.Event;
import android.os.Bundle;
import android.os.Parcel;
+
import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Date;
+import java.util.List;
import java.util.Locale;
/**
* Generic Performance Event that can be used for performance measurements.
* Customer measurements can be added to the bundle.
+ *
+ * Bundle is expected to have following properties:
+ * "attributes", "counters", and "metadata" with String values.
+ *
+ * Attributes: a string representing an array of name/string value pair objects.
+ * Counters: a string representing an array of name/number value pair objects.
+ * Metadata is a string representation of a JsonObject with string values.
+ *
+ * Here is an example of a Performance event bundle data:
+ *
+ * "attributes": [{ "name": "style_id", "value": "mapbox://styles/mapbox/streets-v10"}]
+ *
+ * "counters": [{"name": "fps_average", "value": 90.7655486547093},
+ * {"name": "fps_deviation", "value": 29.301809631465574}]
+ * “metadata”: {
+ * “version”: “9”,
+ * “screenSize”: “1080x1794”,
+ * “country”: “US”,
+ * “device”: “Pixel 2”,
+ * “abi”: “arm64-v8a”,
+ * “brand”: “google”,
+ * “ram”: “3834167296”,
+ * “os”: “android”,
+ * “gpu”: “Qualcomm, Adreno (TM) 540, OpenGL ES 3.2 V@313.0 (GIT@7bf2852, Ie32bfa6f6f)“,
+ * “manufacturer”: “Google”
+ * }
*/
public class PerformanceEvent extends Event {
- private static final String PERFORMANCE_TRACE = "performance.trace";
+
+ private static final String PERFORMANCE_TRACE = "mobile.performance_trace";
private final String event;
@@ -22,23 +57,36 @@ public class PerformanceEvent extends Event {
private final String sessionId;
- private final Bundle data;
+ private final List<Attribute<String>> attributes;
+
+ private final List<Attribute<Double>> counters;
+
+ private final JsonObject metadata;
+
private static final SimpleDateFormat DATE_FORMAT =
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US);
- PerformanceEvent(String sessionId, Bundle data) {
+ PerformanceEvent(String sessionId, Bundle bundle) {
+
this.event = PERFORMANCE_TRACE;
this.created = DATE_FORMAT.format(new Date());
this.sessionId = sessionId;
- this.data = data;
+ this.attributes = initList(bundle.getString("attributes"),
+ new TypeToken<ArrayList<Attribute<String>>>() {});
+ this.counters = initList(bundle.getString("counters"),
+ new TypeToken<ArrayList<Attribute<Double>>>() {});
+ this.metadata = initMetaData(bundle.getString("metadata"));
}
private PerformanceEvent(Parcel in) {
this.event = in.readString();
this.created = in.readString();
this.sessionId = in.readString();
- this.data = in.readBundle();
+
+ this.attributes = initList(in.readString(), new TypeToken<ArrayList<Attribute<String>>>() {});
+ this.counters = initList(in.readString(), new TypeToken<ArrayList<Attribute<Double>>>() {});
+ this.metadata = initMetaData(in.readString());
}
@Override
@@ -51,7 +99,30 @@ public class PerformanceEvent extends Event {
parcel.writeString(event);
parcel.writeString(created);
parcel.writeString(sessionId);
- parcel.writeBundle(data);
+
+ Gson gson = new Gson();
+
+ parcel.writeString(gson.toJson(attributes));
+ parcel.writeString(gson.toJson(counters));
+
+ if (metadata != null) {
+ parcel.writeString(metadata.toString());
+ }
+ }
+
+ private <T> ArrayList<Attribute<T>> initList(String fromString, TypeToken typeToken) {
+ if (fromString == null || fromString.isEmpty()) {
+ return new ArrayList<>();
+ }
+ return new Gson().fromJson(fromString, typeToken.getType());
+ }
+
+ private JsonObject initMetaData(String fromString) {
+ if (fromString == null) {
+ return new JsonObject();
+ } else {
+ return new Gson().fromJson(fromString, JsonObject.class);
+ }
}
public static final Creator<PerformanceEvent> CREATOR = new Creator<PerformanceEvent>() {
@@ -65,4 +136,15 @@ public class PerformanceEvent extends Event {
return new PerformanceEvent[size];
}
};
+
+
+ private class Attribute<T> {
+ private final String name;
+ private final T value;
+
+ Attribute(String name, T value) {
+ this.name = name;
+ this.value = value;
+ }
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/TelemetryImpl.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/TelemetryImpl.java
index 5e021f961e..697a51286f 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/TelemetryImpl.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/module/telemetry/TelemetryImpl.java
@@ -111,8 +111,9 @@ public class TelemetryImpl implements TelemetryDefinition {
@Override
public void onPerformanceEvent(Bundle data) {
- if (data != null && !data.isEmpty()) {
- telemetry.push(new PerformanceEvent(UUID.randomUUID().toString(), data));
+ if (data == null) {
+ data = new Bundle();
}
+ telemetry.push(new PerformanceEvent(UUID.randomUUID().toString(), data));
}
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/module/telemetry/PerformanceEventTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/module/telemetry/PerformanceEventTest.java
new file mode 100644
index 0000000000..6f256b4e56
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/module/telemetry/PerformanceEventTest.java
@@ -0,0 +1,188 @@
+package com.mapbox.mapboxsdk.module.telemetry;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.support.test.runner.AndroidJUnit4;
+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.Mapbox;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.UUID;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@RunWith(AndroidJUnit4.class)
+public class PerformanceEventTest {
+
+ @Test
+ public void checksPerformanceEventWithMetaData() throws Exception {
+ PerformanceEvent event = obtainPerformanceEvent();
+ assertNotNull(event);
+
+ Parcel parcel = Parcel.obtain();
+
+ event.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+
+ PerformanceEvent newPerfEvent = PerformanceEvent.CREATOR.createFromParcel(parcel);
+ assertNotNull(newPerfEvent);
+
+ compare(event, newPerfEvent, "attributes", "style_id");
+ compare(event, newPerfEvent, "counters", "int_value");
+ compare(event, newPerfEvent, "counters", "long_value");
+ compare(event, newPerfEvent, "counters", "double_value");
+ assertEquals(getMetadata(event), getMetadata(newPerfEvent));
+ }
+
+ @Test
+ public void checksPerformanceEventOnlyRequiredData() throws Exception {
+ Bundle bundle = new Bundle();
+ bundle.putString("property ignored", "value will be ignored");
+ PerformanceEvent event = new PerformanceEvent(UUID.randomUUID().toString(), bundle);
+ assertNotNull(event);
+
+ Parcel parcel = Parcel.obtain();
+ event.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+
+ PerformanceEvent newPerfEvent = PerformanceEvent.CREATOR.createFromParcel(parcel);
+ assertNotNull(newPerfEvent);
+
+ assertEquals(getAttributes(event).size(), 0);
+ assertEquals(getCounters(event).size(), 0);
+ assertEquals(getAttributes(newPerfEvent).size(), 0);
+ assertEquals(getCounters(newPerfEvent).size(), 0);
+ assertEquals(getMetadata(event), getMetadata(newPerfEvent));
+ }
+
+
+ private PerformanceEvent obtainPerformanceEvent() {
+ String styleStr = "mapbox://styles/mapbox/streets-v11";
+ boolean testPerfEvent = true;
+ Double doubleValue = 40.5;
+ Long longValue = 40L;
+ Integer intValue = 40;
+
+ List<Attribute<String>> attributes = new ArrayList<>();
+ attributes.add(
+ new Attribute<>("style_id", styleStr));
+ attributes.add(
+ new Attribute<>("test_perf_event", String.valueOf(testPerfEvent)));
+
+ List<Attribute<? extends Number>> counters = new ArrayList();
+ counters.add(new Attribute<>("long_value", longValue));
+ counters.add(new Attribute<>("double_value", doubleValue));
+ counters.add(new Attribute<>("int_value", intValue));
+
+ Gson gson = new Gson();
+
+ Bundle bundle = new Bundle();
+ bundle.putString("attributes", gson.toJson(attributes));
+ bundle.putString("counters", gson.toJson(counters));
+
+ 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());
+ bundle.putString("metadata", metaData.toString());
+
+ return new PerformanceEvent(UUID.randomUUID().toString(), bundle);
+ }
+
+ private void compare(PerformanceEvent event1, PerformanceEvent event2, String listFieldName, String name)
+ throws NoSuchFieldException, IllegalAccessException {
+ Object value1 = getValue(event1, listFieldName, name);
+ Object value2 = getValue(event2, listFieldName, name);
+
+ if (value1 instanceof Double && value2 instanceof Double) {
+ assertEquals((Double)value1, (Double)value2, 0.00006);
+ } else {
+ assertEquals(value1, value2);
+ }
+ }
+
+ private Object getPrivateFieldValue(Object object, String fieldName)
+ throws NoSuchFieldException, IllegalAccessException {
+ Field field = object.getClass().getDeclaredField(fieldName);
+ field.setAccessible(true);
+ return field.get(object);
+ }
+
+ private Object getValue(PerformanceEvent event, String listFieldName, String name)
+ throws NoSuchFieldException, IllegalAccessException {
+ ArrayList list = (ArrayList)getPrivateFieldValue(event, listFieldName);
+ for (Object element : list) {
+ Object elementName = getPrivateFieldValue(element, "name");
+ if (elementName != null && elementName.equals((String)name)) {
+ return getPrivateFieldValue(element, "value");
+ }
+ }
+ return null;
+ }
+
+ private JsonObject getMetadata(PerformanceEvent event)
+ throws NoSuchFieldException, IllegalAccessException {
+ return (JsonObject)getPrivateFieldValue(event, "metadata");
+ }
+
+ private ArrayList getAttributes(PerformanceEvent event)
+ throws NoSuchFieldException, IllegalAccessException {
+ return (ArrayList)getPrivateFieldValue(event, "attributes");
+ }
+
+ private ArrayList getCounters(PerformanceEvent event)
+ throws NoSuchFieldException, IllegalAccessException {
+ return (ArrayList)getPrivateFieldValue(event, "counters");
+ }
+
+ 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 class Attribute<T> {
+ private String name;
+ private T value;
+
+ Attribute(String name, T value) {
+ this.name = name;
+ this.value = value;
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
index a5cc549cc2..017fe3ddca 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
@@ -930,6 +930,17 @@
android:name="android.support.PARENT_ACTIVITY"
android:value=".activity.FeatureOverviewActivity" />
</activity>
+ <activity
+ android:name=".activity.telemetry.PerformanceMeasurementActivity"
+ android:description="@string/description_performance_measurement"
+ android:label="@string/activity_performance_measurement">
+ <meta-data
+ android:name="@string/category"
+ android:value="@string/category_telemetry" />
+ <meta-data
+ android:name="android.support.PARENT_ACTIVITY"
+ android:value=".activity.FeatureOverviewActivity" />
+ </activity>
<!-- For Instrumentation tests -->
<activity
android:name=".activity.style.RuntimeStyleTimingTestActivity"
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/telemetry/PerformanceMeasurementActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/telemetry/PerformanceMeasurementActivity.java
new file mode 100644
index 0000000000..285d7bc6c8
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/telemetry/PerformanceMeasurementActivity.java
@@ -0,0 +1,187 @@
+package com.mapbox.mapboxsdk.testapp.activity.telemetry;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+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.Mapbox;
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.Style;
+import com.mapbox.mapboxsdk.module.http.HttpRequestUtil;
+import com.mapbox.mapboxsdk.testapp.R;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import okhttp3.Call;
+import okhttp3.EventListener;
+import okhttp3.OkHttpClient;
+import timber.log.Timber;
+
+/**
+ * Test activity showcasing gathering performance measurement data.
+ */
+public class PerformanceMeasurementActivity extends AppCompatActivity {
+
+ private MapView mapView;
+
+ private Map<String, Long> startTimes = new HashMap<>();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_map_simple);
+ mapView = findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+
+
+ OkHttpClient.Builder builder = new OkHttpClient.Builder();
+ builder.eventListener(new EventListener() {
+
+ @Override
+ public void callStart(Call call) {
+ String url = call.request().url().toString();
+ startTimes.put(url, System.nanoTime());
+ super.callStart(call);
+ Timber.e("callStart: %s", url);
+ }
+
+ @Override
+ public void callEnd(Call call) {
+ String url = call.request().url().toString();
+ Timber.e("callEnd: %s", url);
+ Long start = startTimes.get(url);
+ if (start != null) {
+ long elapsed = System.nanoTime() - start;
+ triggerPerformanceEvent(url.substring(0, url.indexOf('?')), elapsed);
+ startTimes.remove(start);
+ Timber.e("callEnd: %s took %d", url, elapsed);
+ }
+ super.callEnd(call);
+ }
+ });
+ HttpRequestUtil.setOkHttpClient(builder.build());
+
+ mapView.getMapAsync(mapboxMap -> mapboxMap.setStyle(
+ new Style.Builder().fromUrl(Style.MAPBOX_STREETS)));
+ }
+
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ protected void onDestroy() {
+
+ startTimes.clear();
+
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ private void triggerPerformanceEvent(String style, long elapsed) {
+
+ List<Attribute<String>> attributes = new ArrayList<>();
+ attributes.add(
+ new Attribute<>("style_id", style));
+ attributes.add(
+ new Attribute<>("test_perf_event", "true"));
+
+ List<Attribute<Long>> counters = new ArrayList();
+ counters.add(new Attribute<>("elapsed", elapsed));
+
+
+ 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());
+
+ Gson gson = new Gson();
+
+ Bundle bundle = new Bundle();
+ bundle.putString("attributes", gson.toJson(attributes));
+ bundle.putString("counters", gson.toJson(counters));
+ bundle.putString("metadata", metaData.toString());
+
+ Mapbox.getTelemetry().onPerformanceEvent(bundle);
+ }
+
+ 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 class Attribute<T> {
+ private String name;
+ private T value;
+
+ Attribute(String name, T value) {
+ this.name = name;
+ this.value = value;
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/categories.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/categories.xml
index 918fd4cc3f..2c34a59327 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/categories.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/categories.xml
@@ -16,4 +16,5 @@
<string name="category_textureview">Texture View</string>
<string name="category_location">Location</string>
<string name="category_integration">_Integration</string>
+ <string name="category_telemetry">Telemetry</string>
</resources> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml
index cd4130c44a..778805b3b3 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml
@@ -81,4 +81,5 @@
<string name="description_recyclerview_textureview">Show a TextureView MapView as a recyclerView item</string>
<string name="description_recyclerview_glsurfaceview">Show a GLSurfaceView MapView as a recyclerView item</string>
<string name="description_nested_viewpager">Show a MapView inside a viewpager inside a recyclerView</string>
+ <string name="description_performance_measurement">Show the use PerformanceEvent for performance measurements</string>
</resources>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/titles.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/titles.xml
index 07ba2b7afd..12c82bf21a 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/titles.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/titles.xml
@@ -81,4 +81,5 @@
<string name="activity_recyclerview_textureview">RecyclerView TextureView</string>
<string name="activity_recyclerview_glsurfaceview">RecyclerView GLSurfaceView</string>
<string name="activity_nested_viewpager">Nested ViewPager</string>
+ <string name="activity_performance_measurement">Performance Measurement</string>
</resources> \ No newline at end of file
diff --git a/platform/android/scripts/exclude-activity-gen.json b/platform/android/scripts/exclude-activity-gen.json
index 47c437bd23..a6070edccf 100644
--- a/platform/android/scripts/exclude-activity-gen.json
+++ b/platform/android/scripts/exclude-activity-gen.json
@@ -49,5 +49,6 @@
"ChangeResourcesCachePathActivity",
"EspressoTestActivity",
"FragmentBackStackActivity",
- "ChildFragmentMapInDialogActivity"
+ "ChildFragmentMapInDialogActivity",
+ "PerformanceMeasurementActivity"
]