Merge "change appSwitch ID" into rvc-dev
diff --git a/build/tasks/tests/instrumentation_metric_test_list.mk b/build/tasks/tests/instrumentation_metric_test_list.mk
index 8e86927..be79529 100644
--- a/build/tasks/tests/instrumentation_metric_test_list.mk
+++ b/build/tasks/tests/instrumentation_metric_test_list.mk
@@ -27,7 +27,8 @@
     NeuralNetworksApiBenchmark \
     PackageManagerPerfTests \
     TextClassifierPerfTests \
-    WmPerfTests
+    WmPerfTests \
+    trace_config_detailed.textproto
 
     # TODO(b/72332760): Uncomment when fixed
     #DocumentsUIPerfTests
diff --git a/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoDialHelper.java b/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoDialHelper.java
index b128d68..77ec8a3 100644
--- a/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoDialHelper.java
+++ b/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoDialHelper.java
@@ -224,4 +224,10 @@
      * @param contact Contact's details page to be opened.
      */
     void openDetailsPage(String contact);
+    /**
+     * Setup expectations: The app is open.
+     *
+     * <p>This method is used to check if phone is paired.
+     */
+    boolean isPhonePaired();
 }
diff --git a/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoMapsHelper.java b/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoMapsHelper.java
index 5bf3f03..f42b928 100644
--- a/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoMapsHelper.java
+++ b/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoMapsHelper.java
@@ -17,6 +17,14 @@
 package android.platform.helpers;
 
 public interface IAutoMapsHelper extends IAppHelper {
+
+    /**
+     * Setup expectations: Maps app is open
+     *
+     * <p>This method is used to verify whether search bar is present.
+     */
+    boolean isSearchBarPresent();
+
     /**
      * Setup expectations: Maps app is open
      *
diff --git a/libraries/app-helpers/interfaces/common/src/android/platform/helpers/IMapsHelper.java b/libraries/app-helpers/interfaces/common/src/android/platform/helpers/IMapsHelper.java
index a91a303..af91ae3 100644
--- a/libraries/app-helpers/interfaces/common/src/android/platform/helpers/IMapsHelper.java
+++ b/libraries/app-helpers/interfaces/common/src/android/platform/helpers/IMapsHelper.java
@@ -121,4 +121,31 @@
     public default void swipeStreetView(Direction direction) {
         throw new UnsupportedOperationException("Not yet implemented.");
     }
+
+    /**
+     * Setup expectation: On the home screen.
+     *
+     * <p>Scroll the page to view the map.
+     */
+    public default void scrollPage(Direction dir, float percent) {
+        throw new UnsupportedOperationException("Not yet implemented.");
+    }
+
+    /**
+     * Setup expectation: On the home screen.
+     *
+     * <p>Click the button of my location on the home screen.
+     */
+    public default void clickMyLocationButton() {
+        throw new UnsupportedOperationException("Not yet implemented.");
+    }
+
+    /**
+     * Setup expectation: On the home screen.
+     *
+     * <p>Click the button of compass when exist on the home screen.
+     */
+    public default void clickBaseCompassButton() {
+        throw new UnsupportedOperationException("Not yet implemented.");
+    }
 }
diff --git a/libraries/app-helpers/interfaces/common/src/android/platform/helpers/IYouTubeHelper.java b/libraries/app-helpers/interfaces/common/src/android/platform/helpers/IYouTubeHelper.java
index bf7c5df..a71ac15 100644
--- a/libraries/app-helpers/interfaces/common/src/android/platform/helpers/IYouTubeHelper.java
+++ b/libraries/app-helpers/interfaces/common/src/android/platform/helpers/IYouTubeHelper.java
@@ -16,6 +16,8 @@
 
 package android.platform.helpers;
 
