Merge "Convert device side to write proto rather than csv"
diff --git a/README b/README
index 3c21fcc..3bb78d4 100644
--- a/README
+++ b/README
@@ -1,4 +1,3 @@
-
Note: env setup requires slightly more than a normal Android build,
so that the path gets adjusted for tradefed.sh:
@@ -9,8 +8,9 @@
lunch 2 # generic aosp arm64 eng build
mmma tools/tradefederation/core tools/test/graphicsbenchmark
-
Incremental build + run, from tools/test/graphicsbenchmark dir:
mma
-tradefed.sh run commandAndExit AndroidTest.xml --alt-dir $OUT --apk-dir $PATH_TO_BENCHMARK_APK_DIR
+tradefed.sh run commandAndExit AndroidTest.xml --alt-dir $OUT --apk-dir $OUT/data/app
+
+Contact a member of the team for alternative test apks.
diff --git a/benchmark_libs/Android.bp b/benchmark_libs/Android.bp
index dd61923..0657698 100644
--- a/benchmark_libs/Android.bp
+++ b/benchmark_libs/Android.bp
@@ -19,5 +19,6 @@
srcs: [
"android_benchmark.cpp"
],
+ export_include_dirs: ["."],
shared_libs: ["liblog"],
}
diff --git a/hostside/res/com/android/graphics/benchmark/apk-info.xml b/hostside/res/com/android/graphics/benchmark/apk-info.xml
index ef141ff..b923d6d 100644
--- a/hostside/res/com/android/graphics/benchmark/apk-info.xml
+++ b/hostside/res/com/android/graphics/benchmark/apk-info.xml
@@ -1,15 +1,9 @@
<?xml version="1.0"?>
<apk-info>
<apk>
- <name>sniper3d</name>
- <fileName>Sniper3D_3242.apk</fileName>
- <packageName>com.fungames.sniper3d</packageName>
- <layerName>SurfaceView - com.fungames.sniper3d/com.tfg.libs.billing.unity.BillingActivity#0</layerName>
- </apk>
- <apk>
- <name>afterpulse</name>
- <fileName>afterpulse-v1.9.0.apk</fileName>
- <packageName>com.dle.afterpulse</packageName>
- <layerName>com.dle.afterpulse/com.dle.application.obbdownloader.OBBDownloaderActivity#0</layerName>
+ <name>sample</name>
+ <fileName>GraphicsBenchmarkSampleApp.apk</fileName>
+ <packageName>com.android.graphics.benchmark.example</packageName>
+ <layerName>SurfaceView - com.android.graphics.benchmark.example/com.android.graphics.benchmark.example.SampleActivity#0</layerName>
</apk>
</apk-info>
\ No newline at end of file
diff --git a/hostside/src/com/android/graphics/benchmark/metric/GraphicsBenchmarkMetricCollector.java b/hostside/src/com/android/graphics/benchmark/metric/GraphicsBenchmarkMetricCollector.java
index c795634..76d84fa 100644
--- a/hostside/src/com/android/graphics/benchmark/metric/GraphicsBenchmarkMetricCollector.java
+++ b/hostside/src/com/android/graphics/benchmark/metric/GraphicsBenchmarkMetricCollector.java
@@ -176,7 +176,10 @@
return true;
}
else {
- mElapsedTimes.add(timeStamp - mLatestSeen);
+ // Ignore the first timestamp.
+ if (mLatestSeen != 0) {
+ mElapsedTimes.add(timeStamp - mLatestSeen);
+ }
mLatestSeen = timeStamp;
return false;
}
@@ -186,7 +189,9 @@
private void onStart(DeviceMetricData runData) {}
private void onEnd(DeviceMetricData runData) {
- double minFPS = Double.MAX_VALUE, maxFPS = 0.0, avgFPS = 0.0;
+ double minFPS = Double.MAX_VALUE;
+ double maxFPS = 0.0;
+ long totalTimeNs = 0;
// TODO: correlate with mDeviceResultData to exclude loading period, etc.
@@ -200,19 +205,23 @@
double currentFPS = 1.0e9/time;
minFPS = (currentFPS < minFPS ? currentFPS : minFPS);
maxFPS = (currentFPS > maxFPS ? currentFPS : maxFPS);
- avgFPS += currentFPS;
+ totalTimeNs += time;
outputFile.write(currentFPS + "\n");
}
outputFile.write("\nSTATS\n");
- avgFPS = avgFPS / mElapsedTimes.size();
+ double avgFPS = mElapsedTimes.size() * 1.0e9 / totalTimeNs;
outputFile.write("min FPS = " + minFPS + "\n");
outputFile.write("max FPS = " + maxFPS + "\n");
outputFile.write("avg FPS = " + avgFPS + "\n");
+ runData.addStringMetric("min_fps", Double.toString(minFPS));
+ runData.addStringMetric("max_fps", Double.toString(minFPS));
+ runData.addStringMetric("fps", Double.toString(avgFPS));
+
outputFile.write("\n");
} catch (IOException e) {
throw new RuntimeException(e);
diff --git a/hostside/src/com/android/graphics/benchmark/testtype/GraphicsBenchmarkHostsideController.java b/hostside/src/com/android/graphics/benchmark/testtype/GraphicsBenchmarkHostsideController.java
index 5046ba1..f7a54c9 100644
--- a/hostside/src/com/android/graphics/benchmark/testtype/GraphicsBenchmarkHostsideController.java
+++ b/hostside/src/com/android/graphics/benchmark/testtype/GraphicsBenchmarkHostsideController.java
@@ -34,6 +34,7 @@
import com.android.tradefed.testtype.IShardableTest;
import com.google.common.io.ByteStreams;
+import com.google.common.io.Files;
import org.xml.sax.SAXException;
@@ -116,7 +117,8 @@
getDevice().pushFile(mApkInfoFile, ApkInfo.APK_LIST_LOCATION);
for (ApkInfo apk : mApks) {
- getDevice().installPackage(new File(mApkDir, apk.getFileName()), true);
+ File apkFile = findApk(apk.getFileName());
+ getDevice().installPackage(apkFile, true);
GraphicsBenchmarkMetricCollector.setAppLayerName(apk);
// Might seem counter-intuitive, but the easiest way to get per-package results is
@@ -130,7 +132,18 @@
// TODO: Populate metrics
listener.testStarted(identifier);
- runDeviceTests(PACKAGE, CLASS, "run[" + apk.getName() + "]");
+
+ if (apkFile == null) {
+ listener.testFailed(
+ identifier,
+ String.format(
+ "Missing APK. Unable to find %s in %s.",
+ apk.getFileName(),
+ mApkDir));
+ } else {
+ runDeviceTests(PACKAGE, CLASS, "run[" + apk.getName() + "]");
+ }
+
listener.testEnded(identifier, testMetrics);
ResultDataProto.Result resultData = retrieveResultData();
@@ -147,11 +160,25 @@
try (InputStream inputStream = new FileInputStream(resultFile)) {
ResultDataProto.Result data = ResultDataProto.Result.parseFrom(inputStream);
return data;
- } catch(IOException e) {
+ } catch (IOException e) {
throw new RuntimeException(e);
}
}
+ return null;
+ }
+ /** Find an apk in the apk-dir directory */
+ private File findApk(String filename) {
+ File file = new File(mApkDir, filename);
+ if (file.exists()) {
+ return file;
+ }
+ // If a default sample app is named Sample.apk, it is outputted to
+ // $ANDROID_PRODUCT_OUT/data/app/Sample/Sample.apk.
+ file = new File(mApkDir, Files.getNameWithoutExtension(filename) + "/" + filename);
+ if (file.exists()) {
+ return file;
+ }
return null;
}
@@ -159,21 +186,30 @@
if (mApks != null) {
return;
}
+
+ // Find an apk info file. The priorities are:
+ // 1. Use the specified apk-info if available.
+ // 2. Use 'apk-info.xml' if there is one in the apk-dir directory.
+ // 3. Use the default apk-info.xml in res.
if (mApkInfoFileName != null) {
mApkInfoFile = new File(mApkInfoFileName);
} else {
- String resource = "/com/android/graphics/benchmark/apk-info.xml";
- try(InputStream inputStream = ApkInfo.class.getResourceAsStream(resource)) {
- if (inputStream == null) {
- throw new FileNotFoundException("Unable to find resource: " + resource);
+ mApkInfoFile = new File(mApkDir, "apk-info.xml");
+
+ if (!mApkInfoFile.exists()) {
+ String resource = "/com/android/graphics/benchmark/apk-info.xml";
+ try(InputStream inputStream = ApkInfo.class.getResourceAsStream(resource)) {
+ if (inputStream == null) {
+ throw new FileNotFoundException("Unable to find resource: " + resource);
+ }
+ mApkInfoFile = File.createTempFile("apk-info", ".xml");
+ try (OutputStream ostream = new FileOutputStream(mApkInfoFile)) {
+ ByteStreams.copy(inputStream, ostream);
+ }
+ mApkInfoFile.deleteOnExit();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
}
- mApkInfoFile = File.createTempFile("apk-info", ".xml");
- try (OutputStream ostream = new FileOutputStream(mApkInfoFile)) {
- ByteStreams.copy(inputStream, ostream);
- }
- mApkInfoFile.deleteOnExit();
- } catch (IOException e) {
- throw new RuntimeException(e);
}
}
ApkListXmlParser parser = new ApkListXmlParser();
diff --git a/sample_app/Android.mk b/sample_app/Android.mk
new file mode 100644
index 0000000..a2e0eb7
--- /dev/null
+++ b/sample_app/Android.mk
@@ -0,0 +1,38 @@
+# Copyright 2018, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SDK_VERSION := 26 # Oreo
+LOCAL_MODULE := libsample
+LOCAL_MODULE_TAGS := tests
+LOCAL_SRC_FILES := src/cpp/sample_activity.cpp
+LOCAL_SHARED_LIBRARIES := libagbench
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_SDK_VERSION := 26 # Oreo
+LOCAL_PACKAGE_NAME := GraphicsBenchmarkSampleApp
+LOCAL_MODULE_TAGS := tests
+LOCAL_JNI_SHARED_LIBRARIES := libagbench libsample
+LOCAL_COMPATIBILITY_SUITE := device-tests
+LOCAL_SRC_FILES := $(call all-java-files-under, src/java)
+
+include $(BUILD_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/sample_app/AndroidManifest.xml b/sample_app/AndroidManifest.xml
new file mode 100644
index 0000000..bd77eb3
--- /dev/null
+++ b/sample_app/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.graphics.benchmark.example">
+
+ <application
+ android:allowBackup="false"
+ android:label="SampleBenchmark">
+ <activity android:name=".SampleActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/sample_app/src/cpp/sample_activity.cpp b/sample_app/src/cpp/sample_activity.cpp
new file mode 100644
index 0000000..5504c3a
--- /dev/null
+++ b/sample_app/src/cpp/sample_activity.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <jni.h>
+#include <android_benchmark.h>
+
+extern "C"
+JNIEXPORT void JNICALL
+Java_com_android_graphics_benchmark_example_SampleActivity_broadcastIntent(JNIEnv*, jobject instance) {
+ android::AndroidGraphicsBenchmark benchmark;
+ benchmark.startBenchmark(instance);
+}
diff --git a/sample_app/src/java/com/android/graphics/benchmark/example/MyGLRenderer.java b/sample_app/src/java/com/android/graphics/benchmark/example/MyGLRenderer.java
new file mode 100644
index 0000000..adaaeba
--- /dev/null
+++ b/sample_app/src/java/com/android/graphics/benchmark/example/MyGLRenderer.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.graphics.benchmark.example;
+
+import android.opengl.GLES20;
+import android.opengl.GLSurfaceView;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+public class MyGLRenderer implements GLSurfaceView.Renderer {
+
+ public void onSurfaceCreated(GL10 unused, EGLConfig config) {
+ // Set the background frame color
+ GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
+ }
+
+ public void onDrawFrame(GL10 unused) {
+ // Redraw background color
+ GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
+ }
+
+ public void onSurfaceChanged(GL10 unused, int width, int height) {
+ GLES20.glViewport(0, 0, width, height);
+ }
+}
diff --git a/sample_app/src/java/com/android/graphics/benchmark/example/MyGLSurfaceView.java b/sample_app/src/java/com/android/graphics/benchmark/example/MyGLSurfaceView.java
new file mode 100644
index 0000000..c0897e7
--- /dev/null
+++ b/sample_app/src/java/com/android/graphics/benchmark/example/MyGLSurfaceView.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.graphics.benchmark.example;
+
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+
+class MyGLSurfaceView extends GLSurfaceView {
+
+ private final MyGLRenderer mRenderer;
+
+ public MyGLSurfaceView(Context context){
+ super(context);
+
+ // Create an OpenGL ES 2.0 context
+ setEGLContextClientVersion(2);
+
+ mRenderer = new MyGLRenderer();
+
+ // Set the Renderer for drawing on the GLSurfaceView
+ setRenderer(mRenderer);
+ }
+}
diff --git a/sample_app/src/java/com/android/graphics/benchmark/example/SampleActivity.java b/sample_app/src/java/com/android/graphics/benchmark/example/SampleActivity.java
new file mode 100644
index 0000000..b0207a5
--- /dev/null
+++ b/sample_app/src/java/com/android/graphics/benchmark/example/SampleActivity.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.graphics.benchmark.example;
+
+import android.app.Activity;
+import android.opengl.GLSurfaceView;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+
+public class SampleActivity extends Activity {
+ private GLSurfaceView mGLView;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Create a GLSurfaceView instance and set it
+ // as the ContentView for this Activity.
+ mGLView = new MyGLSurfaceView(this);
+ setContentView(mGLView);
+
+ // Loop every 5s.
+ Handler handler = new Handler();
+ Runnable task = new Runnable() {
+ @Override
+ public void run() {
+ broadcastIntent();
+ handler.postDelayed(this, 5000);
+ }
+ };
+ handler.postDelayed(task, 5000);
+ }
+
+ public native void broadcastIntent();
+
+ static {
+ System.loadLibrary("sample");
+ }
+}