summaryrefslogtreecommitdiff
path: root/apct-tests
diff options
context:
space:
mode:
Diffstat (limited to 'apct-tests')
-rw-r--r--apct-tests/perftests/core/AndroidTest.xml5
-rw-r--r--apct-tests/perftests/core/src/android/wm/WindowAddRemovePerfTest.java23
-rw-r--r--apct-tests/perftests/core/src/android/wm/WindowManagerPerfTestBase.java47
-rw-r--r--apct-tests/perftests/utils/src/android/perftests/utils/ManualBenchmarkState.java51
4 files changed, 118 insertions, 8 deletions
diff --git a/apct-tests/perftests/core/AndroidTest.xml b/apct-tests/perftests/core/AndroidTest.xml
index 1b289130124f..478cfc1fe811 100644
--- a/apct-tests/perftests/core/AndroidTest.xml
+++ b/apct-tests/perftests/core/AndroidTest.xml
@@ -25,4 +25,9 @@
<option name="package" value="com.android.perftests.core" />
<option name="hidden-api-checks" value="false"/>
</test>
+
+ <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+ <option name="directory-keys" value="/data/local/CorePerfTests" />
+ <option name="collect-on-run-ended-only" value="true" />
+ </metrics_collector>
</configuration>
diff --git a/apct-tests/perftests/core/src/android/wm/WindowAddRemovePerfTest.java b/apct-tests/perftests/core/src/android/wm/WindowAddRemovePerfTest.java
index 27790e649a26..a22a638fd32e 100644
--- a/apct-tests/perftests/core/src/android/wm/WindowAddRemovePerfTest.java
+++ b/apct-tests/perftests/core/src/android/wm/WindowAddRemovePerfTest.java
@@ -44,7 +44,11 @@ import org.junit.Rule;
import org.junit.Test;
@LargeTest
-public class WindowAddRemovePerfTest extends WindowManagerPerfTestBase {
+public class WindowAddRemovePerfTest extends WindowManagerPerfTestBase
+ implements ManualBenchmarkState.CustomizedIterationListener {
+
+ private static final int PROFILED_ITERATIONS = 2;
+
@Rule
public final PerfManualStatusReporter mPerfStatusReporter = new PerfManualStatusReporter();
@@ -59,10 +63,24 @@ public class WindowAddRemovePerfTest extends WindowManagerPerfTestBase {
sUiAutomation.dropShellPermissionIdentity();
}
+ /** The last {@link #PROFILED_ITERATIONS} will provide the information of method profiling. */
+ @Override
+ public void onStart(int iteration) {
+ startProfiling(WindowAddRemovePerfTest.class.getSimpleName()
+ + "_MethodTracing_" + iteration + ".trace");
+ }
+
+ @Override
+ public void onFinished(int iteration) {
+ stopProfiling();
+ }
+
@Test
@ManualBenchmarkTest(warmupDurationNs = TIME_1_S_IN_NS, targetTestDurationNs = TIME_5_S_IN_NS)
public void testAddRemoveWindow() throws Throwable {
- new TestWindow().runBenchmark(mPerfStatusReporter.getBenchmarkState());
+ final ManualBenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ state.setCustomizedIterations(PROFILED_ITERATIONS, this);
+ new TestWindow().runBenchmark(state);
}
private static class TestWindow extends BaseIWindow {
@@ -102,6 +120,7 @@ public class WindowAddRemovePerfTest extends WindowManagerPerfTestBase {
state.addExtraResult("remove", elapsedTimeNsOfRemove);
elapsedTimeNs = elapsedTimeNsOfAdd + elapsedTimeNsOfRemove;
+ inputChannel.dispose();
}
}
}
diff --git a/apct-tests/perftests/core/src/android/wm/WindowManagerPerfTestBase.java b/apct-tests/perftests/core/src/android/wm/WindowManagerPerfTestBase.java
index 4d278c3c2d9a..62e9ba84530c 100644
--- a/apct-tests/perftests/core/src/android/wm/WindowManagerPerfTestBase.java
+++ b/apct-tests/perftests/core/src/android/wm/WindowManagerPerfTestBase.java
@@ -21,6 +21,7 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat
import android.app.Activity;
import android.app.UiAutomation;
import android.content.Intent;
+import android.os.ParcelFileDescriptor;
import android.perftests.utils.PerfTestActivity;
import androidx.test.rule.ActivityTestRule;
@@ -32,6 +33,10 @@ import org.junit.BeforeClass;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
import java.util.concurrent.TimeUnit;
public class WindowManagerPerfTestBase {
@@ -40,16 +45,54 @@ public class WindowManagerPerfTestBase {
static final long TIME_1_S_IN_NS = 1 * NANOS_PER_S;
static final long TIME_5_S_IN_NS = 5 * NANOS_PER_S;
+ /**
+ * The out directory matching the directory-keys of collector in AndroidTest.xml. The directory
+ * is in /data because while enabling method profling of system server, it cannot write the
+ * trace to external storage.
+ */
+ static final File BASE_OUT_PATH = new File("/data/local/CorePerfTests");
+
@BeforeClass
public static void setUpOnce() {
+ if (!BASE_OUT_PATH.exists()) {
+ executeShellCommand("mkdir -p " + BASE_OUT_PATH);
+ }
// In order to be closer to the real use case.
- sUiAutomation.executeShellCommand("input keyevent KEYCODE_WAKEUP");
- sUiAutomation.executeShellCommand("wm dismiss-keyguard");
+ executeShellCommand("input keyevent KEYCODE_WAKEUP");
+ executeShellCommand("wm dismiss-keyguard");
getInstrumentation().getContext().startActivity(new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_HOME).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
/**
+ * Executes shell command with reading the output. It may also used to block until the current
+ * command is completed.
+ */
+ static ByteArrayOutputStream executeShellCommand(String command) {
+ final ParcelFileDescriptor pfd = sUiAutomation.executeShellCommand(command);
+ final byte[] buf = new byte[512];
+ final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ int bytesRead;
+ try (FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) {
+ while ((bytesRead = fis.read(buf)) != -1) {
+ bytes.write(buf, 0, bytesRead);
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return bytes;
+ }
+
+ /** Starts method tracing on system server. */
+ void startProfiling(String subPath) {
+ executeShellCommand("am profile start system " + new File(BASE_OUT_PATH, subPath));
+ }
+
+ void stopProfiling() {
+ executeShellCommand("am profile stop system");
+ }
+
+ /**
* Provides an activity that keeps screen on and is able to wait for a stable lifecycle stage.
*/
static class PerfTestActivityRule extends ActivityTestRule<PerfTestActivity> {
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/ManualBenchmarkState.java b/apct-tests/perftests/utils/src/android/perftests/utils/ManualBenchmarkState.java
index a83254b463f4..b07523976bfe 100644
--- a/apct-tests/perftests/utils/src/android/perftests/utils/ManualBenchmarkState.java
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/ManualBenchmarkState.java
@@ -88,6 +88,15 @@ public final class ManualBenchmarkState {
int[] percentiles() default {};
}
+ /** The interface to receive the events of customized iteration. */
+ public interface CustomizedIterationListener {
+ /** The customized iteration starts. */
+ void onStart(int iteration);
+
+ /** The customized iteration finished. */
+ void onFinished(int iteration);
+ }
+
/** It means the entire {@link StatsReport} is not given. */
private static final int DEFAULT_STATS_REPORT = -2;
@@ -105,7 +114,8 @@ public final class ManualBenchmarkState {
private static final int NOT_STARTED = 0; // The benchmark has not started yet.
private static final int WARMUP = 1; // The benchmark is warming up.
private static final int RUNNING = 2; // The benchmark is running.
- private static final int FINISHED = 3; // The benchmark has stopped.
+ private static final int RUNNING_CUSTOMIZED = 3; // Running for customized measurement.
+ private static final int FINISHED = 4; // The benchmark has stopped.
private int mState = NOT_STARTED; // Current benchmark state.
@@ -116,6 +126,14 @@ public final class ManualBenchmarkState {
private int mMaxIterations = 0;
+ /**
+ * Additinal iteration that used to apply customized measurement. The result during these
+ * iterations won't be counted into {@link #mStats}.
+ */
+ private int mMaxCustomizedIterations;
+ private int mCustomizedIterations;
+ private CustomizedIterationListener mCustomizedIterationListener;
+
// Individual duration in nano seconds.
private ArrayList<Long> mResults = new ArrayList<>();
@@ -189,10 +207,25 @@ public final class ManualBenchmarkState {
final boolean keepRunning = mResults.size() < mMaxIterations;
if (!keepRunning) {
mStats = new Stats(mResults);
+ if (mMaxCustomizedIterations > 0 && mCustomizedIterationListener != null) {
+ mState = RUNNING_CUSTOMIZED;
+ mCustomizedIterationListener.onStart(mCustomizedIterations);
+ return true;
+ }
mState = FINISHED;
}
return keepRunning;
}
+ case RUNNING_CUSTOMIZED: {
+ mCustomizedIterationListener.onFinished(mCustomizedIterations);
+ mCustomizedIterations++;
+ if (mCustomizedIterations >= mMaxCustomizedIterations) {
+ mState = FINISHED;
+ return false;
+ }
+ mCustomizedIterationListener.onStart(mCustomizedIterations);
+ return true;
+ }
case FINISHED:
throw new IllegalStateException("The benchmark has finished.");
default:
@@ -210,11 +243,21 @@ public final class ManualBenchmarkState {
}
/**
- * Adds additional result while this benchmark isn't warming up. It is used when a sequence of
- * operations is executed consecutively, the duration of each operation can also be recorded.
+ * This is used to run the benchmark with more information by enabling some debug mechanism but
+ * we don't want to account the special runs (slower) in the stats report.
+ */
+ public void setCustomizedIterations(int iterations, CustomizedIterationListener listener) {
+ mMaxCustomizedIterations = iterations;
+ mCustomizedIterationListener = listener;
+ }
+
+ /**
+ * Adds additional result while this benchmark isn't warming up or running in customized state.
+ * It is used when a sequence of operations is executed consecutively, the duration of each
+ * operation can also be recorded.
*/
public void addExtraResult(String key, long duration) {
- if (isWarmingUp()) {
+ if (isWarmingUp() || mState == RUNNING_CUSTOMIZED) {
return;
}
if (mExtraResults == null) {