+import android.support.test.uiautomator.Direction;
+
 public interface IYouTubeHelper extends IAppHelper {
 
     public enum VideoQuality {
@@ -138,4 +140,10 @@
     public default void exitFullScreenMode() {
         throw new UnsupportedOperationException("Not yet implemented.");
     }
+    /**
+     * Setup expectation: YouTube is open on home page.
+     *
+     * <p>Scroll the home page by specified direction.
+     */
+    public void scrollHomePage(Direction direction);
 }
diff --git a/libraries/collectors-helper/statsd/src/com/android/helpers/StatsdHelper.java b/libraries/collectors-helper/statsd/src/com/android/helpers/StatsdHelper.java
index d1b6b7a..5b6f07e 100644
--- a/libraries/collectors-helper/statsd/src/com/android/helpers/StatsdHelper.java
+++ b/libraries/collectors-helper/statsd/src/com/android/helpers/StatsdHelper.java
@@ -59,7 +59,7 @@
      * Add simple event configurations using a list of atom ids.
      *
      * @param atomIdList uniquely identifies the information that we need to track by statsManager.
-     * @return true if the configuration is added successfully other wise false.
+     * @return true if the configuration is added successfully, otherwise false.
      */
     public boolean addEventConfig(List<Integer> atomIdList) {
         long configId = System.currentTimeMillis();
@@ -105,6 +105,7 @@
         // Needed for collecting gauge metric based on trigger events.
         statsConfigBuilder.addAtomMatcher(getSimpleAtomMatcher(appBreadCrumbUniqueId,
                 Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER));
+        statsConfigBuilder.addWhitelistedAtomIds(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER);
 
         for (Integer atomId : atomIdList) {
             int atomUniqueId = getUniqueId();
diff --git a/libraries/device-collectors/src/main/platform-collectors/src/android/device/collectors/StatsdListener.java b/libraries/device-collectors/src/main/platform-collectors/src/android/device/collectors/StatsdListener.java
index 97f4719..b59d876 100644
--- a/libraries/device-collectors/src/main/platform-collectors/src/android/device/collectors/StatsdListener.java
+++ b/libraries/device-collectors/src/main/platform-collectors/src/android/device/collectors/StatsdListener.java
@@ -28,6 +28,7 @@
 import androidx.test.InstrumentationRegistry;
 
 import com.android.internal.os.StatsdConfigProto.StatsdConfig;
+import com.android.os.AtomsProto.Atom;
 import com.android.os.StatsLog.ConfigMetricsReportList;
 import com.google.protobuf.InvalidProtocolBufferException;
 
@@ -178,6 +179,7 @@
             long configId = getUniqueIdForConfig(configs.get(configName));
             StatsdConfig newConfig = configs.get(configName).toBuilder().setId(configId).build();
             try {
+                Log.i(LOG_TAG, String.format("Adding config %s with ID %d.", configName, configId));
                 addStatsConfig(configId, newConfig.toByteArray());
                 configIds.put(configName, configId);
             } catch (StatsUnavailableException e) {
@@ -217,9 +219,21 @@
             // Dump the metric report to external storage.
             ConfigMetricsReportList reportList;
             try {
+                Log.i(
+                        LOG_TAG,
+                        String.format(
+                                "Pulling metrics for config %s with ID %d.",
+                                configName, configIds.get(configName)));
                 reportList =
                         ConfigMetricsReportList.parseFrom(
                                 getStatsReports(configIds.get(configName)));
+                Log.i(
+                        LOG_TAG,
+                        String.format(
+                                "Found %d metric %s from config %s.",
+                                reportList.getReportsCount(),
+                                reportList.getReportsCount() == 1 ? "report" : "reports",
+                                configName));
                 File reportFile =
                         new File(
                                 saveDirectory,
@@ -249,6 +263,11 @@
 
             // Remove the statsd config.
             try {
+                Log.i(
+                        LOG_TAG,
+                        String.format(
+                                "Removing config %s with ID %d.",
+                                configName, configIds.get(configName)));
                 removeStatsConfig(configIds.get(configName));
             } catch (StatsUnavailableException e) {
                 Log.e(
@@ -400,11 +419,11 @@
             final AssetManager manager, String optionName, String configName) {
         try (InputStream configStream = openConfigWithAssetManager(manager, configName)) {
             try {
-                return StatsdConfig.parseFrom(configStream);
+                return fixPermissions(StatsdConfig.parseFrom(configStream));
             } catch (IOException e) {
                 throw new RuntimeException(
                         String.format(
-                                "Cannot parse profile %s in option %s.", configName, optionName),
+                                "Cannot parse config %s in option %s.", configName, optionName),
                         e);
             }
         } catch (IOException e) {
@@ -458,4 +477,19 @@
     protected boolean logStop(int label) {
         return StatsLog.logStop(label);
     }
+
+    /**
+     * Add a few permission-related options to the statsd config.
+     *
+     * <p>This is related to some new permission restrictions in RVC.
+     */
+    private StatsdConfig fixPermissions(StatsdConfig config) {
+        StatsdConfig.Builder builder = config.toBuilder();
+        // Allow system power stats to be pulled.
+        builder.addDefaultPullPackages("AID_SYSTEM");
+        // Gauge metrics rely on AppBreadcrumbReported as metric dump triggers.
+        builder.addWhitelistedAtomIds(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER);
+
+        return builder.build();
+    }
 }
diff --git a/libraries/device-collectors/src/test/platform/Android.bp b/libraries/device-collectors/src/test/platform/Android.bp
index a6c93ec..14e3dcf 100644
--- a/libraries/device-collectors/src/test/platform/Android.bp
+++ b/libraries/device-collectors/src/test/platform/Android.bp
@@ -30,5 +30,6 @@
         "ub-uiautomator",
     ],
     platform_apis: true,
+    min_sdk_version: "26",
 }
 
diff --git a/libraries/device-collectors/src/test/platform/android/device/collectors/StatsdListenerTest.java b/libraries/device-collectors/src/test/platform/android/device/collectors/StatsdListenerTest.java
index db8606d..b134d17 100644
--- a/libraries/device-collectors/src/test/platform/android/device/collectors/StatsdListenerTest.java
+++ b/libraries/device-collectors/src/test/platform/android/device/collectors/StatsdListenerTest.java
@@ -33,6 +33,7 @@
 import android.os.Bundle;
 
 import com.android.internal.os.StatsdConfigProto.StatsdConfig;
+import com.android.os.AtomsProto.Atom;
 import com.android.os.StatsLog.ConfigMetricsReportList;
 import com.android.os.StatsLog.ConfigMetricsReportList.ConfigKey;
 import com.google.common.collect.ImmutableMap;
@@ -554,4 +555,32 @@
                                 && Arrays.stream(moreComponents)
                                         .allMatch(c -> f.getName().contains(c)));
     }
+
+    /** Test that configs are parsed and applied with correct permission fixes. */
+    @Test
+    public void testConfigsHavePermissionFixes() throws Exception {
+        // Stub a config for testing.
+        ByteArrayInputStream configStream = new ByteArrayInputStream(CONFIG_1.toByteArray());
+        doReturn(configStream)
+                .when(mListener)
+                .openConfigWithAssetManager(any(AssetManager.class), eq(CONFIG_NAME_1));
+
+        Bundle args = new Bundle();
+        args.putString(StatsdListener.OPTION_CONFIGS_RUN_LEVEL, CONFIG_NAME_1);
+        doReturn(args).when(mListener).getArguments();
+
+        Map<String, StatsdConfig> configs =
+                mListener.getConfigsFromOption(StatsdListener.OPTION_CONFIGS_RUN_LEVEL);
+        Assert.assertTrue(configs.containsKey(CONFIG_NAME_1));
+        Assert.assertTrue(
+                configs.get(CONFIG_NAME_1)
+                        .getWhitelistedAtomIdsList()
+                        .stream()
+                        .anyMatch(id -> id == Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER));
+        Assert.assertTrue(
+                configs.get(CONFIG_NAME_1)
+                        .getDefaultPullPackagesList()
+                        .stream()
+                        .anyMatch(name -> "AID_SYSTEM".equals(name)));
+    }
 }
diff --git a/libraries/health/runners/microbenchmark/src/android/platform/test/microbenchmark/Microbenchmark.java b/libraries/health/runners/microbenchmark/src/android/platform/test/microbenchmark/Microbenchmark.java
index 445999b..78a03e8 100644
--- a/libraries/health/runners/microbenchmark/src/android/platform/test/microbenchmark/Microbenchmark.java
+++ b/libraries/health/runners/microbenchmark/src/android/platform/test/microbenchmark/Microbenchmark.java
@@ -21,7 +21,6 @@
 import androidx.annotation.VisibleForTesting;
 import androidx.test.InstrumentationRegistry;
 
-
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -31,6 +30,10 @@
 import java.util.List;
 import java.util.Map;
 
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.internal.runners.model.EachTestNotifier;
+import org.junit.internal.runners.model.ReflectiveCallable;
+import org.junit.internal.runners.statements.RunAfters;
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
 import org.junit.runner.notification.RunNotifier;
@@ -38,6 +41,7 @@
 import org.junit.runners.model.FrameworkMethod;
 import org.junit.runners.model.InitializationError;
 import org.junit.runners.model.Statement;
+import org.junit.rules.RunRules;
 
 /**
  * The {@code Microbenchmark} runner allows you to run test methods repeatedly and with {@link
@@ -51,6 +55,11 @@
     // A constant to indicate that the iteration number is not set.
     @VisibleForTesting static final int ITERATION_NOT_SET = -1;
     public static final String RENAME_ITERATION_OPTION = "rename-iterations";
+    private static final Statement EMPTY =
+            new Statement() {
+                @Override
+                public void evaluate() throws Throwable {}
+            };
 
     private final String mIterationSep;
     private final Bundle mArguments;
@@ -153,6 +162,25 @@
     public @interface TightMethodRule {}
 
     /**
+     * A temporary annotation that acts like the {@code @Before} but is excluded from metric
+     * collection.
+     *
+     * <p>This should be removed as soon as possible. Do not use this unless explicitly instructed
+     * to do so. You'll regret it!
+     *
+     * <p>Note that all {@code TestOption}s must be instantiated as {@code @ClassRule}s to work
+     * inside these annotations.
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target({ElementType.FIELD, ElementType.METHOD})
+    public @interface NoMetricBefore {}
+
+    /** A temporary annotation, same as the above, but for replacing {@code @After} methods. */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target({ElementType.FIELD, ElementType.METHOD})
+    public @interface NoMetricAfter {}
+
+    /**
      * Rename the child class name to add iterations if the renaming iteration option is enabled.
      *
      * <p>Renaming the class here is chosen over renaming the method name because
@@ -173,17 +201,100 @@
                         String.valueOf(mIterations.get(original))), original.getMethodName());
     }
 
+    /** Re-implement the private rules wrapper from {@link BlockJUnit4ClassRunner} in JUnit 4.12. */
+    private Statement withRules(FrameworkMethod method, Object target, Statement statement) {
+        Statement result = statement;
+        List<TestRule> testRules = getTestRules(target);
+        // Apply legacy MethodRules, if they don't overlap with TestRules.
+        for (org.junit.rules.MethodRule each : rules(target)) {
+            if (!testRules.contains(each)) {
+                result = each.apply(result, method, target);
+            }
+        }
+        // Apply modern, method-level TestRules in outer statements.
+        result =
+                testRules.isEmpty()
+                        ? statement
+                        : new RunRules(result, testRules, describeChild(method));
+        return result;
+    }
+
     /**
-     * Keep track of the number of iterations for a particular method and
-     * set the current iteration count for changing the current description.
+     * Combine the {@code #runChild}, {@code #methodBlock}, and final {@code #runLeaf} methods to
+     * implement the specific {@code Microbenchmark} test behavior. In particular, (1) keep track of
+     * the number of iterations for a particular method description, and (2) run {@code
+     * NoMetricBefore} and {@code NoMetricAfter} methods outside of the {@code RunListener} test
+     * wrapping methods.
      */
     @Override
     protected void runChild(final FrameworkMethod method, RunNotifier notifier) {
+        // Update the number of iterations this method has been run.
         if (mRenameIterations) {
             Description original = super.describeChild(method);
             mIterations.computeIfPresent(original, (k, v) -> v + 1);
             mIterations.computeIfAbsent(original, k -> 1);
         }
-        super.runChild(method, notifier);
+
+        Description description = describeChild(method);
+        if (isIgnored(method)) {
+            notifier.fireTestIgnored(description);
+        } else {
+            EachTestNotifier eachNotifier = new EachTestNotifier(notifier, description);
+
+            Object test;
+            try {
+                // Fail fast if the test is not successfully created.
+                test =
+                        new ReflectiveCallable() {
+                            @Override
+                            protected Object runReflectiveCall() throws Throwable {
+                                return createTest();
+                            }
+                        }.run();
+
+                // Run {@code NoMetricBefore} methods first. Fail fast if they fail.
+                for (FrameworkMethod noMetricBefore :
+                        getTestClass().getAnnotatedMethods(NoMetricBefore.class)) {
+                    noMetricBefore.invokeExplosively(test);
+                }
+            } catch (Throwable e) {
+                eachNotifier.fireTestStarted();
+                eachNotifier.addFailure(e);
+                eachNotifier.fireTestFinished();
+                return;
+            }
+
+            Statement statement = methodInvoker(method, test);
+            statement = possiblyExpectingExceptions(method, test, statement);
+            statement = withPotentialTimeout(method, test, statement);
+            statement = withBefores(method, test, statement);
+            statement = withAfters(method, test, statement);
+            statement = withRules(method, test, statement);
+
+            // Fire test events from inside to exclude "no metric" methods.
+            eachNotifier.fireTestStarted();
+            try {
+                statement.evaluate();
+            } catch (AssumptionViolatedException e) {
+                eachNotifier.addFailedAssumption(e);
+            } catch (Throwable e) {
+                eachNotifier.addFailure(e);
+            } finally {
+                eachNotifier.fireTestFinished();
+            }
+
+            try {
+                // Run {@code NoMetricAfter} methods last, reporting all errors.
+                List<FrameworkMethod> afters =
+                        getTestClass().getAnnotatedMethods(NoMetricAfter.class);
+                if (!afters.isEmpty()) {
+                    new RunAfters(EMPTY, afters, test).evaluate();
+                }
+            } catch (AssumptionViolatedException e) {
+                eachNotifier.addFailedAssumption(e);
+            } catch (Throwable e) {
+                eachNotifier.addFailure(e);
+            }
+        }
     }
 }
diff --git a/libraries/launcher-helper/src/android/support/test/launcherhelper/AutoLauncherStrategy.java b/libraries/launcher-helper/src/android/support/test/launcherhelper/AutoLauncherStrategy.java
index bd02521..cdcd388 100644
--- a/libraries/launcher-helper/src/android/support/test/launcherhelper/AutoLauncherStrategy.java
+++ b/libraries/launcher-helper/src/android/support/test/launcherhelper/AutoLauncherStrategy.java
@@ -45,7 +45,7 @@
     private static final String APP_SWITCH_ID = "car_ui_toolbar_menu_item_icon_container";
     private static final String APP_LIST_ID = "apps_grid";
 
-    private static final long APP_LAUNCH_TIMEOUT = 10000;
+    private static final long APP_LAUNCH_TIMEOUT = 30000;
     private static final long UI_WAIT_TIMEOUT = 5000;
     private static final long POLL_INTERVAL = 100;
 
diff --git a/scripts/perf-setup/angler-setup.sh b/scripts/perf-setup/angler-setup.sh
deleted file mode 100755
index cd01184..0000000
--- a/scripts/perf-setup/angler-setup.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-if [[ "`id -u`" -ne "0" ]]; then
-  echo "WARNING: running as non-root, proceeding anyways..."
-fi
-
-stop thermal-engine
-stop perfd
-
-cpubase=/sys/devices/system/cpu
-gov=cpufreq/scaling_governor
-
-cpu=0
-S=960000
-while [ $((cpu < 4)) -eq 1 ]; do
-    echo 1 > $cpubase/cpu${cpu}/online
-    echo userspace > $cpubase/cpu${cpu}/$gov
-    echo $S > $cpubase/cpu${cpu}/cpufreq/scaling_max_freq
-    echo $S > $cpubase/cpu${cpu}/cpufreq/scaling_min_freq
-    echo $S > $cpubase/cpu${cpu}/cpufreq/scaling_setspeed
-    cpu=$(($cpu + 1))
-done
-
-echo -n 0 > /sys/devices/system/cpu/cpu4/online
-echo -n 0 > /sys/devices/system/cpu/cpu5/online
-echo -n 0 > /sys/devices/system/cpu/cpu6/online
-echo -n 0 > /sys/devices/system/cpu/cpu7/online
-
-echo 0 > /sys/class/kgsl/kgsl-3d0/bus_split
-echo 1 > /sys/class/kgsl/kgsl-3d0/force_clk_on
-echo 10000 > /sys/class/kgsl/kgsl-3d0/idle_timer
-
-echo 11863 > /sys/class/devfreq/qcom,gpubw.70/min_freq
-
-echo performance > /sys/class/kgsl/kgsl-3d0/devfreq/governor
-echo 305000000 > /sys/class/kgsl/kgsl-3d0/devfreq/min_freq
-echo 305000000 > /sys/class/kgsl/kgsl-3d0/devfreq/max_freq
-
-echo 4 > /sys/class/kgsl/kgsl-3d0/min_pwrlevel
-echo 4 > /sys/class/kgsl/kgsl-3d0/max_pwrlevel
-
diff --git a/scripts/perf-setup/b1c1-setup.sh b/scripts/perf-setup/b1c1-setup.sh
index 77c3ae2..aa57d85 100755
--- a/scripts/perf-setup/b1c1-setup.sh
+++ b/scripts/perf-setup/b1c1-setup.sh
@@ -18,6 +18,7 @@
 
 stop vendor.thermal-engine
 setprop vendor.powerhal.init 0
+setprop ctl.restart vendor.power-hal-aidl
 setprop ctl.interface_restart android.hardware.power@1.0::IPower/default
 
 cpubase=/sys/devices/system/cpu
diff --git a/scripts/perf-setup/b4s4-setup.sh b/scripts/perf-setup/b4s4-setup.sh
index c7498e4..a1aab6b 100755
--- a/scripts/perf-setup/b4s4-setup.sh
+++ b/scripts/perf-setup/b4s4-setup.sh
@@ -18,6 +18,7 @@
 
 stop vendor.thermal-engine
 setprop vendor.powerhal.init 0
+setprop ctl.restart vendor.power-hal-aidl
 setprop ctl.interface_restart android.hardware.power@1.0::IPower/default
 
 cpubase=/sys/devices/system/cpu
diff --git a/scripts/perf-setup/bullhead-setup.sh b/scripts/perf-setup/bullhead-setup.sh
deleted file mode 100644
index dfecb7d..0000000
--- a/scripts/perf-setup/bullhead-setup.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-if [[ "`id -u`" -ne "0" ]]; then
-  echo "WARNING: running as non-root, proceeding anyways..."
-fi
-
-stop thermal-engine
-stop perfd
-
-cpubase=/sys/devices/system/cpu
-gov=cpufreq/scaling_governor
-
-cpu=0
-S=960000
-while [ $((cpu < 4)) -eq 1 ]; do
-    echo 1 > $cpubase/cpu${cpu}/online
-    echo userspace > $cpubase/cpu${cpu}/$gov
-    echo $S > $cpubase/cpu${cpu}/cpufreq/scaling_max_freq
-    echo $S > $cpubase/cpu${cpu}/cpufreq/scaling_min_freq
-    echo $S > $cpubase/cpu${cpu}/cpufreq/scaling_setspeed
-    cpu=$(($cpu + 1))
-done
-
-echo -n 0 > /sys/devices/system/cpu/cpu4/online
-echo -n 0 > /sys/devices/system/cpu/cpu5/online
-
-echo 0 > /sys/class/kgsl/kgsl-3d0/bus_split
-echo 1 > /sys/class/kgsl/kgsl-3d0/force_clk_on
-echo 10000 > /sys/class/kgsl/kgsl-3d0/idle_timer
-
-echo 7102 > /sys/class/devfreq/qcom,gpubw.19/min_freq
-
-echo performance > /sys/class/kgsl/kgsl-3d0/devfreq/governor
-echo 300000000 > /sys/class/kgsl/kgsl-3d0/devfreq/min_freq
-echo 300000000 > /sys/class/kgsl/kgsl-3d0/devfreq/max_freq
-
-echo 4 > /sys/class/kgsl/kgsl-3d0/min_pwrlevel
-echo 4 > /sys/class/kgsl/kgsl-3d0/max_pwrlevel
diff --git a/scripts/perf-setup/c2f2-setup.sh b/scripts/perf-setup/c2f2-setup.sh
index d83cef4..13a3ca4 100755
--- a/scripts/perf-setup/c2f2-setup.sh
+++ b/scripts/perf-setup/c2f2-setup.sh
@@ -18,6 +18,7 @@
 
 stop vendor.thermal-engine
 setprop vendor.powerhal.init 0
+setprop ctl.restart vendor.power-hal-aidl
 setprop ctl.interface_restart android.hardware.power@1.0::IPower/default
 
 cpubase=/sys/devices/system/cpu
diff --git a/scripts/perf-setup/dragon-setup.sh b/scripts/perf-setup/dragon-setup.sh
deleted file mode 100755
index 7a50a16..0000000
--- a/scripts/perf-setup/dragon-setup.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-# performance testing setup script for dragon device
-
-if [[ "`id -u`" -ne "0" ]]; then
-  echo "WARNING: running as non-root, proceeding anyways..."
-fi
-
-# locking CPU frequency
-
-# note: locking cpu0 is sufficent to cover other cores as well
-echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
-echo 1530000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
-echo 1530000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
-echo 1530000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
-
-# locking GPU frequency
-
-# note: frequency choices can be found in:
-# cat /sys/class/drm/card0/device/pstate
-
-# select 768 MHz
-# 0a: core 768 MHz emc 1600 MHz
-echo 0a > /sys/class/drm/card0/device/pstate
diff --git a/scripts/perf-setup/sailin-setup.sh b/scripts/perf-setup/sailin-setup.sh
deleted file mode 100644
index 4a7a33d..0000000
--- a/scripts/perf-setup/sailin-setup.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#Setup for newer devices
-
-if [[ "`id -u`" -ne "0" ]]; then
-  echo "WARNING: running as non-root, proceeding anyways..."
-fi
-
-stop thermal-engine
-stop perfd
-stop vendor.thermal-engine
-stop vendor.perfd
-
-echo 0 > /sys/devices/system/cpu/cpu0/online
-echo 0 > /sys/devices/system/cpu/cpu1/online
-
-echo performance  > /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor
-echo 2150400 > /sys/devices/system/cpu/cpu2/cpufreq/scaling_max_freq
-
-echo 13763 > /sys/class/devfreq/soc:qcom,gpubw/max_freq
-echo performance > /sys/class/kgsl/kgsl-3d0/devfreq/governor
-echo -n 624000000 > /sys/class/kgsl/kgsl-3d0/devfreq/max_freq
diff --git a/tests/functional/devicehealthchecks/assets/bug_map b/tests/functional/devicehealthchecks/assets/bug_map
index 976a087..b617349 100644
--- a/tests/functional/devicehealthchecks/assets/bug_map
+++ b/tests/functional/devicehealthchecks/assets/bug_map
@@ -1,5 +1,8 @@
 <test_name> <regex.no.spaces> <only_bug_number>
 system_app_anr com.google.android.googlequicksearchbox:search 151164399
+system_app_anr com.google.oslo/.service.OsloService 159025912
+system_app_anr com.google.android.as/com.google.android.apps.miphone.aiai.common.superpacks.impl.AiAiSuperpacksService 159058706
+system_app_anr act=android.telephony.action.CARRIER_CONFIG_CHANGED 159921750
 system_app_crash -1\|android\|26\|null\|1000 155073214
 system_app_crash -1\|android\|32\|null\|1000 155073214
 system_app_crash android.database.sqlite.SQLiteCantOpenDatabaseException: 150248286
@@ -7,7 +10,12 @@
 system_app_crash pzd.a.:com.google.android.gms@ 145798275
 system_app_crash com.android.service.ims.RcsService.registerImsCallbacksAndSetAssociatedSubscription 156402275
 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_native_crash com.google.android.apps.safetyhub 154358781
 system_app_native_crash com.google.android.providers.media.module 154416156
-system_tombstone android.hardware.vibrator-service.drv2624 151884322
-system_tombstone /vendor/bin/hw/android.hardware.gnss@1.0-service-qti 129282808
+system_server_crash void.com.android.server.location.gnss.GnssBatchingProvider.enable 159504970
+SYSTEM_TOMBSTONE android.hardware.vibrator-service.drv2624 151884322
+SYSTEM_TOMBSTONE /vendor/bin/hw/android.hardware.gnss@1.0-service-qti 129282808
+SYSTEM_TOMBSTONE /system/product/priv-app/SafetyHubLprPrebuilt/SafetyHubLprPrebuilt.apk 158504050
diff --git a/tests/health/scenarios/src/android/platform/test/scenario/sample/SampleTest.java b/tests/health/scenarios/src/android/platform/test/scenario/sample/SampleTest.java
index 01b904d..03e8a07 100644
--- a/tests/health/scenarios/src/android/platform/test/scenario/sample/SampleTest.java
+++ b/tests/health/scenarios/src/android/platform/test/scenario/sample/SampleTest.java
@@ -17,6 +17,7 @@
 package android.platform.test.scenario.sample;
 
 import android.util.Log;
+import android.platform.test.option.BooleanOption;
 import android.platform.test.rule.TestWatcher;
 import android.platform.test.scenario.annotation.Scenario;
 
@@ -57,31 +58,65 @@
                     .around(new PrintRule("@Rule #2"))
                     .around(new PrintRule("@Rule #3"));
 
+    @ClassRule
+    public static BooleanOption failBeforeClass =
+            new BooleanOption("fail-before-class").setRequired(false).setDefault(false);
+
+    @Rule
+    public BooleanOption failBefore =
+            new BooleanOption("fail-before").setRequired(false).setDefault(false);
+
+    @Rule
+    public BooleanOption failTest =
+            new BooleanOption("fail-test").setRequired(false).setDefault(false);
+
+    @Rule
+    public BooleanOption failAfter =
+            new BooleanOption("fail-after").setRequired(false).setDefault(false);
+
+    @ClassRule
+    public static BooleanOption failAfterClass =
+            new BooleanOption("fail-after-class").setRequired(false).setDefault(false);
+
     @BeforeClass
     public static void beforeClassMethod() {
+        failIfRequested(failBeforeClass, "@BeforeClass");
         Log.d(LOG_TAG, "@BeforeClass");
     }
 
     @Before
     public void beforeMethod() {
+        failIfRequested(failBefore, "@Before");
         Log.d(LOG_TAG, "@Before");
     }
 
     @Test
     public void testMethod() {
+        failIfRequested(failTest, "@Test");
         Log.d(LOG_TAG, "@Test");
     }
 
     @After
     public void afterMethod() {
+        failIfRequested(failAfter, "@After");
         Log.d(LOG_TAG, "@After");
     }
 
     @AfterClass
     public static void afterClassMethod() {
+        failIfRequested(failAfterClass, "@AfterClass");
         Log.d(LOG_TAG, "@AfterClass");
     }
 
+    /** Log and throw a failure if the provided {@code option} is set. */
+    public static void failIfRequested(BooleanOption option, String location) {
+        if (option.get()) {
+            String message = String.format("Failed %s", location);
+            Log.d(LOG_TAG, message);
+            throw new RuntimeException(message);
+        }
+    }
+
     /** A {@link TestWatcher} that prints the methods it executes. */
     private static class PrintRule extends TestWatcher {
 
diff --git a/tests/health/scenarios/tests/src/android/platform/test/scenario/sample/SampleMicrobenchmark.java b/tests/health/scenarios/tests/src/android/platform/test/scenario/sample/SampleMicrobenchmark.java
index 0f93256..60ab128 100644
--- a/tests/health/scenarios/tests/src/android/platform/test/scenario/sample/SampleMicrobenchmark.java
+++ b/tests/health/scenarios/tests/src/android/platform/test/scenario/sample/SampleMicrobenchmark.java
@@ -17,7 +17,12 @@
 package android.platform.test.scenario.sample;
 
 import android.platform.test.microbenchmark.Microbenchmark;
+import android.platform.test.microbenchmark.Microbenchmark.NoMetricAfter;
+import android.platform.test.microbenchmark.Microbenchmark.NoMetricBefore;
+import android.platform.test.option.BooleanOption;
+import android.util.Log;
 
+import org.junit.ClassRule;
 import org.junit.runner.RunWith;
 
 /**
@@ -26,4 +31,25 @@
  * <p>Run this test with the listener alongside, {@link PrintListener}, to see how they interact.
  */
 @RunWith(Microbenchmark.class)
-public class SampleMicrobenchmark extends SampleTest {}
+public class SampleMicrobenchmark extends SampleTest {
+
+    @ClassRule
+    public static BooleanOption failNoMetricBefore =
+            new BooleanOption("fail-no-metric-before").setRequired(false).setDefault(false);
+
+    @ClassRule
+    public static BooleanOption failNoMetricAfter =
+            new BooleanOption("fail-no-metric-after").setRequired(false).setDefault(false);
+
+    @NoMetricBefore
+    public void noMetricBefore() {
+        SampleTest.failIfRequested(failNoMetricBefore, "@NoMetricBefore");
+        Log.d(SampleTest.LOG_TAG, "@NoMetricBefore");
+    }
+
+    @NoMetricAfter
+    public void noMetricAfter() {
+        SampleTest.failIfRequested(failNoMetricAfter, "@NoMetricAfter");
+        Log.d(SampleTest.LOG_TAG, "@NoMetricAfter");
+    }
+}