Add performance test for BroadcastReceiver
This is intended to be the first of multiple performance tests around ActivityManager. This also refactors some of the existing performance utils so that a BenchmarkState which accepts the elapsed time rather than measures it can be added (ManualBenchmarkState). This test measures the current time, sends a Broadcast, the target APK receives it, measures the current time, and sends its measured time back to the test APK. Test: m ActivityManagerPerfTestsTestApp ActivityManagerPerfTests Test: adb install $OUT/data/app/ActivityManagerPerfTestsTestApp/ActivityManagerPerfTestsTestApp.apk Test: adb install $OUT/data/app/ActivityManagerPerfTests/ActivityManagerPerfTests.apk Test: adb shell am instrument -w -e class \ com.android.frameworks.perftests.am.tests.BroadcastPerfTest \ com.android.frameworks.perftests.amtests/android.support.test.runner.AndroidJUnitRunner Bug: 67460485 Change-Id: Ib1606ff60c6a845088bde5bd1a33294765b88b36
This commit is contained in:
@@ -25,7 +25,6 @@ import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@@ -78,10 +77,7 @@ public final class BenchmarkState {
|
||||
|
||||
// Statistics. These values will be filled when the benchmark has finished.
|
||||
// The computation needs double precision, but long int is fine for final reporting.
|
||||
private long mMedian = 0;
|
||||
private double mMean = 0.0;
|
||||
private double mStandardDeviation = 0.0;
|
||||
private long mMin = 0;
|
||||
private Stats mStats;
|
||||
|
||||
// Individual duration in nano seconds.
|
||||
private ArrayList<Long> mResults = new ArrayList<>();
|
||||
@@ -90,36 +86,6 @@ public final class BenchmarkState {
|
||||
return TimeUnit.MILLISECONDS.toNanos(ms);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates statistics.
|
||||
*/
|
||||
private void calculateSatistics() {
|
||||
final int size = mResults.size();
|
||||
if (size <= 1) {
|
||||
throw new IllegalStateException("At least two results are necessary.");
|
||||
}
|
||||
|
||||
Collections.sort(mResults);
|
||||
mMedian = size % 2 == 0 ? (mResults.get(size / 2) + mResults.get(size / 2 + 1)) / 2 :
|
||||
mResults.get(size / 2);
|
||||
|
||||
mMin = mResults.get(0);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
long result = mResults.get(i);
|
||||
mMean += result;
|
||||
if (result < mMin) {
|
||||
mMin = result;
|
||||
}
|
||||
}
|
||||
mMean /= (double) size;
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
final double tmp = mResults.get(i) - mMean;
|
||||
mStandardDeviation += tmp * tmp;
|
||||
}
|
||||
mStandardDeviation = Math.sqrt(mStandardDeviation / (double) (size - 1));
|
||||
}
|
||||
|
||||
// Stops the benchmark timer.
|
||||
// This method can be called only when the timer is running.
|
||||
public void pauseTiming() {
|
||||
@@ -173,7 +139,7 @@ public final class BenchmarkState {
|
||||
if (ENABLE_PROFILING) {
|
||||
Debug.stopMethodTracing();
|
||||
}
|
||||
calculateSatistics();
|
||||
mStats = new Stats(mResults);
|
||||
mState = FINISHED;
|
||||
return false;
|
||||
}
|
||||
@@ -224,28 +190,28 @@ public final class BenchmarkState {
|
||||
if (mState != FINISHED) {
|
||||
throw new IllegalStateException("The benchmark hasn't finished");
|
||||
}
|
||||
return (long) mMean;
|
||||
return (long) mStats.getMean();
|
||||
}
|
||||
|
||||
private long median() {
|
||||
if (mState != FINISHED) {
|
||||
throw new IllegalStateException("The benchmark hasn't finished");
|
||||
}
|
||||
return mMedian;
|
||||
return mStats.getMedian();
|
||||
}
|
||||
|
||||
private long min() {
|
||||
if (mState != FINISHED) {
|
||||
throw new IllegalStateException("The benchmark hasn't finished");
|
||||
}
|
||||
return mMin;
|
||||
return mStats.getMin();
|
||||
}
|
||||
|
||||
private long standardDeviation() {
|
||||
if (mState != FINISHED) {
|
||||
throw new IllegalStateException("The benchmark hasn't finished");
|
||||
}
|
||||
return (long) mStandardDeviation;
|
||||
return (long) mStats.getStandardDeviation();
|
||||
}
|
||||
|
||||
private String summaryLine() {
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* 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 android.perftests.utils;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Instrumentation;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Provides a benchmark framework.
|
||||
*
|
||||
* This differs from BenchmarkState in that rather than the class measuring the the elapsed time,
|
||||
* the test passes in the elapsed time.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* public void sampleMethod() {
|
||||
* ManualBenchmarkState state = new ManualBenchmarkState();
|
||||
*
|
||||
* int[] src = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
||||
* long elapsedTime = 0;
|
||||
* while (state.keepRunning(elapsedTime)) {
|
||||
* long startTime = System.nanoTime();
|
||||
* int[] dest = new int[src.length];
|
||||
* System.arraycopy(src, 0, dest, 0, src.length);
|
||||
* elapsedTime = System.nanoTime() - startTime;
|
||||
* }
|
||||
* System.out.println(state.summaryLine());
|
||||
* }
|
||||
*
|
||||
* Or use the PerfManualStatusReporter TestRule.
|
||||
*
|
||||
* Make sure that the overhead of checking the clock does not noticeably affect the results.
|
||||
*/
|
||||
public final class ManualBenchmarkState {
|
||||
private static final String TAG = ManualBenchmarkState.class.getSimpleName();
|
||||
|
||||
// TODO: Tune these values.
|
||||
// warm-up for duration
|
||||
private static final long WARMUP_DURATION_NS = TimeUnit.SECONDS.toNanos(5);
|
||||
// minimum iterations to warm-up for
|
||||
private static final int WARMUP_MIN_ITERATIONS = 8;
|
||||
|
||||
// target testing for duration
|
||||
private static final long TARGET_TEST_DURATION_NS = TimeUnit.SECONDS.toNanos(16);
|
||||
private static final int MAX_TEST_ITERATIONS = 1000000;
|
||||
private static final int MIN_TEST_ITERATIONS = 10;
|
||||
|
||||
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 int mState = NOT_STARTED; // Current benchmark state.
|
||||
|
||||
private long mWarmupStartTime = 0;
|
||||
private int mWarmupIterations = 0;
|
||||
|
||||
private int mMaxIterations = 0;
|
||||
|
||||
// Individual duration in nano seconds.
|
||||
private ArrayList<Long> mResults = new ArrayList<>();
|
||||
|
||||
// Statistics. These values will be filled when the benchmark has finished.
|
||||
// The computation needs double precision, but long int is fine for final reporting.
|
||||
private Stats mStats;
|
||||
|
||||
private void beginBenchmark(long warmupDuration, int iterations) {
|
||||
mMaxIterations = (int) (TARGET_TEST_DURATION_NS / (warmupDuration / iterations));
|
||||
mMaxIterations = Math.min(MAX_TEST_ITERATIONS,
|
||||
Math.max(mMaxIterations, MIN_TEST_ITERATIONS));
|
||||
mState = RUNNING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Judges whether the benchmark needs more samples.
|
||||
*
|
||||
* For the usage, see class comment.
|
||||
*/
|
||||
public boolean keepRunning(long duration) {
|
||||
if (duration < 0) {
|
||||
throw new RuntimeException("duration is negative: " + duration);
|
||||
}
|
||||
switch (mState) {
|
||||
case NOT_STARTED:
|
||||
mState = WARMUP;
|
||||
mWarmupStartTime = System.nanoTime();
|
||||
return true;
|
||||
case WARMUP: {
|
||||
final long timeSinceStartingWarmup = System.nanoTime() - mWarmupStartTime;
|
||||
++mWarmupIterations;
|
||||
if (mWarmupIterations >= WARMUP_MIN_ITERATIONS
|
||||
&& timeSinceStartingWarmup >= WARMUP_DURATION_NS) {
|
||||
beginBenchmark(timeSinceStartingWarmup, mWarmupIterations);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case RUNNING: {
|
||||
mResults.add(duration);
|
||||
final boolean keepRunning = mResults.size() < mMaxIterations;
|
||||
if (!keepRunning) {
|
||||
mStats = new Stats(mResults);
|
||||
mState = FINISHED;
|
||||
}
|
||||
return keepRunning;
|
||||
}
|
||||
case FINISHED:
|
||||
throw new IllegalStateException("The benchmark has finished.");
|
||||
default:
|
||||
throw new IllegalStateException("The benchmark is in an unknown state.");
|
||||
}
|
||||
}
|
||||
|
||||
private String summaryLine() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("Summary: ");
|
||||
sb.append("median=").append(mStats.getMedian()).append("ns, ");
|
||||
sb.append("mean=").append(mStats.getMean()).append("ns, ");
|
||||
sb.append("min=").append(mStats.getMin()).append("ns, ");
|
||||
sb.append("max=").append(mStats.getMax()).append("ns, ");
|
||||
sb.append("sigma=").append(mStats.getStandardDeviation()).append(", ");
|
||||
sb.append("iteration=").append(mResults.size()).append(", ");
|
||||
sb.append("values=").append(mResults.toString());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void sendFullStatusReport(Instrumentation instrumentation, String key) {
|
||||
if (mState != FINISHED) {
|
||||
throw new IllegalStateException("The benchmark hasn't finished");
|
||||
}
|
||||
Log.i(TAG, key + summaryLine());
|
||||
final Bundle status = new Bundle();
|
||||
status.putLong(key + "_median", mStats.getMedian());
|
||||
status.putLong(key + "_mean", (long) mStats.getMean());
|
||||
status.putLong(key + "_stddev", (long) mStats.getStandardDeviation());
|
||||
instrumentation.sendStatus(Activity.RESULT_OK, status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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 android.perftests.utils;
|
||||
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
/**
|
||||
* Use this rule to make sure we report the status after the test success.
|
||||
*
|
||||
* <code>
|
||||
*
|
||||
* @Rule public PerfManualStatusReporter mPerfStatusReporter = new PerfManualStatusReporter();
|
||||
* @Test public void functionName() {
|
||||
* ManualBenchmarkState state = mPerfStatusReporter.getBenchmarkState();
|
||||
*
|
||||
* int[] src = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
||||
* long elapsedTime = 0;
|
||||
* while (state.keepRunning(elapsedTime)) {
|
||||
* long startTime = System.nanoTime();
|
||||
* int[] dest = new int[src.length];
|
||||
* System.arraycopy(src, 0, dest, 0, src.length);
|
||||
* elapsedTime = System.nanoTime() - startTime;
|
||||
* }
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* When test succeeded, the status report will use the key as
|
||||
* "functionName_*"
|
||||
*/
|
||||
|
||||
public class PerfManualStatusReporter implements TestRule {
|
||||
private final ManualBenchmarkState mState;
|
||||
|
||||
public PerfManualStatusReporter() {
|
||||
mState = new ManualBenchmarkState();
|
||||
}
|
||||
|
||||
public ManualBenchmarkState getBenchmarkState() {
|
||||
return mState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement apply(Statement base, Description description) {
|
||||
return new Statement() {
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
base.evaluate();
|
||||
|
||||
mState.sendFullStatusReport(InstrumentationRegistry.getInstrumentation(),
|
||||
description.getMethodName());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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 android.perftests.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Stats {
|
||||
private long mMedian, mMin, mMax;
|
||||
private double mMean, mStandardDeviation;
|
||||
|
||||
/* Calculate stats in constructor. */
|
||||
public Stats(List<Long> values) {
|
||||
// make a copy since we're modifying it
|
||||
values = new ArrayList<>(values);
|
||||
final int size = values.size();
|
||||
if (size < 2) {
|
||||
throw new IllegalArgumentException("At least two results are necessary.");
|
||||
}
|
||||
|
||||
Collections.sort(values);
|
||||
|
||||
mMedian = size % 2 == 0 ? (values.get(size / 2) + values.get(size / 2 - 1)) / 2 :
|
||||
values.get(size / 2);
|
||||
|
||||
mMin = values.get(0);
|
||||
mMax = values.get(values.size() - 1);
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
long result = values.get(i);
|
||||
mMean += result;
|
||||
}
|
||||
mMean /= (double) size;
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
final double tmp = values.get(i) - mMean;
|
||||
mStandardDeviation += tmp * tmp;
|
||||
}
|
||||
mStandardDeviation = Math.sqrt(mStandardDeviation / (double) (size - 1));
|
||||
}
|
||||
|
||||
public double getMean() {
|
||||
return mMean;
|
||||
}
|
||||
|
||||
public long getMedian() {
|
||||
return mMedian;
|
||||
}
|
||||
|
||||
public long getMax() {
|
||||
return mMax;
|
||||
}
|
||||
|
||||
public long getMin() {
|
||||
return mMin;
|
||||
}
|
||||
|
||||
public double getStandardDeviation() {
|
||||
return mStandardDeviation;
|
||||
}
|
||||
}
|
||||
34
tests/ActivityManagerPerfTests/README.txt
Normal file
34
tests/ActivityManagerPerfTests/README.txt
Normal file
@@ -0,0 +1,34 @@
|
||||
ActivityManagerPerfTests
|
||||
|
||||
Performance tests for various ActivityManager components, e.g. Services, Broadcasts
|
||||
|
||||
Command to run tests (not working yet, atest seems buggy)
|
||||
* atest .../frameworks/base/tests/ActivityManagerPerfTests
|
||||
* m ActivityManagerPerfTests ActivityManagerPerfTestsTestApp && \
|
||||
adb install $OUT/data/app/ActivityManagerPerfTests/ActivityManagerPerfTests.apk && \
|
||||
adb install $OUT/data/app/ActivityManagerPerfTestsTestApp/ActivityManagerPerfTestsTestApp.apk && \
|
||||
adb shell am instrument -w \
|
||||
com.android.frameworks.perftests.amtests/android.support.test.runner.AndroidJUnitRunner
|
||||
|
||||
Overview
|
||||
* The numbers we are trying to measure are end-to-end numbers
|
||||
* For example, the time it takes from sending an Intent to start a Service
|
||||
to the time the Service runs its callbacks
|
||||
* System.nanoTime() is monotonic and consistent between processes, so we use that for measuring time
|
||||
* To make sure the test app is running, we start an Activity
|
||||
* If the test app is involved, it will measure the time and send it back to the instrumentation test
|
||||
* The time is sent back through a Binder interface in the Intent
|
||||
* Each sent time is tagged with an id since there can be multiple events that send back a time
|
||||
* For example, one is sent when the Activity is started, and another could be sent when a
|
||||
Broadcast is received
|
||||
|
||||
Structure
|
||||
* tests
|
||||
* Instrumentation test which runs the various performance tests and reports the results
|
||||
|
||||
* test-app
|
||||
* Target package which contains the Services, BroadcastReceivers, etc. to test against
|
||||
* Sends the time it measures back to the test package
|
||||
|
||||
* utils
|
||||
* Utilities that both the instrumentation test and test app can use
|
||||
28
tests/ActivityManagerPerfTests/test-app/Android.mk
Normal file
28
tests/ActivityManagerPerfTests/test-app/Android.mk
Normal file
@@ -0,0 +1,28 @@
|
||||
# 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.
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(call all-java-files-under, src)
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||
ActivityManagerPerfTestsUtils
|
||||
|
||||
LOCAL_PACKAGE_NAME := ActivityManagerPerfTestsTestApp
|
||||
|
||||
include $(BUILD_PACKAGE)
|
||||
29
tests/ActivityManagerPerfTests/test-app/AndroidManifest.xml
Normal file
29
tests/ActivityManagerPerfTests/test-app/AndroidManifest.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.frameworks.perftests.amteststestapp">
|
||||
<application android:name=".TestApplication">
|
||||
<activity android:name=".TestActivity" android:exported="true"/>
|
||||
<receiver
|
||||
android:name=".TestBroadcastReceiver"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="com.android.frameworks.perftests.ACTION_BROADCAST_MANIFEST_RECEIVE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.frameworks.perftests.amteststestapp;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.android.frameworks.perftests.am.util.Constants;
|
||||
import com.android.frameworks.perftests.am.util.Utils;
|
||||
|
||||
public class TestActivity extends Activity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
Utils.sendTime(getIntent(), Constants.TYPE_ACTIVITY_CREATED);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.frameworks.perftests.amteststestapp;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.frameworks.perftests.am.util.Constants;
|
||||
import com.android.frameworks.perftests.am.util.Utils;
|
||||
|
||||
public class TestApplication extends Application {
|
||||
private static final String TAG = TestApplication.class.getSimpleName();
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
createRegisteredReceiver();
|
||||
|
||||
super.onCreate();
|
||||
}
|
||||
|
||||
// Create registered BroadcastReceiver
|
||||
private void createRegisteredReceiver() {
|
||||
BroadcastReceiver registered = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Log.i(TAG, "RegisteredReceiver.onReceive");
|
||||
Utils.sendTime(intent, Constants.TYPE_BROADCAST_RECEIVE);
|
||||
}
|
||||
};
|
||||
IntentFilter intentFilter = new IntentFilter(Constants.ACTION_BROADCAST_REGISTERED_RECEIVE);
|
||||
registerReceiver(registered, intentFilter);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.frameworks.perftests.amteststestapp;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.frameworks.perftests.am.util.Constants;
|
||||
import com.android.frameworks.perftests.am.util.Utils;
|
||||
|
||||
public class TestBroadcastReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Utils.sendTime(intent, Constants.TYPE_BROADCAST_RECEIVE);
|
||||
}
|
||||
}
|
||||
33
tests/ActivityManagerPerfTests/tests/Android.mk
Normal file
33
tests/ActivityManagerPerfTests/tests/Android.mk
Normal file
@@ -0,0 +1,33 @@
|
||||
# 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.
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(call all-java-files-under, src)
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||
android-support-test \
|
||||
apct-perftests-utils \
|
||||
ActivityManagerPerfTestsUtils
|
||||
|
||||
LOCAL_PACKAGE_NAME := ActivityManagerPerfTests
|
||||
|
||||
# For android.permission.FORCE_STOP_PACKAGES permission
|
||||
LOCAL_CERTIFICATE := platform
|
||||
|
||||
include $(BUILD_PACKAGE)
|
||||
27
tests/ActivityManagerPerfTests/tests/AndroidManifest.xml
Normal file
27
tests/ActivityManagerPerfTests/tests/AndroidManifest.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.frameworks.perftests.amtests">
|
||||
<uses-permission android:name="android.permission.DUMP" />
|
||||
<uses-permission android:name="android.permission.FORCE_STOP_PACKAGES" />
|
||||
|
||||
<application>
|
||||
<uses-library android:name="android.test.runner" />
|
||||
</application>
|
||||
|
||||
<instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
|
||||
android:targetPackage="com.android.frameworks.perftests.amtests"/>
|
||||
</manifest>
|
||||
29
tests/ActivityManagerPerfTests/tests/AndroidTest.xml
Normal file
29
tests/ActivityManagerPerfTests/tests/AndroidTest.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<configuration description="Runs ActivityManager Performance Tests">
|
||||
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
|
||||
<option name="test-file-name" value="ActivityManagerPerfTests.apk"/>
|
||||
<option name="test-file-name" value="ActivityManagerPerfTestsTestApp.apk"/>
|
||||
<option name="cleanup-apks" value="true"/>
|
||||
</target_preparer>
|
||||
|
||||
<option name="test-suite-tag" value="apct"/>
|
||||
<option name="test-tag" value="ActivityManagerPerfTests"/>
|
||||
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
|
||||
<option name="package" value="com.android.frameworks.perftests.amtests"/>
|
||||
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
|
||||
</test>
|
||||
</configuration>
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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.frameworks.perftests.am.tests;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.perftests.utils.ManualBenchmarkState;
|
||||
import android.perftests.utils.PerfManualStatusReporter;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
|
||||
import com.android.frameworks.perftests.am.util.TargetPackageUtils;
|
||||
import com.android.frameworks.perftests.am.util.TimeReceiver;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
|
||||
import java.util.function.LongSupplier;
|
||||
|
||||
public class BasePerfTest {
|
||||
private static final String TAG = BasePerfTest.class.getSimpleName();
|
||||
|
||||
private TimeReceiver mTimeReceiver;
|
||||
|
||||
@Rule
|
||||
public PerfManualStatusReporter mPerfManualStatusReporter = new PerfManualStatusReporter();
|
||||
|
||||
protected Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = InstrumentationRegistry.getTargetContext();
|
||||
mTimeReceiver = new TimeReceiver();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
TargetPackageUtils.killTargetPackage(mContext);
|
||||
}
|
||||
|
||||
protected Intent createIntent(String action) {
|
||||
final Intent intent = new Intent(action);
|
||||
intent.addFlags(
|
||||
Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND | Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
||||
intent.putExtras(mTimeReceiver.createReceiveTimeExtraBinder());
|
||||
return intent;
|
||||
}
|
||||
|
||||
private void setUpIteration() {
|
||||
mTimeReceiver.clear();
|
||||
TargetPackageUtils.killTargetPackage(mContext);
|
||||
}
|
||||
|
||||
protected void startTargetPackage() {
|
||||
TargetPackageUtils.startTargetPackage(mContext, mTimeReceiver);
|
||||
}
|
||||
|
||||
protected long getReceivedTimeNs(String type) {
|
||||
return mTimeReceiver.getReceivedTimeNs(type);
|
||||
}
|
||||
|
||||
protected void runPerfFunction(LongSupplier func) {
|
||||
final ManualBenchmarkState benchmarkState = mPerfManualStatusReporter.getBenchmarkState();
|
||||
long elapsedTimeNs = 0;
|
||||
while (benchmarkState.keepRunning(elapsedTimeNs)) {
|
||||
setUpIteration();
|
||||
elapsedTimeNs = func.getAsLong();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.frameworks.perftests.am.tests;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.support.test.filters.LargeTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.frameworks.perftests.am.util.Constants;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@LargeTest
|
||||
public class BroadcastPerfTest extends BasePerfTest {
|
||||
@Test
|
||||
public void manifestBroadcastRunning() {
|
||||
runPerfFunction(() -> {
|
||||
startTargetPackage();
|
||||
|
||||
final Intent intent = createIntent(Constants.ACTION_BROADCAST_MANIFEST_RECEIVE);
|
||||
|
||||
final long startTime = System.nanoTime();
|
||||
|
||||
mContext.sendBroadcast(intent);
|
||||
|
||||
final long endTime = getReceivedTimeNs(Constants.TYPE_BROADCAST_RECEIVE);
|
||||
|
||||
return endTime - startTime;
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void manifestBroadcastNotRunning() {
|
||||
runPerfFunction(() -> {
|
||||
final Intent intent = createIntent(Constants.ACTION_BROADCAST_MANIFEST_RECEIVE);
|
||||
|
||||
final long startTime = System.nanoTime();
|
||||
|
||||
mContext.sendBroadcast(intent);
|
||||
|
||||
final long endTime = getReceivedTimeNs(Constants.TYPE_BROADCAST_RECEIVE);
|
||||
|
||||
return endTime - startTime;
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void registeredBroadcast() {
|
||||
runPerfFunction(() -> {
|
||||
startTargetPackage();
|
||||
|
||||
final Intent intent = createIntent(Constants.ACTION_BROADCAST_REGISTERED_RECEIVE);
|
||||
|
||||
final long startTime = System.nanoTime();
|
||||
|
||||
mContext.sendBroadcast(intent);
|
||||
|
||||
final long endTime = getReceivedTimeNs(Constants.TYPE_BROADCAST_RECEIVE);
|
||||
|
||||
return endTime - startTime;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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.frameworks.perftests.am.util;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.SystemClock;
|
||||
|
||||
public class TargetPackageUtils {
|
||||
private static final String TAG = TargetPackageUtils.class.getSimpleName();
|
||||
|
||||
public static final String PACKAGE_NAME = "com.android.frameworks.perftests.amteststestapp";
|
||||
public static final String ACTIVITY_NAME = PACKAGE_NAME + ".TestActivity";
|
||||
|
||||
private static final long WAIT_TIME_MS = 100L;
|
||||
|
||||
// Cache for test app's uid, so we only have to query it once.
|
||||
private static int sTestAppUid = -1;
|
||||
|
||||
/**
|
||||
* Kills the test package synchronously.
|
||||
*/
|
||||
public static void killTargetPackage(Context context) {
|
||||
ActivityManager activityManager = context.getSystemService(ActivityManager.class);
|
||||
activityManager.forceStopPackage(PACKAGE_NAME);
|
||||
while (targetPackageIsRunning(context)) {
|
||||
sleep();
|
||||
}
|
||||
|
||||
Utils.drainBroadcastQueue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the test package synchronously. It does so by starting an Activity.
|
||||
*/
|
||||
public static void startTargetPackage(Context context, TimeReceiver timeReceiver) {
|
||||
// "am start-activity -W PACKAGE_NAME/ACTIVITY_CLASS_NAME" still requires a sleep even
|
||||
// though it should be synchronous, so just use Intent instead
|
||||
final Intent intent = new Intent();
|
||||
intent.putExtras(timeReceiver.createReceiveTimeExtraBinder());
|
||||
intent.setClassName(PACKAGE_NAME, ACTIVITY_NAME);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
|
||||
while (!targetPackageIsRunning(context)) {
|
||||
sleep();
|
||||
}
|
||||
// make sure Application has run
|
||||
timeReceiver.getReceivedTimeNs(Constants.TYPE_ACTIVITY_CREATED);
|
||||
Utils.drainBroadcastQueue();
|
||||
}
|
||||
|
||||
private static boolean targetPackageIsRunning(Context context) {
|
||||
final int uid = getTestAppUid(context);
|
||||
final String result = Utils.runShellCommand(
|
||||
String.format("cmd activity get-uid-state %d", uid));
|
||||
return !result.contains("(NONEXISTENT)");
|
||||
}
|
||||
|
||||
private static void sleep() {
|
||||
SystemClock.sleep(WAIT_TIME_MS);
|
||||
}
|
||||
|
||||
private static int getTestAppUid(Context context) {
|
||||
if (sTestAppUid == -1) {
|
||||
final PackageManager pm = context.getPackageManager();
|
||||
try {
|
||||
sTestAppUid = pm.getPackageUid(PACKAGE_NAME, 0);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return sTestAppUid;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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.frameworks.perftests.am.util;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
/**
|
||||
* TimeReceiver will listen for any messages containing a timestamp by starting a BroadcastReceiver
|
||||
* which listens for Intents with the SendTime.ACTION_SEND_TIME action.
|
||||
*/
|
||||
public class TimeReceiver {
|
||||
private static final String TAG = TimeReceiver.class.getSimpleName();
|
||||
private static final long DEFAULT_RECEIVE_TIME_TIMEOUT_MILLIS = 10000L;
|
||||
|
||||
private BlockingQueue<ReceivedMessage> mQueue = new LinkedBlockingQueue<>();
|
||||
|
||||
private static class ReceivedMessage {
|
||||
private final String mReceivedMessageType;
|
||||
private final long mReceivedTimeNs;
|
||||
|
||||
public ReceivedMessage(String receivedMessageType, long receivedTimeNs) {
|
||||
mReceivedMessageType = receivedMessageType;
|
||||
mReceivedTimeNs = receivedTimeNs;
|
||||
}
|
||||
}
|
||||
|
||||
public Bundle createReceiveTimeExtraBinder() {
|
||||
Bundle extras = new Bundle();
|
||||
extras.putBinder(Constants.EXTRA_RECEIVER_CALLBACK, new ITimeReceiverCallback.Stub() {
|
||||
@Override
|
||||
public void sendTime(String type, long timeNs) throws RemoteException {
|
||||
if (type == null) {
|
||||
throw new RuntimeException("receivedType is null");
|
||||
}
|
||||
if (timeNs < 0) {
|
||||
throw new RuntimeException(
|
||||
"receivedTime is negative/non-existant: " + timeNs);
|
||||
}
|
||||
Log.i(TAG, type + " " + timeNs);
|
||||
mQueue.add(new ReceivedMessage(type, timeNs));
|
||||
}
|
||||
});
|
||||
return extras;
|
||||
}
|
||||
|
||||
public long getReceivedTimeNs(String type) {
|
||||
return getReceivedTimeNs(type, DEFAULT_RECEIVE_TIME_TIMEOUT_MILLIS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a received timestamp with the given type tag. Will throw away any messages with a
|
||||
* different type tag. If it times out, a RuntimeException is thrown.
|
||||
*/
|
||||
public long getReceivedTimeNs(String type, long timeoutMs) {
|
||||
ReceivedMessage message;
|
||||
long endTimeNs = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(timeoutMs);
|
||||
do {
|
||||
long curTimeNs = System.nanoTime();
|
||||
if (curTimeNs > endTimeNs) {
|
||||
throw new RuntimeException("Timed out when listening for a time: " + type);
|
||||
}
|
||||
try {
|
||||
Log.i(TAG, "waiting for message " + type);
|
||||
message = mQueue.poll(endTimeNs - curTimeNs, TimeUnit.NANOSECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (message == null) {
|
||||
throw new RuntimeException("Timed out when listening for a time: " + type);
|
||||
}
|
||||
Log.i(TAG, "got message " + message.mReceivedMessageType);
|
||||
if (!type.equals(message.mReceivedMessageType)) {
|
||||
Log.i(TAG, String.format("Expected type \"%s\", got \"%s\" (%d), skipping", type,
|
||||
message.mReceivedMessageType, message.mReceivedTimeNs));
|
||||
}
|
||||
} while (!type.equals(message.mReceivedMessageType));
|
||||
return message.mReceivedTimeNs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the message queue.
|
||||
*/
|
||||
public void clear() {
|
||||
mQueue.clear();
|
||||
}
|
||||
}
|
||||
31
tests/ActivityManagerPerfTests/utils/Android.mk
Normal file
31
tests/ActivityManagerPerfTests/utils/Android.mk
Normal file
@@ -0,0 +1,31 @@
|
||||
# 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.
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(call all-java-files-under, src) \
|
||||
src/com/android/frameworks/perftests/am/util/ITimeReceiverCallback.aidl
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||
android-support-test \
|
||||
junit \
|
||||
ub-uiautomator
|
||||
|
||||
LOCAL_MODULE := ActivityManagerPerfTestsUtils
|
||||
|
||||
include $(BUILD_STATIC_JAVA_LIBRARY)
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.frameworks.perftests.am.util;
|
||||
|
||||
public class Constants {
|
||||
public static final String TYPE_ACTIVITY_CREATED = "activity_create";
|
||||
public static final String TYPE_BROADCAST_RECEIVE = "broadcast_receive";
|
||||
|
||||
public static final String ACTION_BROADCAST_MANIFEST_RECEIVE =
|
||||
"com.android.frameworks.perftests.ACTION_BROADCAST_MANIFEST_RECEIVE";
|
||||
public static final String ACTION_BROADCAST_REGISTERED_RECEIVE =
|
||||
"com.android.frameworks.perftests.ACTION_BROADCAST_REGISTERED_RECEIVE";
|
||||
|
||||
public static final String EXTRA_RECEIVER_CALLBACK = "receiver_callback_binder";
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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.frameworks.perftests.am.util;
|
||||
|
||||
interface ITimeReceiverCallback {
|
||||
void sendTime(String type, long timeNs);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.frameworks.perftests.am.util;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.RemoteException;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class Utils {
|
||||
private static final String TAG = "AmPerfTestsUtils";
|
||||
|
||||
public static void drainBroadcastQueue() {
|
||||
runShellCommand("am wait-for-broadcast-idle");
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the command and returns the stdout.
|
||||
*/
|
||||
public static String runShellCommand(String cmd) {
|
||||
try {
|
||||
return UiDevice.getInstance(
|
||||
InstrumentationRegistry.getInstrumentation()).executeShellCommand(cmd);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the current time in a message with the given type so TimeReceiver can receive it.
|
||||
*/
|
||||
public static void sendTime(Intent intent, String type) {
|
||||
final long time = System.nanoTime();
|
||||
final ITimeReceiverCallback sendTimeBinder = ITimeReceiverCallback.Stub.asInterface(
|
||||
intent.getExtras().getBinder(Constants.EXTRA_RECEIVER_CALLBACK));
|
||||
try {
|
||||
sendTimeBinder.sendTime(type, time);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user