summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2020-11-03 18:09:46 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2020-11-03 18:09:46 +0000
commit3850efb9a2ff1e1ede404df5c9ba0d92d753ab32 (patch)
treeba5820cf3e320c4b66f946fdfb72763dad10ce49
parentbd51d8dc0e22a17d2e07592fd99c5e9a9462c5ef (diff)
parent535eccd4cbf1e5c8309fd59c5bc67379efc5a9d3 (diff)
downloadplatform_testing-3850efb9a2ff1e1ede404df5c9ba0d92d753ab32.tar.gz
Snap for 6948038 from 535eccd4cbf1e5c8309fd59c5bc67379efc5a9d3 to rvc-platform-releaseandroid-platform-11.0.0_r4android-platform-11.0.0_r3
Change-Id: Ie6b6c83b1474d522556f7c3a7b18eab3b11ade05
-rw-r--r--libraries/app-helpers/core/src/android/platform/helpers/AbstractStandardAppHelper.java2
-rw-r--r--libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoSettingHelper.java28
-rw-r--r--libraries/collectors-helper/simpleperf/Android.bp29
-rw-r--r--libraries/collectors-helper/simpleperf/src/com/android/helpers/SimpleperfHelper.java204
-rw-r--r--libraries/collectors-helper/simpleperf/test/Android.bp30
-rw-r--r--libraries/collectors-helper/simpleperf/test/src/com/android/helpers/tests/SimpleperfHelperTest.java95
-rw-r--r--libraries/device-collectors/src/main/Android.bp1
-rw-r--r--libraries/device-collectors/src/main/java/android/device/collectors/SimpleperfListener.java207
-rw-r--r--libraries/device-collectors/src/test/java/android/device/collectors/SimpleperfListenerTest.java251
-rw-r--r--libraries/health/rules/src/android/platform/test/rule/DisableAutofillRule.java59
-rw-r--r--libraries/health/runners/longevity/host/src/android/host/test/longevity/listener/TimeoutTerminator.java2
-rw-r--r--libraries/health/runners/longevity/host/tests/src/android/host/test/longevity/LongevitySuiteTest.java40
-rw-r--r--libraries/health/runners/longevity/host/tests/src/android/host/test/longevity/listener/TimeoutTerminatorTest.java4
-rw-r--r--libraries/health/runners/longevity/platform/src/android/platform/test/longevity/LongevityClassRunner.java7
-rw-r--r--libraries/health/runners/longevity/platform/src/android/platform/test/longevity/LongevitySuite.java6
-rw-r--r--libraries/health/runners/longevity/platform/tests/src/android/platform/test/longevity/listener/TimeoutTerminatorTest.java4
-rw-r--r--libraries/launcher-helper/src/android/support/test/launcherhelper/LauncherStrategyFactory.java1
-rw-r--r--libraries/launcher-helper/src/android/support/test/launcherhelper/VolvoLauncherStrategy.java182
-rwxr-xr-xscripts/perf-setup/b5r3-setup.sh84
-rw-r--r--tests/functional/devicehealthchecks/assets/bug_map1
20 files changed, 1039 insertions, 198 deletions
diff --git a/libraries/app-helpers/core/src/android/platform/helpers/AbstractStandardAppHelper.java b/libraries/app-helpers/core/src/android/platform/helpers/AbstractStandardAppHelper.java
index 331091541..fe710b0b0 100644
--- a/libraries/app-helpers/core/src/android/platform/helpers/AbstractStandardAppHelper.java
+++ b/libraries/app-helpers/core/src/android/platform/helpers/AbstractStandardAppHelper.java
@@ -198,7 +198,7 @@ public abstract class AbstractStandardAppHelper implements IAppHelper {
}
}
if (!mDevice.wait(
- Until.hasObject(mLauncherStrategy.getWorkspaceSelector()), EXIT_WAIT_TIMEOUT)) {
+ Until.hasObject(getLauncherStrategy().getWorkspaceSelector()), EXIT_WAIT_TIMEOUT)) {
throw new IllegalStateException("Failed to exit the app to launcher.");
}
}
diff --git a/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoSettingHelper.java b/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoSettingHelper.java
index 403b50e6c..7ad708441 100644
--- a/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoSettingHelper.java
+++ b/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoSettingHelper.java
@@ -191,4 +191,32 @@ public interface IAutoSettingHelper extends IAppHelper, Scrollable {
* <p>get day/night mode status.
*/
DayNightMode getDayNightModeStatus();
+
+ /**
+ * Setup expectations: full settings facet is open.
+ *
+ * <p>search in settings app and select the first search result.
+ *
+ * @param item to be searched.
+ */
+ void searchAndSelect(String item);
+
+ /**
+ * Setup expectations: full settings facet is open.
+ *
+ * <p>search in settings app.
+ *
+ * @param item to be searched.
+ * @param selectedIndex determines which search result to select.
+ */
+ void searchAndSelect(String item, int selectedIndex);
+
+ /**
+ * Setup expectations: search result is open.
+ *
+ * <p>verify page title contains the searched item.
+ *
+ * @param item to be verified.
+ */
+ boolean isValidPageTitle(String item);
}
diff --git a/libraries/collectors-helper/simpleperf/Android.bp b/libraries/collectors-helper/simpleperf/Android.bp
new file mode 100644
index 000000000..98d66b039
--- /dev/null
+++ b/libraries/collectors-helper/simpleperf/Android.bp
@@ -0,0 +1,29 @@
+// Copyright (C) 2020 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.
+
+// Used for collecting simpleperf samples.
+java_library {
+ name: "simpleperf-helper",
+ defaults: ["tradefed_errorprone_defaults"],
+
+ srcs: ["src/**/*.java"],
+
+ static_libs: [
+ "androidx.test.runner",
+ "ub-uiautomator",
+ ],
+
+ sdk_version: "current",
+}
+
diff --git a/libraries/collectors-helper/simpleperf/src/com/android/helpers/SimpleperfHelper.java b/libraries/collectors-helper/simpleperf/src/com/android/helpers/SimpleperfHelper.java
new file mode 100644
index 000000000..2e08f65b7
--- /dev/null
+++ b/libraries/collectors-helper/simpleperf/src/com/android/helpers/SimpleperfHelper.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2020 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.helpers;
+
+import android.os.SystemClock;
+import android.support.test.uiautomator.UiDevice;
+import android.util.Log;
+import androidx.test.InstrumentationRegistry;
+
+import java.io.IOException;
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+/**
+ * SimpleperfHelper is used to start and stop simpleperf sample collection and move the output
+ * sample file to the destination folder.
+ */
+public class SimpleperfHelper {
+
+ private static final String LOG_TAG = SimpleperfHelper.class.getSimpleName();
+ private static final String SIMPLEPERF_TMP_FILE_PATH = "/data/local/tmp/perf.data";
+
+ private static final String SIMPLEPERF_START_CMD =
+ "simpleperf record -o %s -g --post-unwind=yes -f 500 -a --exclude-perf";
+ private static final String SIMPLEPERF_STOP_CMD = "pkill -INT simpleperf";
+ private static final String SIMPLEPERF_PROC_ID_CMD = "pidof simpleperf";
+ private static final String REMOVE_CMD = "rm %s";
+ private static final String MOVE_CMD = "mv %s %s";
+
+ private static final int SIMPLEPERF_STOP_WAIT_COUNT = 12;
+ private static final long SIMPLEPERF_STOP_WAIT_TIME = 5000;
+
+ private UiDevice mUiDevice;
+
+ public boolean startCollecting() {
+ mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ try {
+ // Cleanup any running simpleperf sessions.
+ Log.i(LOG_TAG, "Cleanup simpleperf before starting.");
+ if (isSimpleperfRunning()) {
+ Log.i(LOG_TAG, "Simpleperf is already running. Stopping simpleperf.");
+ if (!stopSimpleperf()) {
+ return false;
+ }
+ }
+
+ Log.i(LOG_TAG, String.format("Starting simpleperf"));
+ new Thread() {
+ @Override
+ public void run() {
+ UiDevice uiDevice =
+ UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ try {
+ uiDevice.executeShellCommand(
+ String.format(SIMPLEPERF_START_CMD, SIMPLEPERF_TMP_FILE_PATH));
+ } catch (IOException e) {
+ Log.e(LOG_TAG, "Failed to start simpleperf.");
+ }
+ }
+ }.start();
+
+ if (!isSimpleperfRunning()) {
+ Log.e(LOG_TAG, "Simpleperf sampling failed to start.");
+ return false;
+ }
+ } catch (IOException e) {
+ Log.e(LOG_TAG, "Unable to start simpleperf sampling due to :" + e.getMessage());
+ return false;
+ }
+ Log.i(LOG_TAG, "Simpleperf sampling started successfully.");
+ return true;
+ }
+
+ /**
+ * Stop the simpleperf sample collection under /data/local/tmp/perf.data and copy the output to
+ * the destination file.
+ *
+ * @param destinationFile file to copy the simpleperf sample file to.
+ * @return true if the trace collection is successful otherwise false.
+ */
+ public boolean stopCollecting(String destinationFile) {
+ Log.i(LOG_TAG, "Stopping simpleperf.");
+ try {
+ if (stopSimpleperf()) {
+ if (!copyFileOutput(destinationFile)) {
+ return false;
+ }
+ } else {
+ Log.e(LOG_TAG, "Simpleperf failed to stop");
+ return false;
+ }
+ } catch (IOException e) {
+ Log.e(LOG_TAG, "Unable to stop the simpleperf samping due to " + e.getMessage());
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Utility method for sending the signal to stop simpleperf.
+ *
+ * @return true if simpleperf is successfully stopped.
+ */
+ public boolean stopSimpleperf() throws IOException {
+ if (!isSimpleperfRunning()) {
+ Log.e(LOG_TAG, "Simpleperf stop called, but simpleperf is not running.");
+ return false;
+ }
+
+ String stopOutput = mUiDevice.executeShellCommand(SIMPLEPERF_STOP_CMD);
+ Log.i(LOG_TAG, String.format("Simpleperf stop command ran"));
+ int waitCount = 0;
+ while (isSimpleperfRunning()) {
+ if (waitCount < SIMPLEPERF_STOP_WAIT_COUNT) {
+ SystemClock.sleep(SIMPLEPERF_STOP_WAIT_TIME);
+ waitCount++;
+ continue;
+ }
+ return false;
+ }
+ Log.e(LOG_TAG, "Simpleperf stopped successfully.");
+ return true;
+ }
+
+ /**
+ * Check if there is a simpleperf instance running.
+ *
+ * @return true if there is a running simpleperf instance, otherwise false.
+ */
+ private boolean isSimpleperfRunning() {
+ try {
+ String simpleperfProcId = mUiDevice.executeShellCommand(SIMPLEPERF_PROC_ID_CMD);
+ Log.i(LOG_TAG, String.format("Simpleperf process id - %s", simpleperfProcId));
+ if (simpleperfProcId.isEmpty()) {
+ return false;
+ }
+ } catch (IOException e) {
+ Log.e(LOG_TAG, "Unable to check simpleperf status: " + e.getMessage());
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Copy the temporary simpleperf output file to the given destinationFile.
+ *
+ * @param destinationFile file to copy simpleperf output into.
+ * @return true if the simpleperf file copied successfully, otherwise false.
+ */
+ private boolean copyFileOutput(String destinationFile) {
+ Path path = Paths.get(destinationFile);
+ String destDirectory = path.getParent().toString();
+ // Check if directory already exists
+ File directory = new File(destDirectory);
+ if (!directory.exists()) {
+ boolean success = directory.mkdirs();
+ if (!success) {
+ Log.e(
+ LOG_TAG,
+ String.format(
+ "Result output directory %s not created successfully.",
+ destDirectory));
+ return false;
+ }
+ }
+
+ // Copy the collected trace from /data/local/tmp to the destinationFile.
+ try {
+ String moveResult =
+ mUiDevice.executeShellCommand(
+ String.format(MOVE_CMD, SIMPLEPERF_TMP_FILE_PATH, destinationFile));
+ if (!moveResult.isEmpty()) {
+ Log.e(
+ LOG_TAG,
+ String.format(
+ "Unable to move simpleperf output file from %s to %s due to %s",
+ SIMPLEPERF_TMP_FILE_PATH, destinationFile, moveResult));
+ return false;
+ }
+ } catch (IOException e) {
+ Log.e(
+ LOG_TAG,
+ "Unable to move the simpleperf sample file to destination file."
+ + e.getMessage());
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/libraries/collectors-helper/simpleperf/test/Android.bp b/libraries/collectors-helper/simpleperf/test/Android.bp
new file mode 100644
index 000000000..860dbac95
--- /dev/null
+++ b/libraries/collectors-helper/simpleperf/test/Android.bp
@@ -0,0 +1,30 @@
+// Copyright (C) 2020 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.
+
+java_library {
+ name: "simpleperf-helper-test",
+ defaults: ["tradefed_errorprone_defaults"],
+
+ srcs: ["src/**/*.java"],
+
+ static_libs: [
+ "androidx.test.runner",
+ "android-support-test",
+ "simpleperf-helper",
+ "junit",
+
+ ],
+
+ sdk_version: "current",
+}
diff --git a/libraries/collectors-helper/simpleperf/test/src/com/android/helpers/tests/SimpleperfHelperTest.java b/libraries/collectors-helper/simpleperf/test/src/com/android/helpers/tests/SimpleperfHelperTest.java
new file mode 100644
index 000000000..7c2fdd7a5
--- /dev/null
+++ b/libraries/collectors-helper/simpleperf/test/src/com/android/helpers/tests/SimpleperfHelperTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2020 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.helpers.tests;
+
+import android.support.test.uiautomator.UiDevice;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.helpers.SimpleperfHelper;
+
+import java.io.IOException;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Android Unit tests for {@link SimpleperfHelper}.
+ *
+ * <p>atest CollectorsHelperTest:com.android.helpers.tests.SimpleperfHelperTest
+ */
+@RunWith(AndroidJUnit4.class)
+public class SimpleperfHelperTest {
+
+ private static final String REMOVE_CMD = "rm %s";
+ private static final String FILE_SIZE_IN_BYTES = "wc -c %s";
+
+ private SimpleperfHelper simpleperfHelper;
+
+ @Before
+ public void setUp() {
+ simpleperfHelper = new SimpleperfHelper();
+ }
+
+ @After
+ public void teardown() throws IOException {
+ simpleperfHelper.stopCollecting("data/local/tmp/perf.data");
+ UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ uiDevice.executeShellCommand(String.format(REMOVE_CMD, "/data/local/tmp/perf.data"));
+ }
+
+ /** Test simpleperf collection starts collecting properly. */
+ @Test
+ public void testSimpleperfStartSuccess() throws Exception {
+ assertTrue(simpleperfHelper.startCollecting());
+ }
+
+ /** Test if the path name is prefixed with /. */
+ @Test
+ public void testSimpleperfValidOutputPath() throws Exception {
+ assertTrue(simpleperfHelper.startCollecting());
+ assertTrue(simpleperfHelper.stopCollecting("data/local/tmp/perf.data"));
+ }
+
+ /** Test the invalid output path. */
+ @Test
+ public void testSimpleperfInvalidOutputPath() throws Exception {
+ assertTrue(simpleperfHelper.startCollecting());
+ // Don't have permission to create new folder under /data
+ assertFalse(simpleperfHelper.stopCollecting("/data/dummy/xyz/perf.data"));
+ }
+
+ /** Test simpleperf collection returns true and output file size greater than zero */
+ @Test
+ public void testSimpleperfSuccess() throws Exception {
+ assertTrue(simpleperfHelper.startCollecting());
+ Thread.sleep(1000);
+ assertTrue(simpleperfHelper.stopCollecting("/data/local/tmp/perf.data"));
+ Thread.sleep(1000);
+ UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ String[] fileStats =
+ uiDevice.executeShellCommand(
+ String.format(FILE_SIZE_IN_BYTES, "/data/local/tmp/perf.data"))
+ .split(" ");
+ int fileSize = Integer.parseInt(fileStats[0].trim());
+ assertTrue(fileSize > 0);
+ }
+}
diff --git a/libraries/device-collectors/src/main/Android.bp b/libraries/device-collectors/src/main/Android.bp
index 9ae62aaac..5da043a01 100644
--- a/libraries/device-collectors/src/main/Android.bp
+++ b/libraries/device-collectors/src/main/Android.bp
@@ -25,6 +25,7 @@ java_library {
"memory-helper",
"perfetto-helper",
"power-helper",
+ "simpleperf-helper",
"ub-uiautomator",
"system-metric-helper",
],
diff --git a/libraries/device-collectors/src/main/java/android/device/collectors/SimpleperfListener.java b/libraries/device-collectors/src/main/java/android/device/collectors/SimpleperfListener.java
new file mode 100644
index 000000000..61fc87a5b
--- /dev/null
+++ b/libraries/device-collectors/src/main/java/android/device/collectors/SimpleperfListener.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2020 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.device.collectors;
+
+import android.device.collectors.annotations.OptionClass;
+import android.os.Bundle;
+import android.util.Log;
+import androidx.annotation.VisibleForTesting;
+import com.android.helpers.SimpleperfHelper;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import org.junit.runner.Description;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+
+/**
+ * A {@link SimpleperfListener} that captures simpleperf samples for a test run or per test method
+ * run and saves the results under
+ * <root_folder>/<test_display_name>/SimpleperfListener/<test_display_name>-<invocation_count>.perf
+ */
+@OptionClass(alias = "simpleperf-collector")
+public class SimpleperfListener extends BaseMetricListener {
+
+ // Default output folder to store the simpleperf sample files.
+ private static final String DEFAULT_OUTPUT_ROOT = "/sdcard/test_results";
+ // Destination directory to save the trace results.
+ private static final String TEST_OUTPUT_ROOT = "test_output_root";
+ // Simpleperf file path key.
+ private static final String SIMPLEPERF_FILE_PATH = "simpleperf_file_path";
+ // Argument determining whether we collect for the entire run, or per test.
+ public static final String COLLECT_PER_RUN = "per_run";
+ public static final String SIMPLEPERF_PREFIX = "simpleperf_";
+ // Skip failure metrics collection if set to true.
+ public static final String SKIP_TEST_FAILURE_METRICS = "skip_test_failure_metrics";
+
+ // Simpleperf samples collected during the test will be saved under this root folder.
+ private String mTestOutputRoot;
+ // Store the method name and invocation count to create a unique filename for each trace.
+ private Map<String, Integer> mTestIdInvocationCount = new HashMap<>();
+ private boolean mSimpleperfStartSuccess = false;
+ private boolean mIsCollectPerRun;
+ private boolean mIsTestFailed = false;
+ private boolean mSkipTestFailureMetrics;
+
+ private SimpleperfHelper mSimpleperfHelper = new SimpleperfHelper();
+
+ public SimpleperfListener() {
+ super();
+ }
+
+ /**
+ * Constructor to simulate receiving the instrumentation arguments. Shoud not be used except for
+ * testing.
+ */
+ @VisibleForTesting
+ SimpleperfListener(Bundle args, SimpleperfHelper helper, Map invocationMap) {
+ super(args);
+ mSimpleperfHelper = helper;
+ mTestIdInvocationCount = invocationMap;
+ }
+
+ @Override
+ public void onTestRunStart(DataRecord runData, Description description) {
+ Bundle args = getArgsBundle();
+
+ // Whether to collect for the entire run, or per test.
+ mIsCollectPerRun = Boolean.parseBoolean(args.getString(COLLECT_PER_RUN));
+
+ // Destination folder in the device to save all simpleperf sample files.
+ // Defaulted to /sdcard/test_results if test_output_root is not passed.
+ mTestOutputRoot = args.getString(TEST_OUTPUT_ROOT, DEFAULT_OUTPUT_ROOT);
+
+ // By default this flag is set to false to collect metrics on test failure.
+ mSkipTestFailureMetrics = "true".equals(args.getString(SKIP_TEST_FAILURE_METRICS));
+
+ if (!mIsCollectPerRun) {
+ return;
+ }
+
+ Log.i(getTag(), "Starting simpleperf before test run started.");
+ startSimpleperf();
+ }
+
+ @Override
+ public void onTestStart(DataRecord testData, Description description) {
+ mIsTestFailed = false;
+ if (mIsCollectPerRun) {
+ return;
+ }
+
+ mTestIdInvocationCount.compute(
+ getTestFileName(description), (key, value) -> (value == null) ? 1 : value + 1);
+ Log.i(getTag(), "Starting simpleperf before test started.");
+ startSimpleperf();
+ }
+
+ @Override
+ public void onTestFail(DataRecord testData, Description description, Failure failure) {
+ mIsTestFailed = true;
+ }
+
+ @Override
+ public void onTestEnd(DataRecord testData, Description description) {
+ if (mIsCollectPerRun) {
+ return;
+ }
+
+ if (!mSimpleperfStartSuccess) {
+ Log.i(
+ getTag(),
+ "Skipping simpleperf stop attempt onTestEnd because simpleperf did not start"
+ + "successfully");
+ return;
+ }
+
+ if (mSkipTestFailureMetrics && mIsTestFailed) {
+ Log.i(getTag(), "Skipping metric collection due to test failure");
+ // Stop the existing simpleperf session.
+ try {
+ if (!mSimpleperfHelper.stopSimpleperf()) {
+ Log.e(getTag(), "Failed to stop the simpleperf process.");
+ }
+ } catch (IOException e) {
+ Log.e(getTag(), "Failed to stop simpleperf", e);
+ }
+ } else {
+ Log.i(getTag(), "Stopping simpleperf after test ended.");
+ // Construct test output directory in the below format
+ // <root_folder>/<test_name>/SimpleperfListener/<test_name>-<count>.data
+ Path path =
+ Paths.get(
+ mTestOutputRoot,
+ getTestFileName(description),
+ this.getClass().getSimpleName(),
+ String.format(
+ "%s%s-%d.data",
+ SIMPLEPERF_PREFIX,
+ getTestFileName(description),
+ mTestIdInvocationCount.get(getTestFileName(description))));
+ stopSimpleperf(path, testData);
+ }
+ }
+
+ @Override
+ public void onTestRunEnd(DataRecord runData, Result result) {
+ if (!mIsCollectPerRun) {
+ return;
+ }
+
+ if (!mSimpleperfStartSuccess) {
+ Log.i(getTag(), "Skipping simpleperf stop attempt as simpleperf failed to start.");
+ return;
+ }
+
+ Log.i(getTag(), "Stopping simpleperf after test run ended");
+ Path path =
+ Paths.get(
+ mTestOutputRoot,
+ this.getClass().getSimpleName(),
+ String.format(
+ "%s%d.data", SIMPLEPERF_PREFIX, UUID.randomUUID().hashCode()));
+ stopSimpleperf(path, runData);
+ }
+
+ /** Start simpleperf sampling. */
+ public void startSimpleperf() {
+ mSimpleperfStartSuccess = mSimpleperfHelper.startCollecting();
+ if (!mSimpleperfStartSuccess) {
+ Log.e(getTag(), "Simpleperf did not start successfully.");
+ }
+ }
+
+ /** Stop simpleperf sampling and dump the collected file into the given path. */
+ private void stopSimpleperf(Path path, DataRecord record) {
+ if (!mSimpleperfHelper.stopCollecting(path.toString())) {
+ Log.e(getTag(), "Failed to collect the simpleperf output.");
+ } else {
+ record.addStringMetric(SIMPLEPERF_FILE_PATH, path.toString());
+ }
+ }
+
+ /**
+ * Returns the packagename.classname_methodname which has no special characters and is used to
+ * create file names.
+ */
+ public static String getTestFileName(Description description) {
+ return String.format("%s_%s", description.getClassName(), description.getMethodName());
+ }
+}
diff --git a/libraries/device-collectors/src/test/java/android/device/collectors/SimpleperfListenerTest.java b/libraries/device-collectors/src/test/java/android/device/collectors/SimpleperfListenerTest.java
new file mode 100644
index 000000000..7473f71a6
--- /dev/null
+++ b/libraries/device-collectors/src/test/java/android/device/collectors/SimpleperfListenerTest.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2020 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.device.collectors;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.app.Instrumentation;
+import android.os.Bundle;
+import androidx.test.runner.AndroidJUnit4;
+import com.android.helpers.SimpleperfHelper;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+
+/**
+ * Android Unit tests for {@link SimpleperfListener}.
+ *
+ * <p>To run: atest CollectorDeviceLibTest:android.device.collectors.SimpleperfListenerTest
+ */
+@RunWith(AndroidJUnit4.class)
+public class SimpleperfListenerTest {
+
+ // A {@code Description} to pass when faking a test run start call.
+ private static final Description FAKE_DESCRIPTION = Description.createSuiteDescription("run");
+
+ private static final Description FAKE_TEST_DESCRIPTION =
+ Description.createTestDescription("class", "method");
+
+ private Description mRunDesc;
+ private Description mTest1Desc;
+ private Description mTest2Desc;
+ private SimpleperfListener mListener;
+ @Mock private Instrumentation mInstrumentation;
+ private Map<String, Integer> mInvocationCount;
+ private DataRecord mDataRecord;
+
+ @Spy private SimpleperfHelper mSimpleperfHelper;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mRunDesc = Description.createSuiteDescription("run");
+ mTest1Desc = Description.createTestDescription("run", "test1");
+ mTest2Desc = Description.createTestDescription("run", "test2");
+ }
+
+ private SimpleperfListener initListener(Bundle b) {
+ mInvocationCount = new HashMap<>();
+
+ SimpleperfListener listener =
+ spy(new SimpleperfListener(b, mSimpleperfHelper, mInvocationCount));
+
+ mDataRecord = listener.createDataRecord();
+ listener.setInstrumentation(mInstrumentation);
+ return listener;
+ }
+
+ /*
+ * Verify simpleperf start and stop collection methods called exactly once for single test.
+ */
+ @Test
+ public void testSimpleperfPerTestSuccessFlow() throws Exception {
+ Bundle b = new Bundle();
+ mListener = initListener(b);
+ doReturn(true).when(mSimpleperfHelper).startCollecting();
+ doReturn(true).when(mSimpleperfHelper).stopCollecting(anyString());
+ // Test run start behavior
+ mListener.testRunStarted(mRunDesc);
+
+ // Test test start behavior
+ mListener.testStarted(mTest1Desc);
+ verify(mSimpleperfHelper, times(1)).startCollecting();
+ mListener.onTestEnd(mDataRecord, mTest1Desc);
+ verify(mSimpleperfHelper, times(1)).stopCollecting(anyString());
+ }
+
+ /*
+ * Verify stop collecting called exactly once when the test failed and the
+ * skip test failure mmetrics is enabled.
+ */
+ @Test
+ public void testSimpleperfPerTestFailureFlowDefault() throws Exception {
+ Bundle b = new Bundle();
+ b.putString(SimpleperfListener.SKIP_TEST_FAILURE_METRICS, "false");
+ mListener = initListener(b);
+
+ doReturn(true).when(mSimpleperfHelper).startCollecting();
+ doReturn(true).when(mSimpleperfHelper).stopCollecting(anyString());
+ // Test run start behavior
+ mListener.testRunStarted(mRunDesc);
+
+ // Test test start behavior
+ mListener.testStarted(mTest1Desc);
+ verify(mSimpleperfHelper, times(1)).startCollecting();
+
+ // Test fail behaviour
+ Failure failureDesc = new Failure(FAKE_TEST_DESCRIPTION, new Exception());
+ mListener.onTestFail(mDataRecord, mTest1Desc, failureDesc);
+ mListener.onTestEnd(mDataRecord, mTest1Desc);
+ verify(mSimpleperfHelper, times(1)).stopCollecting(anyString());
+ }
+
+ /*
+ * Verify stop simpleperf called exactly once when the test failed and the
+ * skip test failure metrics is enabled.
+ */
+ @Test
+ public void testSimpleperfPerTestFailureFlowWithSkipMmetrics() throws Exception {
+ Bundle b = new Bundle();
+ b.putString(SimpleperfListener.SKIP_TEST_FAILURE_METRICS, "true");
+ mListener = initListener(b);
+
+ doReturn(true).when(mSimpleperfHelper).startCollecting();
+ doReturn(true).when(mSimpleperfHelper).stopSimpleperf();
+ // Test run start behavior
+ mListener.testRunStarted(mRunDesc);
+
+ // Test test start behavior
+ mListener.testStarted(mTest1Desc);
+ verify(mSimpleperfHelper, times(1)).startCollecting();
+
+ // Test fail behaviour
+ Failure failureDesc = new Failure(FAKE_TEST_DESCRIPTION, new Exception());
+ mListener.onTestFail(mDataRecord, mTest1Desc, failureDesc);
+ mListener.onTestEnd(mDataRecord, mTest1Desc);
+ verify(mSimpleperfHelper, times(1)).stopSimpleperf();
+ }
+
+ /*
+ * Verify simpleperf start and stop collection methods called exactly once for test run.
+ * and not during each test method.
+ */
+ @Test
+ public void testSimpleperfPerRunSuccessFlow() throws Exception {
+ Bundle b = new Bundle();
+ b.putString(SimpleperfListener.COLLECT_PER_RUN, "true");
+ mListener = initListener(b);
+ doReturn(true).when(mSimpleperfHelper).startCollecting();
+ doReturn(true).when(mSimpleperfHelper).stopCollecting(anyString());
+
+ // Test run start behavior
+ mListener.onTestRunStart(mListener.createDataRecord(), FAKE_DESCRIPTION);
+ verify(mSimpleperfHelper, times(1)).startCollecting();
+ mListener.testStarted(mTest1Desc);
+ verify(mSimpleperfHelper, times(1)).startCollecting();
+ mListener.onTestEnd(mDataRecord, mTest1Desc);
+ verify(mSimpleperfHelper, times(0)).stopCollecting(anyString());
+ mListener.onTestRunEnd(mListener.createDataRecord(), new Result());
+ verify(mSimpleperfHelper, times(1)).stopCollecting(anyString());
+ }
+
+ /*
+ * Verify stop is not called if Simpleperf start did not succeed.
+ */
+ @Test
+ public void testSimpleperfPerRunFailureFlow() throws Exception {
+ Bundle b = new Bundle();
+ b.putString(SimpleperfListener.COLLECT_PER_RUN, "true");
+ mListener = initListener(b);
+ doReturn(false).when(mSimpleperfHelper).startCollecting();
+
+ // Test run start behavior
+ mListener.onTestRunStart(mListener.createDataRecord(), FAKE_DESCRIPTION);
+ verify(mSimpleperfHelper, times(1)).startCollecting();
+ mListener.onTestRunEnd(mListener.createDataRecord(), new Result());
+ verify(mSimpleperfHelper, times(0)).stopCollecting(anyString());
+ }
+
+ /*
+ * Verify simpleperf stop is not invoked if start did not succeed.
+ */
+ @Test
+ public void testSimpleperfStartFailureFlow() throws Exception {
+ Bundle b = new Bundle();
+ mListener = initListener(b);
+ doReturn(false).when(mSimpleperfHelper).startCollecting();
+
+ // Test run start behavior
+ mListener.testRunStarted(mRunDesc);
+
+ // Test test start behavior
+ mListener.testStarted(mTest1Desc);
+ verify(mSimpleperfHelper, times(1)).startCollecting();
+ mListener.onTestEnd(mDataRecord, mTest1Desc);
+ verify(mSimpleperfHelper, times(0)).stopCollecting(anyString());
+ }
+
+ /*
+ * Verify test method invocation count is updated successfully based on the number of times the
+ * test method is invoked.
+ */
+ @Test
+ public void testSimpleperfInvocationCount() throws Exception {
+ Bundle b = new Bundle();
+ mListener = initListener(b);
+ doReturn(true).when(mSimpleperfHelper).startCollecting();
+ doReturn(true).when(mSimpleperfHelper).stopCollecting(anyString());
+
+ // Test run start behavior
+ mListener.testRunStarted(mRunDesc);
+
+ // Test1 invocation 1 start behavior
+ mListener.testStarted(mTest1Desc);
+ verify(mSimpleperfHelper, times(1)).startCollecting();
+ mListener.onTestEnd(mDataRecord, mTest1Desc);
+ verify(mSimpleperfHelper, times(1)).stopCollecting(anyString());
+
+ // Test1 invocation 2 start behaviour
+ mListener.testStarted(mTest1Desc);
+ verify(mSimpleperfHelper, times(2)).startCollecting();
+ mListener.onTestEnd(mDataRecord, mTest1Desc);
+ verify(mSimpleperfHelper, times(2)).stopCollecting(anyString());
+
+ // Test2 invocation 1 start behaviour
+ mListener.testStarted(mTest2Desc);
+ verify(mSimpleperfHelper, times(3)).startCollecting();
+ mDataRecord = mListener.createDataRecord();
+ mListener.onTestEnd(mDataRecord, mTest2Desc);
+ verify(mSimpleperfHelper, times(3)).stopCollecting(anyString());
+
+ // Check if the test count is incremented properly.
+ assertEquals(2, (int) mInvocationCount.get(mListener.getTestFileName(mTest1Desc)));
+ assertEquals(1, (int) mInvocationCount.get(mListener.getTestFileName(mTest2Desc)));
+ }
+}
diff --git a/libraries/health/rules/src/android/platform/test/rule/DisableAutofillRule.java b/libraries/health/rules/src/android/platform/test/rule/DisableAutofillRule.java
new file mode 100644
index 000000000..ec936d0f8
--- /dev/null
+++ b/libraries/health/rules/src/android/platform/test/rule/DisableAutofillRule.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2020 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.platform.test.rule;
+
+import android.support.test.uiautomator.UiDevice;
+import android.text.TextUtils;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.runner.Description;
+
+import java.io.IOException;
+
+/**
+ * This rule sets the Android Autofill provider to none, and prevents autofill dialogs from popping
+ * up during the test. .
+ */
+public class DisableAutofillRule extends TestWatcher {
+ private String originalAutoFillService = "null";
+
+ @Override
+ protected void starting(Description description) {
+ try {
+ UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ String result = uiDevice.executeShellCommand("settings get secure autofill_service");
+ if (!TextUtils.isEmpty(result) && !result.equals(originalAutoFillService)) {
+ originalAutoFillService = result;
+ }
+ uiDevice.executeShellCommand("settings put secure autofill_service null");
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to set autofill service to none");
+ }
+ }
+
+ @Override
+ protected void finished(Description description) {
+ try {
+ UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+ .executeShellCommand(
+ "settings put secure autofill_service " + originalAutoFillService);
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to set autofill service back to original");
+ }
+ }
+}
diff --git a/libraries/health/runners/longevity/host/src/android/host/test/longevity/listener/TimeoutTerminator.java b/libraries/health/runners/longevity/host/src/android/host/test/longevity/listener/TimeoutTerminator.java
index 5204e44ef..65e6a0d20 100644
--- a/libraries/health/runners/longevity/host/src/android/host/test/longevity/listener/TimeoutTerminator.java
+++ b/libraries/health/runners/longevity/host/src/android/host/test/longevity/listener/TimeoutTerminator.java
@@ -44,7 +44,7 @@ public class TimeoutTerminator extends RunTerminator {
* <p>Note: this initializes the countdown timer if unset.
*/
@Override
- public void testRunStarted(Description description) {
+ public void testStarted(Description description) {
if (mStartTimestamp == UNSET_TIMESTAMP) {
mStartTimestamp = getCurrentTimestamp();
}
diff --git a/libraries/health/runners/longevity/host/tests/src/android/host/test/longevity/LongevitySuiteTest.java b/libraries/health/runners/longevity/host/tests/src/android/host/test/longevity/LongevitySuiteTest.java
index 261a87d80..d21a61f29 100644
--- a/libraries/health/runners/longevity/host/tests/src/android/host/test/longevity/LongevitySuiteTest.java
+++ b/libraries/health/runners/longevity/host/tests/src/android/host/test/longevity/LongevitySuiteTest.java
@@ -18,6 +18,8 @@ package android.host.test.longevity;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
+import android.host.test.longevity.listener.TimeoutTerminator;
+
import java.util.HashMap;
import java.util.Map;
@@ -81,7 +83,7 @@ public class LongevitySuiteTest {
FailingTestSuite.class, new AllDefaultPossibilitiesBuilder(true), args);
try {
suite.run(new RunNotifier());
- fail("This run should be invalidated by test failures.");
+ fail("This run should be invalidated by test failure.");
} catch (StoppedByUserException e) {
// Expect this failure for an invalid, erroring test run.
}
@@ -91,9 +93,7 @@ public class LongevitySuiteTest {
@SuiteClasses({
FailingTestSuite.FailingTest.class,
})
- /**
- * Sample device-side test cases.
- */
+ /** Sample device-side test case that fails. */
public static class FailingTestSuite {
public static class FailingTest {
@Test
@@ -103,6 +103,38 @@ public class LongevitySuiteTest {
}
}
+ /** Tests that test runs are timing out if the tests run over the allotted suite time. */
+ @Test
+ public void testTimeoutTestRuns() throws InitializationError {
+ Map<String, String> args = new HashMap();
+ args.put(LongevitySuite.INVALIDATE_OPTION, "true");
+ args.put(TimeoutTerminator.OPTION, "25");
+ args.put(ITERATIONS_OPTION_NAME, String.valueOf(10));
+ LongevitySuite suite =
+ new LongevitySuite(
+ TimeoutTestSuite.class, new AllDefaultPossibilitiesBuilder(true), args);
+ try {
+ suite.run(new RunNotifier());
+ fail("This run should be ended by a timeout failure.");
+ } catch (StoppedByUserException e) {
+ // Expect this failure for an invalid, erroring test run.
+ }
+ }
+
+ @RunWith(LongevitySuite.class)
+ @SuiteClasses({
+ TimeoutTestSuite.TimedTest.class,
+ })
+ /** Sample device-side test case that takes time. */
+ public static class TimeoutTestSuite {
+ public static class TimedTest {
+ @Test
+ public void testSleep() throws InterruptedException {
+ Thread.sleep(10);
+ }
+ }
+ }
+
/**
* Tests that the {@link LongevitySuite} properly accounts for the number of tests in children.
*/
diff --git a/libraries/health/runners/longevity/host/tests/src/android/host/test/longevity/listener/TimeoutTerminatorTest.java b/libraries/health/runners/longevity/host/tests/src/android/host/test/longevity/listener/TimeoutTerminatorTest.java
index 1862e11b8..c439721f5 100644
--- a/libraries/health/runners/longevity/host/tests/src/android/host/test/longevity/listener/TimeoutTerminatorTest.java
+++ b/libraries/health/runners/longevity/host/tests/src/android/host/test/longevity/listener/TimeoutTerminatorTest.java
@@ -50,7 +50,7 @@ public class TimeoutTerminatorTest {
*/
@Test
public void testTimeoutTerminator_pass() throws Exception {
- mListener.testRunStarted(Description.EMPTY);
+ mListener.testStarted(Description.EMPTY);
Thread.sleep(10L);
mListener.testFinished(Description.EMPTY);
verify(mNotifier, never()).pleaseStop();
@@ -61,7 +61,7 @@ public class TimeoutTerminatorTest {
*/
@Test
public void testTimeoutTerminator_timeout() throws Exception {
- mListener.testRunStarted(Description.EMPTY);
+ mListener.testStarted(Description.EMPTY);
Thread.sleep(60L);
mListener.testFinished(Description.EMPTY);
verify(mNotifier).pleaseStop();
diff --git a/libraries/health/runners/longevity/platform/src/android/platform/test/longevity/LongevityClassRunner.java b/libraries/health/runners/longevity/platform/src/android/platform/test/longevity/LongevityClassRunner.java
index e565427e1..f1cc67d2b 100644
--- a/libraries/health/runners/longevity/platform/src/android/platform/test/longevity/LongevityClassRunner.java
+++ b/libraries/health/runners/longevity/platform/src/android/platform/test/longevity/LongevityClassRunner.java
@@ -38,6 +38,7 @@ import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.MultipleFailureException;
import org.junit.runners.model.Statement;
+import org.junit.runner.notification.StoppedByUserException;
/**
* A {@link BlockJUnit4ClassRunner} that runs the test class's {@link BeforeClass} methods as {@link
@@ -229,12 +230,16 @@ public class LongevityClassRunner extends BlockJUnit4ClassRunner {
@Override
public void evaluate() throws Throwable {
List<Throwable> errors = new ArrayList<>();
+ boolean stoppedByUser = false;
try {
mStatement.evaluate();
} catch (Throwable e) {
+ if (e instanceof StoppedByUserException) {
+ stoppedByUser = true;
+ }
errors.add(e);
} finally {
- if (LongevityClassRunner.this.hasTestFailed()) {
+ if (!stoppedByUser && LongevityClassRunner.this.hasTestFailed()) {
errors.addAll(invokeAndCollectErrors(mAfterClassMethods, mTarget));
}
}
diff --git a/libraries/health/runners/longevity/platform/src/android/platform/test/longevity/LongevitySuite.java b/libraries/health/runners/longevity/platform/src/android/platform/test/longevity/LongevitySuite.java
index ced687480..2e0df1c53 100644
--- a/libraries/health/runners/longevity/platform/src/android/platform/test/longevity/LongevitySuite.java
+++ b/libraries/health/runners/longevity/platform/src/android/platform/test/longevity/LongevitySuite.java
@@ -201,9 +201,7 @@ public class LongevitySuite extends android.host.test.longevity.LongevitySuite {
super.runChild(suiteRunner, notifier);
}
- /**
- * Returns the platform-specific {@link TimeoutTerminator} for Android devices.
- */
+ /** Returns the platform-specific {@link ErrorTerminator} for an Android device. */
@Override
public android.host.test.longevity.listener.ErrorTerminator getErrorTerminator(
final RunNotifier notifier) {
@@ -211,7 +209,7 @@ public class LongevitySuite extends android.host.test.longevity.LongevitySuite {
}
/**
- * Returns the platform-specific {@link TimeoutTerminator} for Android devices.
+ * Returns the platform-specific {@link TimeoutTerminator} for an Android device.
*
* <p>This method will always return the same {@link TimeoutTerminator} instance.
*/
diff --git a/libraries/health/runners/longevity/platform/tests/src/android/platform/test/longevity/listener/TimeoutTerminatorTest.java b/libraries/health/runners/longevity/platform/tests/src/android/platform/test/longevity/listener/TimeoutTerminatorTest.java
index 76749ffb3..a6dfb79e9 100644
--- a/libraries/health/runners/longevity/platform/tests/src/android/platform/test/longevity/listener/TimeoutTerminatorTest.java
+++ b/libraries/health/runners/longevity/platform/tests/src/android/platform/test/longevity/listener/TimeoutTerminatorTest.java
@@ -53,7 +53,7 @@ public class TimeoutTerminatorTest {
*/
@Test
public void testTimeoutTerminator_pass() throws Exception {
- mListener.testRunStarted(Description.EMPTY);
+ mListener.testStarted(Description.EMPTY);
SystemClock.sleep(10L);
verify(mNotifier, never()).pleaseStop();
}
@@ -63,7 +63,7 @@ public class TimeoutTerminatorTest {
*/
@Test
public void testTimeoutTerminator_timeout() throws Exception {
- mListener.testRunStarted(Description.EMPTY);
+ mListener.testStarted(Description.EMPTY);
SystemClock.sleep(60L);
mListener.testFinished(Description.EMPTY);
verify(mNotifier).pleaseStop();
diff --git a/libraries/launcher-helper/src/android/support/test/launcherhelper/LauncherStrategyFactory.java b/libraries/launcher-helper/src/android/support/test/launcherhelper/LauncherStrategyFactory.java
index 8a3db419d..f812b991f 100644
--- a/libraries/launcher-helper/src/android/support/test/launcherhelper/LauncherStrategyFactory.java
+++ b/libraries/launcher-helper/src/android/support/test/launcherhelper/LauncherStrategyFactory.java
@@ -42,7 +42,6 @@ public class LauncherStrategyFactory {
mKnownLauncherStrategies = new HashSet<>();
registerLauncherStrategy(AospLauncherStrategy.class);
registerLauncherStrategy(AutoLauncherStrategy.class);
- registerLauncherStrategy(VolvoLauncherStrategy.class);
registerLauncherStrategy(GoogleExperienceLauncherStrategy.class);
registerLauncherStrategy(Launcher3Strategy.class);
registerLauncherStrategy(NexusLauncherStrategy.class);
diff --git a/libraries/launcher-helper/src/android/support/test/launcherhelper/VolvoLauncherStrategy.java b/libraries/launcher-helper/src/android/support/test/launcherhelper/VolvoLauncherStrategy.java
deleted file mode 100644
index d0cac6148..000000000
--- a/libraries/launcher-helper/src/android/support/test/launcherhelper/VolvoLauncherStrategy.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2017 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.launcherhelper;
-
-import android.app.Instrumentation;
-import android.os.SystemClock;
-import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.BySelector;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject2;
-import android.support.test.uiautomator.Until;
-import android.system.helpers.CommandsHelper;
-
-import java.util.Map;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/** Implementation of {@link ILauncherStrategy} to support Volvo launcher */
-public class VolvoLauncherStrategy extends AutoLauncherStrategy {
- private static final String VOLVO_LAUNCHER_PACKAGE = "com.volvocars.launcher";
- private static final String SYSTEM_UI_PACKAGE = "com.android.systemui";
-
- private static final Map<String, BySelector> FACET_MAP =
- Stream.of(
- new Object[][] {
- {
- "App Grid",
- By.res(SYSTEM_UI_PACKAGE, "nav_bar_apps").clickable(true)
- },
- })
- .collect(
- Collectors.toMap(
- data -> (String) data[0], data -> (BySelector) data[1]));
-
- private static final Map<String, BySelector> APP_OPEN_VERIFIERS =
- Stream.of(
- new Object[][] {
- {"App Grid", By.res(VOLVO_LAUNCHER_PACKAGE, "apps_pane")},
- })
- .collect(
- Collectors.toMap(
- data -> (String) data[0], data -> (BySelector) data[1]));
-
- private static final long APP_LAUNCH_TIMEOUT_MS = 10000;
- private static final long UI_WAIT_TIMEOUT_MS = 5000;
- private static final long POLL_INTERVAL = 100;
-
- protected UiDevice mDevice;
- private Instrumentation mInstrumentation;
- private CommandsHelper mCommandsHelper;
-
- @Override
- public String getSupportedLauncherPackage() {
- return VOLVO_LAUNCHER_PACKAGE;
- }
-
- @Override
- public void setUiDevice(UiDevice uiDevice) {
- mDevice = uiDevice;
- }
-
- @Override
- public void setInstrumentation(Instrumentation instrumentation) {
- super.setInstrumentation(instrumentation);
- mInstrumentation = instrumentation;
- mCommandsHelper = CommandsHelper.getInstance(mInstrumentation);
- }
-
- @Override
- public void openApp(String appName) {
- if (checkApplicationExists(appName)) {
- UiObject2 app = mDevice.findObject(By.clickable(true).hasDescendant(By.text(appName)));
- app.clickAndWait(Until.newWindow(), APP_LAUNCH_TIMEOUT_MS);
- mDevice.waitForIdle();
- } else {
- throw new RuntimeException(String.format("Application %s not found", appName));
- }
- }
-
- @Override
- public void openBluetoothAudioApp() {
- String appName = "Bluetooth Media Player";
- if (checkApplicationExists(appName)) {
- UiObject2 app = mDevice.findObject(By.clickable(true).hasDescendant(By.text(appName)));
- app.clickAndWait(Until.newWindow(), APP_LAUNCH_TIMEOUT_MS);
- mDevice.waitForIdle();
- } else {
- throw new RuntimeException(String.format("Application %s not found", appName));
- }
- }
-
- @Override
- public void openGooglePlayStore() {
- mDevice.pressHome();
- mDevice.waitForIdle();
- mCommandsHelper.executeShellCommand(
- "am start -a android.intent.action.MAIN "
- + "-c android.intent.category.LAUNCHER "
- + "-n com.android.vending/"
- + "com.google.android.finsky.carmainactivity.MainActivity");
- }
-
- @Override
- public boolean checkApplicationExists(String appName) {
- openAppGridFacet();
- UiObject2 app = findApplication(appName);
- return app != null;
- }
-
- @Override
- public void openAppGridFacet() {
- openFacet("App Grid");
- }
-
- @Override
- public void openMapsFacet() {
- // Volvo does not have Facet for Maps, so open Maps from App Grid
- openApp("Maps");
- }
-
- private void openFacet(String facetName) {
- BySelector facetSelector = FACET_MAP.get(facetName);
- UiObject2 facet = mDevice.findObject(facetSelector);
- if (facet != null) {
- facet.click();
- waitUntilAppOpen(facetName, APP_LAUNCH_TIMEOUT_MS);
- } else {
- throw new RuntimeException(String.format("Failed to find %s facet.", facetName));
- }
- }
-
- private void waitUntilAppOpen(String appName, long timeout) {
- SystemClock.sleep(timeout);
- long startTime = SystemClock.uptimeMillis();
- boolean isOpen = false;
- do {
- isOpen = mDevice.hasObject(APP_OPEN_VERIFIERS.get(appName));
- if (isOpen) {
- break;
- }
- SystemClock.sleep(POLL_INTERVAL);
- } while ((SystemClock.uptimeMillis() - startTime) < timeout);
- if (!isOpen) {
- throw new IllegalStateException(
- String.format(
- "Did not find any app of %s in foreground after %d ms.",
- appName, timeout));
- }
- }
-
- private UiObject2 findApplication(String appName) {
- BySelector appSelector = By.clickable(true).hasDescendant(By.text(appName));
- return mDevice.findObject(appSelector);
- }
-
- /** {@inheritDoc} */
- @Override
- public void openNotifications() {
- String cmd = "cmd statusbar expand-notifications";
- mCommandsHelper.executeShellCommand(cmd);
- }
-
- /** {@inheritDoc} */
- @Override
- public void pressHome() {
- String cmd = "input keyevent KEYCODE_HOME";
- mCommandsHelper.executeShellCommand(cmd);
- }
-}
diff --git a/scripts/perf-setup/b5r3-setup.sh b/scripts/perf-setup/b5r3-setup.sh
new file mode 100755
index 000000000..d02ee0771
--- /dev/null
+++ b/scripts/perf-setup/b5r3-setup.sh
@@ -0,0 +1,84 @@
+#!/system/bin/sh
+#
+# Copyright (C) 2020 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.
+
+# performance test setup for 2020 devices
+function disable_thermal()
+{
+ thermal_path='/sys/devices/virtual/thermal/'
+
+ nz=$(ls -al $thermal_path | grep thermal_zone | wc -l)
+ i=0
+ while [ $i -lt $nz ]; do
+ tz_path=$thermal_path'thermal_zone'$i'/'
+ mode_path=$tz_path'mode'
+
+ if [ -f $mode_path ]; then
+ echo disabled > $tz_path'mode'
+ fi
+ i=$(($i + 1));
+ done
+}
+
+disable_thermal
+setprop vendor.powerhal.init 0
+setprop ctl.restart vendor.power-hal-aidl
+
+cpubase=/sys/devices/system/cpu
+gov=cpufreq/scaling_governor
+
+cpu=6
+top=8
+#Big Core 652800 940800 1152000 1478400 1728000 1900800 2092800 2208000
+#Big Plus 806400 1094400 1401600 1766400 1996800 2188800 2304000 2400000
+cpufreq=2092800
+# Set the bigcores around 2G
+while [ $((cpu < $top)) -eq 1 ]; do
+ echo 1 > $cpubase/cpu${cpu}/online
+ echo userspace > $cpubase/cpu${cpu}/$gov
+ echo $cpufreq > /sys/devices/system/cpu/cpu$cpu/cpufreq/scaling_max_freq
+ echo $cpufreq > /sys/devices/system/cpu/cpu$cpu/cpufreq/scaling_setspeed
+ S=`cat $cpubase/cpu${cpu}/cpufreq/scaling_cur_freq`
+ echo "set cpu $cpu to $S kHz"
+ cpu=$(($cpu + 1))
+done
+
+cpu=0
+top=6
+# Disable the silver cores.
+while [ $((cpu < $top)) -eq 1 ]; do
+ echo "disable cpu $cpu"
+ echo 0 > $cpubase/cpu${cpu}/online
+ cpu=$(($cpu + 1))
+done
+
+echo "disable GPU bus split"
+echo 0 > /sys/class/kgsl/kgsl-3d0/bus_split
+echo "enable GPU force clock on"
+echo 1 > /sys/class/kgsl/kgsl-3d0/force_clk_on
+echo "set GPU idle timer to 10000"
+echo 10000 > /sys/class/kgsl/kgsl-3d0/idle_timer
+
+# 0 381 572 762 1144 1571 2086 2597 2929 3879 4943 5931 6881
+echo performance > /sys/class/devfreq/soc:qcom,gpubw/governor
+echo -n "set GPU bus frequency to max at "
+cat /sys/class/devfreq/soc:qcom,gpubw/cur_freq
+
+#625 500 400 275 mhz
+echo performance > /sys/class/kgsl/kgsl-3d0/devfreq/governor
+echo 0 > /sys/class/kgsl/kgsl-3d0/max_pwrlevel
+echo 0 > /sys/class/kgsl/kgsl-3d0/min_pwrlevel
+echo -n "set GPU frequency to max at "
+cat /sys/class/kgsl/kgsl-3d0/devfreq/cur_freq
diff --git a/tests/functional/devicehealthchecks/assets/bug_map b/tests/functional/devicehealthchecks/assets/bug_map
index b6173492b..1448d8db5 100644
--- a/tests/functional/devicehealthchecks/assets/bug_map
+++ b/tests/functional/devicehealthchecks/assets/bug_map
@@ -13,6 +13,7 @@ system_app_crash com.google.android.inputmethod.latin 157051520
system_app_crash com.android.vending/com.google.android.finsky.verifier.impl.PackageVerificationService 156670156
system_app_crash com.google.android.apps.youtube.music.mediabrowser.MusicBrowserService.a 157917208
system_app_crash android.database.sqlite.SQLiteCloseable.acquireReference 159658068
+system_app_crash com.google.android.gms.backup.component.D2dTransportService 31428310
system_app_native_crash com.google.android.apps.safetyhub 154358781
system_app_native_crash com.google.android.providers.media.module 154416156
system_server_crash void.com.android.server.location.gnss.GnssBatchingProvider.enable 159504970