diff options
Diffstat (limited to 'platform/android/MapboxGLAndroidSDKTestApp')
6 files changed, 389 insertions, 0 deletions
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 |