Merge "Calculating jank from the timestamps."
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 3887c1d..4b7229d 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -132,16 +132,14 @@
CTS_TEST_CASES := $(call cts-get-lib-paths,$(cts_host_libraries)) \
$(call cts-get-package-paths,$(cts_test_packages)) \
$(call cts-get-native-paths,$(cts_native_exes)) \
- $(call cts-get-ui-lib-paths,$(cts_ui_tests)) \
- $(call cts-get-ui-lib-paths,$(PTS_UI_TESTS))
+ $(call cts-get-ui-lib-paths,$(cts_ui_tests))
# All the XMLs that will end up under the repository/testcases
# and that need to be created before making the final CTS distribution.
CTS_TEST_XMLS := $(call cts-get-test-xmls,$(cts_host_libraries)) \
$(call cts-get-test-xmls,$(cts_test_packages)) \
$(call cts-get-test-xmls,$(cts_native_exes)) \
- $(call cts-get-test-xmls,$(cts_ui_tests)) \
- $(call cts-get-test-xmls,$(PTS_UI_TESTS))
+ $(call cts-get-test-xmls,$(cts_ui_tests))
# The following files will be placed in the tools directory of the CTS distribution
diff --git a/suite/pts/PtsBenchmarkingList.mk b/suite/pts/PtsBenchmarkingList.mk
index 0aba241..ab79bca 100644
--- a/suite/pts/PtsBenchmarkingList.mk
+++ b/suite/pts/PtsBenchmarkingList.mk
@@ -34,7 +34,5 @@
PTS_HOST_CASES := \
PtsHostBootup \
- PtsHostUi
-
-PTS_UI_TESTS := \
+ PtsHostUi \
PtsHostJank
diff --git a/suite/pts/deviceTests/opengl/AndroidManifest.xml b/suite/pts/deviceTests/opengl/AndroidManifest.xml
index 86e21e2..6aa50cf 100644
--- a/suite/pts/deviceTests/opengl/AndroidManifest.xml
+++ b/suite/pts/deviceTests/opengl/AndroidManifest.xml
@@ -30,7 +30,8 @@
</activity>
<activity
android:name="com.android.pts.opengl.reference.GLReferenceActivity"
- android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode" >
+ android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
+ android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
diff --git a/suite/pts/deviceTests/opengl/assets/texture/arc.png b/suite/pts/deviceTests/opengl/assets/texture/arc.png
index 5a68acd..f95e7a0 100644
--- a/suite/pts/deviceTests/opengl/assets/texture/arc.png
+++ b/suite/pts/deviceTests/opengl/assets/texture/arc.png
Binary files differ
diff --git a/suite/pts/deviceTests/opengl/assets/texture/fish.png b/suite/pts/deviceTests/opengl/assets/texture/fish.png
index 6f62650..fdf1e2c 100644
--- a/suite/pts/deviceTests/opengl/assets/texture/fish.png
+++ b/suite/pts/deviceTests/opengl/assets/texture/fish.png
Binary files differ
diff --git a/suite/pts/deviceTests/opengl/assets/texture/water1.png b/suite/pts/deviceTests/opengl/assets/texture/water1.png
index 2fdefa1..96f4e62 100644
--- a/suite/pts/deviceTests/opengl/assets/texture/water1.png
+++ b/suite/pts/deviceTests/opengl/assets/texture/water1.png
Binary files differ
diff --git a/suite/pts/deviceTests/opengl/assets/texture/water2.png b/suite/pts/deviceTests/opengl/assets/texture/water2.png
index 7050e3d..92eebf9 100644
--- a/suite/pts/deviceTests/opengl/assets/texture/water2.png
+++ b/suite/pts/deviceTests/opengl/assets/texture/water2.png
Binary files differ
diff --git a/suite/pts/deviceTests/opengl/assets/vertex/basic b/suite/pts/deviceTests/opengl/assets/vertex/basic
index be831d0..88ba2ba 100644
--- a/suite/pts/deviceTests/opengl/assets/vertex/basic
+++ b/suite/pts/deviceTests/opengl/assets/vertex/basic
@@ -11,6 +11,7 @@
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
+precision mediump float;
attribute vec4 a_Position;
attribute vec2 a_TexCoordinate;
varying vec2 v_TexCoordinate;
diff --git a/suite/pts/deviceTests/opengl/assets/vertex/blur b/suite/pts/deviceTests/opengl/assets/vertex/blur
index ffb2bf0..ffd6a86 100644
--- a/suite/pts/deviceTests/opengl/assets/vertex/blur
+++ b/suite/pts/deviceTests/opengl/assets/vertex/blur
@@ -11,6 +11,7 @@
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
+precision mediump float;
attribute vec4 a_Position;
attribute vec2 a_TexCoordinate;
varying vec2 v_TexCoordinate;
diff --git a/suite/pts/deviceTests/opengl/assets/vertex/perspective b/suite/pts/deviceTests/opengl/assets/vertex/perspective
index 6889c72..14c8c30 100644
--- a/suite/pts/deviceTests/opengl/assets/vertex/perspective
+++ b/suite/pts/deviceTests/opengl/assets/vertex/perspective
@@ -11,6 +11,7 @@
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
+precision mediump float;
uniform mat4 u_MVPMatrix;
uniform mat4 u_MVMatrix;
attribute vec4 a_Position;
diff --git a/suite/pts/deviceTests/opengl/assets/vertex/water b/suite/pts/deviceTests/opengl/assets/vertex/water
index 05174e4..dc09a99 100644
--- a/suite/pts/deviceTests/opengl/assets/vertex/water
+++ b/suite/pts/deviceTests/opengl/assets/vertex/water
@@ -11,6 +11,7 @@
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
+precision mediump float;
uniform mat4 u_MVPMatrix;
uniform mat4 u_MVMatrix;
attribute vec4 a_Position;
diff --git a/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/Benchmark.java b/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/BenchmarkName.java
similarity index 96%
rename from suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/Benchmark.java
rename to suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/BenchmarkName.java
index d61f45d..e9f219b 100644
--- a/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/Benchmark.java
+++ b/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/BenchmarkName.java
@@ -16,7 +16,7 @@
/**
* Represents the different primitive benchmarks.
*/
-public enum Benchmark {
+public enum BenchmarkName {
FullPipeline,
PixelOutput,
ShaderPerf,
diff --git a/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLPrimitiveActivity.java b/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLPrimitiveActivity.java
index 4db037c..377e851 100644
--- a/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLPrimitiveActivity.java
+++ b/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLPrimitiveActivity.java
@@ -39,7 +39,7 @@
private CountDownLatch mStartSignal = new CountDownLatch(1);
private Semaphore mSemaphore = new Semaphore(0);
- private Benchmark mBenchmark;
+ private BenchmarkName mBenchmark;
private boolean mOffscreen;
private int mNumFrames;
private int mNumIterations;
@@ -51,8 +51,8 @@
super.onCreate(data);
System.loadLibrary("ptsopengl_jni");
Intent intent = getIntent();
- mBenchmark = Benchmark.valueOf(
- intent.getStringExtra(GLActivityIntentKeys.INTENT_EXTRA_BENCHMARK_NAME));
+ mBenchmark = BenchmarkName.valueOf(intent.getStringExtra(
+ GLActivityIntentKeys.INTENT_EXTRA_BENCHMARK_NAME));
mOffscreen = intent.getBooleanExtra(GLActivityIntentKeys.INTENT_EXTRA_OFFSCREEN, false);
mNumFrames = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_FRAMES, 0);
mNumIterations = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_ITERATIONS, 0);
diff --git a/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLPrimitiveBenchmark.java b/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLPrimitiveBenchmark.java
index 3efba20..1f40c7a 100644
--- a/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLPrimitiveBenchmark.java
+++ b/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLPrimitiveBenchmark.java
@@ -41,7 +41,7 @@
*/
@TimeoutReq(minutes = 100)
public void testFullPipelineOffscreen() throws Exception {
- runBenchmark(Benchmark.FullPipeline, true, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
+ runBenchmark(BenchmarkName.FullPipeline, true, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
}
/**
@@ -49,7 +49,7 @@
*/
@TimeoutReq(minutes = 100)
public void testFullPipelineOnscreen() throws Exception {
- runBenchmark(Benchmark.FullPipeline, false, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
+ runBenchmark(BenchmarkName.FullPipeline, false, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
}
/**
@@ -57,7 +57,7 @@
*/
@TimeoutReq(minutes = 100)
public void testPixelOutputOffscreen() throws Exception {
- runBenchmark(Benchmark.PixelOutput, true, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
+ runBenchmark(BenchmarkName.PixelOutput, true, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
}
/**
@@ -65,7 +65,7 @@
*/
@TimeoutReq(minutes = 100)
public void testPixelOutputOnscreen() throws Exception {
- runBenchmark(Benchmark.PixelOutput, false, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
+ runBenchmark(BenchmarkName.PixelOutput, false, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
}
/**
@@ -73,7 +73,7 @@
*/
@TimeoutReq(minutes = 100)
public void testShaderPerfOffscreen() throws Exception {
- runBenchmark(Benchmark.ShaderPerf, true, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
+ runBenchmark(BenchmarkName.ShaderPerf, true, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
}
/**
@@ -81,7 +81,7 @@
*/
@TimeoutReq(minutes = 100)
public void testShaderPerfOnscreen() throws Exception {
- runBenchmark(Benchmark.ShaderPerf, false, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
+ runBenchmark(BenchmarkName.ShaderPerf, false, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
}
/**
@@ -89,7 +89,7 @@
*/
@TimeoutReq(minutes = 100)
public void testContextSwitchOffscreen() throws Exception {
- runBenchmark(Benchmark.ContextSwitch, true, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
+ runBenchmark(BenchmarkName.ContextSwitch, true, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
}
/**
@@ -97,7 +97,7 @@
*/
@TimeoutReq(minutes = 100)
public void testContextSwitchOnscreen() throws Exception {
- runBenchmark(Benchmark.ContextSwitch, false, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
+ runBenchmark(BenchmarkName.ContextSwitch, false, NUM_FRAMES, NUM_ITERATIONS, TIMEOUT);
}
/**
@@ -110,9 +110,8 @@
* @param timeout The milliseconds to wait for an iteration of the benchmark before timing out.
* @throws Exception If the benchmark could not be run.
*/
- private void runBenchmark(
- Benchmark benchmark, boolean offscreen, int numFrames, int numIterations, int timeout)
- throws Exception {
+ private void runBenchmark(BenchmarkName benchmark, boolean offscreen, int numFrames,
+ int numIterations, int timeout) throws Exception {
String benchmarkName = benchmark.toString();
Intent intent = new Intent();
intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_BENCHMARK_NAME, benchmarkName);
diff --git a/suite/pts/hostTests/jank/Android.mk b/suite/pts/hostTests/jank/Android.mk
index 936a850..efd0bd8 100644
--- a/suite/pts/hostTests/jank/Android.mk
+++ b/suite/pts/hostTests/jank/Android.mk
@@ -17,19 +17,16 @@
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/local/tmp
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_MODULE := PtsHostJank
-LOCAL_JAVA_LIBRARIES := uiautomator.core
-LOCAL_STATIC_JAVA_LIBRARIES := com.android.uiautomator.platform.common
-LOCAL_PROGUARD_ENABLED := disabled
-LOCAL_CTS_TEST_APK := PtsDeviceJankApp
-LOCAL_CTS_TEST_APP_PACKAGE := com.android.pts.opengl
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt ddmlib-prebuilt ptscommonutilhost
+
LOCAL_CTS_TEST_PACKAGE := com.android.pts.jank
-include $(BUILD_CTS_UI_JAVA_LIBRARY)
+include $(BUILD_CTS_HOST_JAVA_LIBRARY)
# Build the test APK using its own makefile, and any other CTS-related packages
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/suite/pts/hostTests/jank/app/Android.mk b/suite/pts/hostTests/jank/app/Android.mk
index 257c552..5ef1a92 100644
--- a/suite/pts/hostTests/jank/app/Android.mk
+++ b/suite/pts/hostTests/jank/app/Android.mk
@@ -27,8 +27,11 @@
LOCAL_JNI_SHARED_LIBRARIES := libptsopengl_jni
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-# add the src of the reference benchmark
-LOCAL_SRC_FILES += $(call all-java-files-under, ../../../deviceTests/opengl/src)
+# add the src of the benchmark, but filter out the tests
+BENCHMARK_SRC := $(call all-java-files-under, ../../../deviceTests/opengl/src)
+LOCAL_SRC_FILES += $(filter-out %Benchmark.java, $(BENCHMARK_SRC))
+
+#$(info $(LOCAL_SRC_FILES))
LOCAL_ASSET_DIR := $(LOCAL_PATH)/../../../deviceTests/opengl/assets
diff --git a/suite/pts/hostTests/jank/app/AndroidManifest.xml b/suite/pts/hostTests/jank/app/AndroidManifest.xml
index e75fd7a..8c2e577 100644
--- a/suite/pts/hostTests/jank/app/AndroidManifest.xml
+++ b/suite/pts/hostTests/jank/app/AndroidManifest.xml
@@ -25,20 +25,22 @@
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<application>
+ <uses-library android:name="android.test.runner" />
<activity
- android:name=".JankActivity"
- android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode" >
+ android:name="com.android.pts.opengl.primitive.GLPrimitiveActivity"
+ android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
+ android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
- <activity
- android:name="com.android.pts.opengl.reference.GLGameActivity"
- android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
- android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
- </activity>
</application>
+ <instrumentation
+ android:name="android.test.InstrumentationCtsTestRunner"
+ android:label="Jank Test"
+ android:targetPackage="com.android.pts.jank" />
+
</manifest>
\ No newline at end of file
diff --git a/suite/pts/hostTests/jank/app/src/com/android/pts/jank/JankActivity.java b/suite/pts/hostTests/jank/app/src/com/android/pts/jank/JankActivity.java
deleted file mode 100644
index 2c37922..0000000
--- a/suite/pts/hostTests/jank/app/src/com/android/pts/jank/JankActivity.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2013 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.pts.jank;
-
-import android.app.Activity;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.widget.Button;
-
-import com.android.pts.opengl.reference.GLGameActivity;
-
-public class JankActivity extends Activity {
- static final String TAG = "JankActivity";
-
- private final static int GAME_ACTIVITY_CODE = 1;
-
- public void onCreate(Bundle data) {
- super.onCreate(data);
- // Sets the view to be a big button. This is pressed by uiautomator when SurfaceFlinger's
- // buffers have been cleared.
- final Button start = new Button(this);
- start.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- final Intent intent = new Intent(JankActivity.this, GLGameActivity.class);
- startActivityForResult(intent, GAME_ACTIVITY_CODE);
- }
- });
- setContentView(start);
- }
-
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == GAME_ACTIVITY_CODE) {
- finish();
- }
- }
-}
diff --git a/suite/pts/hostTests/jank/app/src/com/android/pts/jank/JankTest.java b/suite/pts/hostTests/jank/app/src/com/android/pts/jank/JankTest.java
new file mode 100644
index 0000000..84caa63
--- /dev/null
+++ b/suite/pts/hostTests/jank/app/src/com/android/pts/jank/JankTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2013 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.pts.jank;
+
+import com.android.pts.opengl.GLActivityIntentKeys;
+import com.android.pts.opengl.primitive.BenchmarkName;
+import com.android.pts.opengl.primitive.GLPrimitiveActivity;
+import com.android.pts.util.PtsActivityInstrumentationTestCase2;
+
+import android.content.Intent;
+
+public class JankTest extends PtsActivityInstrumentationTestCase2<GLPrimitiveActivity> {
+
+ public JankTest() {
+ super(GLPrimitiveActivity.class);
+ }
+
+ /**
+ * Runs the full OpenGL ES 2.0 pipeline test.
+ */
+ public void testFullPipeline() throws Exception {
+ runBenchmark(BenchmarkName.FullPipeline);
+ }
+
+ /**
+ * Runs the pixel output test.
+ */
+ public void testPixelOutput() throws Exception {
+ runBenchmark(BenchmarkName.PixelOutput);
+ }
+
+ /**
+ * Runs the shader performance test.
+ */
+ public void testShaderPerf() throws Exception {
+ runBenchmark(BenchmarkName.ShaderPerf);
+ }
+
+ /**
+ * Runs the context switch overhead test.
+ */
+ public void testContextSwitch() throws Exception {
+ runBenchmark(BenchmarkName.ContextSwitch);
+ }
+
+ /**
+ * Runs the benchhmark for jank test.
+ */
+ public void runBenchmark(BenchmarkName benchmark) throws Exception {
+ Intent intent = new Intent();
+ String benchmarkName = benchmark.toString();
+ intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_BENCHMARK_NAME, benchmarkName);
+ intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_OFFSCREEN, false);
+ intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_FRAMES, 200);
+ intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_ITERATIONS, 1);
+ intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_TIMEOUT, 50000);
+ GLPrimitiveActivity activity = null;
+ setActivityIntent(intent);
+ try {
+ activity = getActivity();
+ activity.waitForCompletion();
+ } finally {
+ if (activity != null) {
+ activity.finish();
+ }
+ }
+ }
+}
diff --git a/suite/pts/hostTests/jank/src/com/android/pts/jank/PtsHostJankTest.java b/suite/pts/hostTests/jank/src/com/android/pts/jank/PtsHostJankTest.java
index b12908a..85a8f5e 100644
--- a/suite/pts/hostTests/jank/src/com/android/pts/jank/PtsHostJankTest.java
+++ b/suite/pts/hostTests/jank/src/com/android/pts/jank/PtsHostJankTest.java
@@ -13,55 +13,184 @@
*/
package com.android.pts.jank;
-import android.util.Log;
-
-import com.android.uiautomator.core.UiDevice;
-import com.android.uiautomator.testrunner.UiAutomatorTestCase;
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.Log.LogLevel;
+import com.android.pts.util.HostReportLog;
+import com.android.pts.util.ReportLog;
+import com.android.pts.util.ResultType;
+import com.android.pts.util.ResultUnit;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.result.TestRunResult;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
import java.io.BufferedReader;
+import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.concurrent.Semaphore;
-import junit.framework.Assert;
+public class PtsHostJankTest extends DeviceTestCase implements IBuildReceiver {
-public class PtsHostJankTest extends UiAutomatorTestCase {
- private static final String TAG = PtsHostJankTest.class.getSimpleName();
- private static final int NUM_ITERATIONS = 5;
- private static final String APP_WINDOW_NAME =
- "SurfaceView";
- private static final String LAUNCH_COMMAND =
- "am start -a android.intent.action.MAIN -n com.android.pts.jank/.JankActivity -W";
+ private static final String TAG = "PtsHostJankTest";
+ private static final String CTS_RUNNER = "android.test.InstrumentationCtsTestRunner";
+ private static final String APP_WINDOW_NAME = "SurfaceView";
+ private static final String PACKAGE = "com.android.pts.jank";
+ private static final String APK = "PtsDeviceJankApp.apk";
private static final String CLEAR_BUFFER_CMD =
- "dumpsys SurfaceFlinger --latency-clear " + APP_WINDOW_NAME;
+ "adb -s %s shell dumpsys SurfaceFlinger --latency-clear %s";
private static final String FRAME_LATENCY_CMD =
- "dumpsys SurfaceFlinger --latency " + APP_WINDOW_NAME;
+ "adb -s %s shell dumpsys SurfaceFlinger --latency %s";
private static final long PENDING_FENCE_TIMESTAMP = (1L << 63) - 1;
+ private static final double MILLISECOND = 1E3;
+ private static final int REQ_NUM_DELTAS = 100;
- public void testGLReferenceBenchmark() throws Exception {
- // Launch the app.
- runShellCommand(LAUNCH_COMMAND);
+ private ArrayList<Double> mTimestamps = new ArrayList<Double>();
+ private double mRefreshPeriod;
+ private volatile int mNumDeltas = 0;
+ private volatile int mJankNumber = 0;
+ private volatile int mTotalJanks = 0;
+ private CtsBuildHelper mBuild;
+ private ITestDevice mDevice;
- // Wait till the device is idle.
- UiDevice device = UiDevice.getInstance();
- device.waitForIdle();
+ @Override
+ public void setBuild(IBuildInfo buildInfo) {
+ mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+ }
- // This is batch is important because this is where jank caused by loading textures and
- // meshes will be encountered. It also needs to be separated from the loop so that the
- // start button can be pressed.
- clearBuffer();
- // Touch screen, which starts the rendering.
- int width = device.getDisplayWidth();
- int height = device.getDisplayHeight();
- device.click(width / 2, height / 2);
- Thread.sleep(2000);
- dumpBuffer();
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mDevice = getDevice();
+ mDevice.uninstallPackage(PACKAGE);
+ File app = mBuild.getTestApp(APK);
+ mDevice.installPackage(app, false);
+ }
- // Loop because SurfaceFlinger's buffer is small.
- for (int i = 0; i < NUM_ITERATIONS; i++) {
- clearBuffer();
- Thread.sleep(2000);
- dumpBuffer();
+
+ @Override
+ protected void tearDown() throws Exception {
+ mDevice.uninstallPackage(PACKAGE);
+ super.tearDown();
+ }
+
+ public void testFullPipeline() throws Exception {
+ runGLPrimitiveBenchmark("testFullPipeline");
+ }
+
+ public void testPixelOutput() throws Exception {
+ runGLPrimitiveBenchmark("testPixelOutput");
+ }
+
+ public void testShaderPerf() throws Exception {
+ runGLPrimitiveBenchmark("testShaderPerf");
+ }
+
+ public void testContextSwitch() throws Exception {
+ runGLPrimitiveBenchmark("testContextSwitch");
+ }
+
+ public void runGLPrimitiveBenchmark(String benchmark) throws Exception {
+ // Collect timestamps.
+ final TimestampCollector worker = new TimestampCollector();
+ worker.start();
+
+ // Start the benchmark.
+ RemoteAndroidTestRunner testRunner =
+ new RemoteAndroidTestRunner(PACKAGE, CTS_RUNNER, mDevice.getIDevice());
+ testRunner.setMethodName("com.android.pts.jank.JankTest", benchmark);
+ CollectingTestListener listener = new CollectingTestListener();
+ mDevice.runInstrumentationTests(testRunner, listener);
+
+ // Wait for the worker.
+ worker.finish();
+
+ TestRunResult result = listener.getCurrentRunResults();
+ if (result.isRunFailure()) {
+ throw new Exception(result.getRunFailureMessage());
+ }
+
+ assertFalse("Couldn't get enough timestamps", needMoreDeltas());
+
+ // Create and deliver the report.
+ HostReportLog report = new HostReportLog(
+ mDevice.getSerialNumber(), PtsHostJankTest.class.getName() + "#" + benchmark);
+ report.printValue(
+ "Number of Janks", mJankNumber, ResultType.LOWER_BETTER, ResultUnit.COUNT);
+ report.printValue("Total Janks", mTotalJanks, ResultType.LOWER_BETTER, ResultUnit.COUNT);
+ double jankiness = ((double) mJankNumber / mNumDeltas) * 100.0;
+ report.printSummary(
+ "Jankiness Percentage", jankiness, ResultType.LOWER_BETTER, ResultUnit.SCORE);
+ report.deliverReportToHost();
+ }
+
+ private boolean needMoreDeltas() {
+ return mNumDeltas < REQ_NUM_DELTAS;
+ }
+
+ private void calcJank() {
+ final int numTimestamps = mTimestamps.size();
+ if (numTimestamps > 2) {
+ final int numIntervals = numTimestamps - 1;
+ double[] intervals = new double[numIntervals];
+ for (int i = 0; i < numIntervals; i++) {
+ intervals[i] = mTimestamps.get(i + 1) - mTimestamps.get(i);
+ }
+ final int numDeltas = Math.min(numIntervals - 1, REQ_NUM_DELTAS - mNumDeltas);
+ for (int i = 0; i < numDeltas; i++) {
+ double delta = intervals[i + 1] - intervals[i];
+ double normalizedDelta = delta / mRefreshPeriod;
+ // This makes delay over 1.5 * frameIntervalNomial a jank.
+ // Note that too big delay is not excluded here as there should be no pause.
+ int jankiness = (int) Math.round(Math.max(normalizedDelta, 0.0));
+ if (jankiness > 0) {
+ mJankNumber++;
+ Log.i(TAG, "Jank at frame " + (mNumDeltas + i));
+ }
+ mTotalJanks += jankiness;
+ }
+ mNumDeltas += numDeltas;
+ }
+ mTimestamps.clear();
+ }
+
+ private class TimestampCollector extends Thread {
+ private volatile Exception mException = null;
+ private volatile boolean mRunning = true;
+
+ public void run() {
+ try {
+ // Loop because SurfaceFlinger's buffer is small.
+ while (mRunning) {
+ clearBuffer();
+ Thread.sleep(2000);
+ dumpBuffer();
+ calcJank();
+ // Keep going till we have enough deltas
+ mRunning = needMoreDeltas();
+ }
+ } catch (Exception e) {
+ mException = e;
+ }
+ }
+
+ public void finish() throws Exception {
+ mRunning = false;
+ try {
+ join(20000);// Wait 20s for thread to join
+ } catch (InterruptedException e) {
+ // Nobody cares
+ }
+ // If there was an error, throw it.
+ if (mException != null) {
+ throw mException;
+ }
}
}
@@ -69,7 +198,8 @@
// Clear SurfaceFlinger latency buffer.
Process p = null;
try {
- p = runShellCommand(CLEAR_BUFFER_CMD);
+ p = runShellCommand(
+ String.format(CLEAR_BUFFER_CMD, mDevice.getSerialNumber(), APP_WINDOW_NAME));
} finally {
if (p != null) {
p.destroy();
@@ -82,16 +212,19 @@
// Dump SurfaceFlinger latency buffer.
Process p = null;
try {
- p = runShellCommand(FRAME_LATENCY_CMD);
+ p = runShellCommand(
+ String.format(FRAME_LATENCY_CMD, mDevice.getSerialNumber(), APP_WINDOW_NAME));
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = reader.readLine();
- long refreshPeriod = Long.parseLong(line.trim());
- while ((line = reader.readLine()) != null) {
- String[] values = line.split("\\s+");
- if (values.length == 3) {
- long timestamp = Long.parseLong(values[1]);
- if (timestamp != PENDING_FENCE_TIMESTAMP && timestamp != 0) {
- Log.i(TAG, "Timestamp: " + timestamp);
+ if (line != null) {
+ mRefreshPeriod = Long.parseLong(line.trim()) / 1e6;// Convert from ns to ms
+ while ((line = reader.readLine()) != null) {
+ String[] values = line.split("\\s+");
+ if (values.length == 3) {
+ long timestamp = Long.parseLong(values[1]);
+ if (timestamp != PENDING_FENCE_TIMESTAMP && timestamp != 0) {
+ mTimestamps.add(timestamp / 1e6);// Convert from ns to ms
+ }
}
}
}