From d26b5093b9a588e7835fc6e77ed4ff75adf785de Mon Sep 17 00:00:00 2001 From: Guang Zhu Date: Wed, 28 Jan 2015 19:08:43 -0800 Subject: enable customized reporting of final jank metrics Bug: 19125024 Change-Id: I14507c0476171490ddbc55836d314d907a2d8bfb --- src/android/support/test/jank/JankMetrics.java | 32 ++++++++++++++ src/android/support/test/jank/JankTest.java | 25 +++++++++-- src/android/support/test/jank/JankTestBase.java | 58 ++++++++++++++++++------- src/android/support/test/jank/JankUtil.java | 5 +-- 4 files changed, 97 insertions(+), 23 deletions(-) create mode 100644 src/android/support/test/jank/JankMetrics.java diff --git a/src/android/support/test/jank/JankMetrics.java b/src/android/support/test/jank/JankMetrics.java new file mode 100644 index 0000000..b227804 --- /dev/null +++ b/src/android/support/test/jank/JankMetrics.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2015 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 android.support.test.jank; + +/** + * {@link JankMetrics} contains aggregated {@link JankResult} after looped execution of a test case. + * + */ +public class JankMetrics { + /** average number of jank across iterations */ + public double averageJank; + /** max jank number among all iterations */ + public int maxJank; + /** average FPS across iterations */ + public double averageFps; + /** average of longest frame duration reported from all frames rendered for each iteration */ + public double averageMaxFrameDuration; +} diff --git a/src/android/support/test/jank/JankTest.java b/src/android/support/test/jank/JankTest.java index 1256ab7..67726ac 100644 --- a/src/android/support/test/jank/JankTest.java +++ b/src/android/support/test/jank/JankTest.java @@ -32,15 +32,32 @@ public @interface JankTest { /** The minimum number of frames expected */ int expectedFrames(); - /** Alternate method to execute before the test method */ + /** + * Alternate method to execute before the test method + *

+ * Note: the annotated method must have same signature as {@link JankTestBase#beforeTest()} + */ String beforeTest() default "beforeTest"; - /** Alternate method to execute before each iteration */ + /** + * Alternate method to execute before each iteration + *

+ * Note: the annotated method must have same signature as {@link JankTestBase#beforeLoop()} + */ String beforeLoop() default "beforeLoop"; - /** Alternate method to execute after each iteration */ + /** + * Alternate method to execute after each iteration + *

+ * Note: the annotated method must have same signature as {@link JankTestBase#afterLoop()} + */ String afterLoop() default "afterLoop"; - /** Alternate method to execute after all iterations have completed */ + /** + * Alternate method to execute after all iterations have completed. + *

+ * Important: the annotated method must take a parameter of type {@link JankMetrics}. + * See {@link JankTestBase#afterTest(JankMetrics)} + * */ String afterTest() default "afterTest"; } diff --git a/src/android/support/test/jank/JankTestBase.java b/src/android/support/test/jank/JankTestBase.java index e23e975..821090b 100644 --- a/src/android/support/test/jank/JankTestBase.java +++ b/src/android/support/test/jank/JankTestBase.java @@ -67,9 +67,19 @@ public class JankTestBase extends InstrumentationTestCase { // Default implementation. Do nothing. } - /** Called once after all iterations have completed. */ - public void afterTest() throws Exception { - // Default implementation. Do nothing. + /** + * Called once after all iterations have completed. + *

Note: default implementation reports the aggregated jank metrics via + * {@link Instrumentation#sendStatus(int, Bundle)} + * @param metrics the aggregated jank metrics after looped execution + * */ + public void afterTest(JankMetrics metrics) throws Exception { + Bundle status = new Bundle(); + status.putDouble(KEY_AVG_JANK, metrics.averageJank); + status.putInt(KEY_MAX_JANK, metrics.maxJank); + status.putDouble(KEY_AVG_FPS, metrics.averageFps); + status.putDouble(KEY_AVG_MAX_FRAME_DURATION, metrics.averageMaxFrameDuration); + getInstrumentation().sendStatus(Activity.RESULT_OK, status); } /** Return the index of the currently executing iteration. */ @@ -77,7 +87,6 @@ public class JankTestBase extends InstrumentationTestCase { return mCurrentIteration; } - @Override protected final void runTest() throws Throwable { @@ -87,7 +96,7 @@ public class JankTestBase extends InstrumentationTestCase { Method beforeTest = resolveMethod(annotation.beforeTest()); Method beforeLoop = resolveMethod(annotation.beforeLoop()); Method afterLoop = resolveMethod(annotation.afterLoop()); - Method afterTest = resolveMethod(annotation.afterTest()); + Method afterTest = resolveAfterTest(annotation.afterTest()); // Get a JankUtil instance JankUtil jank = JankUtil.getInstance(getInstrumentation()); @@ -132,16 +141,14 @@ public class JankTestBase extends InstrumentationTestCase { afterLoop.invoke(this, (Object[])null); } - // Test tear down - afterTest.invoke(this, (Object[])null); - - // Report results - Bundle status = new Bundle(); - status.putDouble(KEY_AVG_JANK, (double)sumJankyFrames / iterations); - status.putInt(KEY_MAX_JANK, maxJankyFrames); - status.putDouble(KEY_AVG_FPS, sumFps / iterations); - status.putDouble(KEY_AVG_MAX_FRAME_DURATION, sumLongestFrame / iterations); - getInstrumentation().sendStatus(Activity.RESULT_OK, status); + // Report aggregated results + JankMetrics metrics = new JankMetrics(); + metrics.averageJank = (double)sumJankyFrames / iterations; + metrics.maxJank = maxJankyFrames; + metrics.averageFps = sumFps / iterations; + metrics.averageMaxFrameDuration = sumLongestFrame / iterations; + // Test tear down and reporting + afterTest.invoke(this, metrics); } @@ -163,6 +170,27 @@ public class JankTestBase extends InstrumentationTestCase { return method; } + /** + * Returns a {@link Method}} object representing the method annotated with + * {@link JankTest#afterTest()}. + */ + private Method resolveAfterTest(String name) { + assertNotNull(name); + + Method method = null; + try { + method = getClass().getMethod(name, JankMetrics.class); + } catch (NoSuchMethodException e) { + fail("method annotated with JankTest#afterTest has wrong signature"); + } + + if (!Modifier.isPublic(method.getModifiers())) { + fail(String.format("Method \"%s\" should be public", name)); + } + + return method; + } + /** Returns a {@link Bundle} containing the command line parameters. */ protected final Bundle getArguments() { if (arguments == null) { diff --git a/src/android/support/test/jank/JankUtil.java b/src/android/support/test/jank/JankUtil.java index 7f63174..d433d98 100644 --- a/src/android/support/test/jank/JankUtil.java +++ b/src/android/support/test/jank/JankUtil.java @@ -20,11 +20,8 @@ import android.accessibilityservice.AccessibilityServiceInfo; import android.app.Instrumentation; import android.app.UiAutomation; import android.util.Log; -import android.view.accessibility.AccessibilityWindowInfo; import android.view.FrameStats; - -import java.util.HashMap; -import java.util.Map; +import android.view.accessibility.AccessibilityWindowInfo; /** The {@link JankUtil} class provides functionality for monitoring jank. */ public class JankUtil { -- cgit v1.2.3