Merge "wifi: Add Radio stats in WifiUsabilityStatsEntry" into sc-dev
diff --git a/hostsidetests/car/AndroidTest.xml b/hostsidetests/car/AndroidTest.xml
index d72f51a..3699a2b 100644
--- a/hostsidetests/car/AndroidTest.xml
+++ b/hostsidetests/car/AndroidTest.xml
@@ -19,6 +19,10 @@
     <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <option name="config-descriptor:metadata" key="parameter" value="not_secondary_user" />
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsCarApp.apk" />
+    </target_preparer>
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
         <option name="jar" value="CtsCarHostTestCases.jar" />
         <option name="runtime-hint" value="1m" />
diff --git a/hostsidetests/car/app/Android.bp b/hostsidetests/car/app/Android.bp
index 0c54753..0a0dd6a 100644
--- a/hostsidetests/car/app/Android.bp
+++ b/hostsidetests/car/app/Android.bp
@@ -21,4 +21,13 @@
     defaults: ["cts_defaults"],
     srcs: ["src/**/*.java"],
     sdk_version: "current",
+
+    enforce_uses_libs: false,
+    static_libs: [
+        "android.frameworks.automotive.powerpolicy-V1-java",
+        "android.hardware.automotive.vehicle-V2.0-java",
+        "androidx.test.rules",
+    ],
+
+    libs: ["android.car"],
 }
diff --git a/hostsidetests/car/app/AndroidManifest.xml b/hostsidetests/car/app/AndroidManifest.xml
index 17b2685..cd8e6b7 100755
--- a/hostsidetests/car/app/AndroidManifest.xml
+++ b/hostsidetests/car/app/AndroidManifest.xml
@@ -18,7 +18,21 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.car.cts.app">
 
+    <uses-permission android:name="android.car.permission.CAR_POWER"/>
+    <uses-permission android:name="android.car.permission.READ_CAR_POWER_POLICY"/>
+    <uses-permission android:name="android.permission.READ_LOGS"/>
+    <uses-permission android:name="android.permission.STORAGE_INTERNAL"/>
+
     <application>
+        <activity android:name=".PowerPolicyTestActivity"
+            android:launchMode="singleTask"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+
         <activity android:name=".SimpleActivity" android:exported="true">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/hostsidetests/car/app/src/android/car/cts/app/PowerPolicyTestActivity.java b/hostsidetests/car/app/src/android/car/cts/app/PowerPolicyTestActivity.java
new file mode 100644
index 0000000..1bab9f6
--- /dev/null
+++ b/hostsidetests/car/app/src/android/car/cts/app/PowerPolicyTestActivity.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2021 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.car.cts.app;
+
+import android.app.Activity;
+import android.car.Car;
+import android.car.hardware.power.CarPowerManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.annotation.concurrent.GuardedBy;
+
+/**
+ * To test car power policy:
+ *     <pre class="prettyprint">
+ *         adb shell am force-stop android.car.cts.app
+ *         adb shell am start -n android.car.cts.app/.PowerPolicyTestActivity \
+ *              --es "powerpolicy" "testcase,action[,data]"
+ *         - testcase: suite | 1 | 2 | 3 | 4 | 5 | 6
+ *         - action:   start | end | dumpstate | dumppolicy | applypolicy | closefile
+ *         - data:     policyId
+ *     </pre>
+ */
+public final class PowerPolicyTestActivity extends Activity {
+    private static final String TAG = PowerPolicyTestActivity.class.getSimpleName();
+    private static final String SHARED_DATA_FILE = "/storage/emulated/obb/PowerPolicyData.txt";
+
+    private Car mCarApi;
+    private final Object mLock = new Object();
+    @GuardedBy("mLock")
+    private CarPowerManager mPowerManager;
+    private PrintWriter mPrintWriter;
+
+    @Nullable
+    public CarPowerManager getPowerManager() {
+        synchronized (mLock) {
+            return mPowerManager;
+        }
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        Log.d(TAG, "onNewIntent");
+        Bundle extras = intent.getExtras();
+        if (extras == null) {
+            Log.w(TAG, "onNewIntent: empty extras");
+            return;
+        }
+        PowerPolicyTestCommand cmd = PowerPolicyTestClient.parseCommand(extras);
+        if (cmd == null) {
+            Log.w(TAG, "onNewIntent: invalid power policy test command");
+            return;
+        }
+        cmd.setCar(mCarApi);
+        cmd.setPrintWriter(mPrintWriter);
+        PowerPolicyTestClient.handleCommand(cmd);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        initCarApi();
+        Context ctx = getApplicationContext();
+        try {
+            mPrintWriter = new PrintWriter(new File(ctx.getFilesDir(), SHARED_DATA_FILE));
+        } catch (IOException e) {
+            Log.e(TAG, "onCreate: failed to open PowerPolicyData.txt");
+            mPrintWriter = null;
+        }
+
+        Log.d(TAG, "onCreate");
+        onNewIntent(getIntent());
+    }
+
+    private void initCarApi() {
+        if (mCarApi != null && mCarApi.isConnected()) {
+            mCarApi.disconnect();
+            mCarApi = null;
+        }
+        mCarApi = Car.createCar(this, null, Car.CAR_WAIT_TIMEOUT_WAIT_FOREVER,
+                (Car car, boolean ready) -> {
+                    initManagers(car, ready);
+                });
+    }
+
+    @Override
+    protected void onDestroy() {
+        Log.d(TAG, "onDestroy");
+        if (mCarApi != null) {
+            mCarApi.disconnect();
+        }
+        super.onDestroy();
+    }
+
+    private void initManagers(Car car, boolean ready) {
+        synchronized (mLock) {
+            if (ready) {
+                mPowerManager = (CarPowerManager) car.getCarManager(
+                        android.car.Car.POWER_SERVICE);
+                Log.d(TAG, "initManagers() completed");
+            } else {
+                mPowerManager = null;
+                Log.wtf(TAG, "initManagers() set to be null");
+            }
+        }
+    }
+}
diff --git a/hostsidetests/car/app/src/android/car/cts/app/PowerPolicyTestClient.java b/hostsidetests/car/app/src/android/car/cts/app/PowerPolicyTestClient.java
new file mode 100644
index 0000000..71ffda0
--- /dev/null
+++ b/hostsidetests/car/app/src/android/car/cts/app/PowerPolicyTestClient.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2021 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.car.cts.app;
+
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.util.Log;
+
+public final class PowerPolicyTestClient {
+    private static final String TAG = PowerPolicyTestClient.class.getSimpleName();
+
+    private static final String POWERPOLICY_TEST_CMD_IDENTIFIER = "powerpolicy";
+    private static final String TEST_CMD_START = "start";
+    private static final String TEST_CMD_END = "end";
+    private static final String TEST_CMD_DUMP_STATE = "dumpstate";
+    private static final String TEST_CMD_DUMP_POLICY = "dumppolicy";
+    private static final String TEST_CMD_APPLY_POLICY = "applypolicy";
+    private static final String TEST_CMD_CLOSE_DATAFILE = "closefile";
+
+    private static PowerPolicyTestClient sPowerPolicyTestClient = new PowerPolicyTestClient();
+
+    private long mClientStartTime;
+
+    // This method is not intended for multi-threaded calls.
+    public static void handleCommand(PowerPolicyTestCommand cmd) {
+        switch (cmd.getType()) {
+            case START:
+                if (sPowerPolicyTestClient != null) {
+                    Log.w(TAG, "can not restart the test without ending the previous test first");
+                    return;
+                }
+                break;
+            default:
+                if (sPowerPolicyTestClient == null) {
+                    Log.w(TAG, "execute test start command first");
+                    return;
+                }
+                break;
+        }
+        cmd.execute(sPowerPolicyTestClient);
+
+        if (cmd.getType() == PowerPolicyTestCommand.TestCommandType.END) {
+            sPowerPolicyTestClient = null;
+        }
+    }
+
+    public static PowerPolicyTestCommand parseCommand(Bundle intentExtras) {
+        String testcase;
+        String action;
+        String data;
+        PowerPolicyTestCommand cmd = null;
+        String powertest = intentExtras.getString(POWERPOLICY_TEST_CMD_IDENTIFIER);
+        if (powertest == null) {
+            Log.d(TAG, "empty power test command");
+            return cmd;
+        }
+
+        String[] tokens = powertest.split(",");
+        int paramCount = tokens.length;
+        if (paramCount != 2 && paramCount != 3) {
+            throw new IllegalArgumentException("invalid command syntax");
+        }
+
+        testcase = tokens[0];
+        action = tokens[1];
+        if (paramCount == 3) {
+            data = tokens[2];
+        } else {
+            data = null;
+        }
+
+        switch (testcase) {
+            case TEST_CMD_START:
+                cmd = new PowerPolicyTestCommand.StartTestcaseCommand(testcase);
+                break;
+            case TEST_CMD_END:
+                cmd = new PowerPolicyTestCommand.EndTestcaseCommand(testcase);
+                break;
+            case TEST_CMD_DUMP_STATE:
+                cmd = new PowerPolicyTestCommand.DumpStateCommand(testcase);
+                break;
+            case TEST_CMD_DUMP_POLICY:
+                cmd = new PowerPolicyTestCommand.DumpPolicyCommand(testcase);
+                break;
+            case TEST_CMD_APPLY_POLICY:
+                if (paramCount != 3) {
+                    throw new IllegalArgumentException("invalid command syntax");
+                }
+                cmd = new PowerPolicyTestCommand.ApplyPolicyCommand(testcase);
+                cmd.mPolicyId = data;
+                break;
+            case TEST_CMD_CLOSE_DATAFILE:
+                cmd = new PowerPolicyTestCommand.CloseDataFileCommand(testcase);
+                break;
+            default:
+                throw new IllegalArgumentException("invalid power policy test command: "
+                    + action);
+        }
+
+        Log.i(TAG, "testcase=" + testcase + ", command=" + action);
+        return cmd;
+    }
+
+    public void cleanup() {
+        //TODO(b/183134882): add any necessary cleanup activities here
+    }
+
+    public void registerAndGo() {
+        mClientStartTime = SystemClock.uptimeMillis();
+        //TODO(b/183134882): here is the place to add listeners
+    }
+}
diff --git a/hostsidetests/car/app/src/android/car/cts/app/PowerPolicyTestCommand.java b/hostsidetests/car/app/src/android/car/cts/app/PowerPolicyTestCommand.java
new file mode 100644
index 0000000..82d01db
--- /dev/null
+++ b/hostsidetests/car/app/src/android/car/cts/app/PowerPolicyTestCommand.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2021 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.car.cts.app;
+
+import android.car.Car;
+import android.car.hardware.power.CarPowerManager;
+import android.car.hardware.power.CarPowerPolicy;
+import android.util.Log;
+
+import java.io.PrintWriter;
+
+public abstract class PowerPolicyTestCommand {
+    private static final String TAG = PowerPolicyTestCommand.class.getSimpleName();
+
+    private final String mTestcase;
+    private final TestCommandType mType;
+
+    protected String mPolicyId;
+    protected Car mCar;
+    protected CarPowerManager mCarPowerManager;
+    protected PrintWriter mPrintWriter;
+
+    PowerPolicyTestCommand(String tc, TestCommandType type) {
+        mTestcase = tc;
+        mType = type;
+    }
+
+    void setCar(Car c) {
+        mCar = c;
+        mCarPowerManager = (CarPowerManager) mCar.getCarManager(Car.POWER_SERVICE);
+    }
+
+    String getTestcase() {
+        return mTestcase;
+    }
+
+    Car getCar() {
+        return mCar;
+    }
+
+    TestCommandType getType() {
+        return mType;
+    }
+
+    PrintWriter getPrintWriter() {
+        return mPrintWriter;
+    }
+
+    void setPrintWriter(PrintWriter fw) {
+        mPrintWriter = fw;
+    }
+
+    abstract void execute(PowerPolicyTestClient testClient);
+
+    enum TestCommandType {
+      START,
+      END,
+      DUMP_STATE,
+      DUMP_POLICY,
+      APPLY_POLICY,
+      CLOSE_DATAFILE
+    }
+
+    static final class StartTestcaseCommand extends PowerPolicyTestCommand {
+        StartTestcaseCommand(String tc) {
+            super(tc, TestCommandType.START);
+        }
+
+        void execute(PowerPolicyTestClient testClient) {
+            testClient.registerAndGo();
+        }
+    }
+
+    static final class EndTestcaseCommand extends PowerPolicyTestCommand {
+        EndTestcaseCommand(String tc) {
+            super(tc, TestCommandType.END);
+        }
+
+        @Override
+        void execute(PowerPolicyTestClient testClient) {
+            mPrintWriter.flush();
+            testClient.cleanup();
+        }
+    }
+
+    static final class DumpStateCommand extends PowerPolicyTestCommand {
+        DumpStateCommand(String tc) {
+            super(tc, TestCommandType.DUMP_STATE);
+        }
+
+        @Override
+        void execute(PowerPolicyTestClient testClient) {
+            int curState = mCarPowerManager.getPowerState();
+            mPrintWriter.printf("%s: Current Power State: %s\n", getTestcase(), curState);
+            Log.d(TAG, "Current Power State: " + curState);
+        }
+    }
+
+    static final class DumpPolicyCommand extends PowerPolicyTestCommand {
+        DumpPolicyCommand(String tc) {
+            super(tc, TestCommandType.DUMP_POLICY);
+        }
+
+        @Override
+        void execute(PowerPolicyTestClient testClient) {
+            CarPowerPolicy cpp = mCarPowerManager.getCurrentPowerPolicy();
+            if (cpp == null) {
+                Log.d(TAG, "null current power policy");
+                return;
+            }
+            String policyId = cpp.getPolicyId();
+            int[] enabledComponents = cpp.getEnabledComponents();
+            int[] disabledComponents = cpp.getDisabledComponents();
+
+            mPrintWriter.printf("%s: Current Power Policy: id=%s", getTestcase(), policyId);
+            mPrintWriter.printf(", enabledComponents=[");
+            for (int enabled : enabledComponents) {
+                mPrintWriter.printf("%d ", enabled);
+            }
+            mPrintWriter.printf("], disabledComponents=[");
+            for (int disabled : disabledComponents) {
+                mPrintWriter.printf("%d ", disabled);
+            }
+            mPrintWriter.println("]");
+            Log.d(TAG, "Dumped Policy Id: " + policyId);
+        }
+    }
+
+    static final class ApplyPolicyCommand extends PowerPolicyTestCommand {
+        ApplyPolicyCommand(String tc) {
+            super(tc, TestCommandType.APPLY_POLICY);
+        }
+
+        @Override
+        void execute(PowerPolicyTestClient testClient) {
+            if (mPolicyId == null) {
+                Log.w(TAG, "missing policy id for applying policy");
+                return;
+            }
+
+            mCarPowerManager.applyPowerPolicy(mPolicyId);
+            mPrintWriter.printf("%s : Apply Power Policy:%s\n", getTestcase(), mPolicyId);
+            Log.d(TAG, "apply policy with Id: " + mPolicyId);
+        }
+    }
+
+    static final class CloseDataFileCommand extends PowerPolicyTestCommand {
+        CloseDataFileCommand(String tc) {
+            super(tc, TestCommandType.CLOSE_DATAFILE);
+        }
+
+        @Override
+        void execute(PowerPolicyTestClient testClient) {
+            mPrintWriter.close();
+            Log.d(TAG, "close the data file");
+        }
+    }
+}
+
diff --git a/hostsidetests/os/src/android/os/cts/OsHostTests.java b/hostsidetests/os/src/android/os/cts/OsHostTests.java
index 5aea564..37f3e78 100644
--- a/hostsidetests/os/src/android/os/cts/OsHostTests.java
+++ b/hostsidetests/os/src/android/os/cts/OsHostTests.java
@@ -16,8 +16,6 @@
 
 package android.os.cts;
 
-import static com.google.common.truth.Truth.assertThat;
-
 import android.platform.test.annotations.AppModeFull;
 
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
@@ -29,15 +27,11 @@
 import com.android.tradefed.testtype.IAbi;
 import com.android.tradefed.testtype.IAbiReceiver;
 import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.util.AbiUtils;
 
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.InputStreamReader;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Scanner;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -56,15 +50,6 @@
     private static final String FILTER_FG_SERVICE_REGEXP =
             "TestFgService starting foreground: pid=([0-9]*)";
 
-    // Testing the intent filter verification mechanism
-    private static final String HOST_VERIFICATION_APK = "CtsHostLinkVerificationApp.apk";
-    private static final String HOST_VERIFICATION_PKG = "com.android.cts.openlinksskeleton";
-    private static final String FILTER_VERIFIER_REGEXP =
-            "Verifying IntentFilter\\..* package:\"" + HOST_VERIFICATION_PKG + "\"";
-    private static final Pattern HOST_PATTERN = Pattern.compile(".*hosts:\"(.*?)\"");
-    // domains that should be validated against given our test apk
-    private static final String HOST_WILDCARD = "wildcard.tld";
-
     /**
      * A reference to the device under test.
      */
@@ -148,59 +133,4 @@
         assertTrue("Looking for nonexistence of service process " + pid,
                 lsOut.contains("No such file"));
     }
-
-    public void testIntentFilterHostValidation() throws Exception {
-        String line = null;
-        try {
-            // Clean slate in case of earlier aborted run
-            mDevice.uninstallPackage(HOST_VERIFICATION_PKG);
-
-            final String[] options = { AbiUtils.createAbiFlag(mAbi.getName()) };
-            final int currentUser = mDevice.getCurrentUser();
-
-            mDevice.clearLogcat();
-
-            final String errorString;
-            errorString = mDevice.installPackageForUser(getTestAppFile(HOST_VERIFICATION_APK),
-                    false /* = reinstall? */, currentUser, options);
-
-            assertNull("Couldn't install web intent filter sample apk in user " +
-                    currentUser + " : " + errorString, errorString);
-
-            String logs = mDevice.executeAdbCommand("logcat", "-v", "brief", "-d");
-            boolean foundVerifierOutput = false;
-            Pattern verifierPattern = Pattern.compile(FILTER_VERIFIER_REGEXP);
-            Scanner scanner = new Scanner(logs);
-            while (scanner.hasNextLine()) {
-                line = scanner.nextLine();
-                Matcher verifierMatcher = verifierPattern.matcher(line);
-                if (verifierMatcher.find()) {
-                    Matcher m = HOST_PATTERN.matcher(line);
-                    assertTrue(m.find());
-                    final String hostgroup = m.group(1);
-                    HashSet<String> allHosts = new HashSet<>(
-                            Arrays.asList(hostgroup.split(" ")));
-                    assertThat(allHosts).containsExactly(HOST_WILDCARD);
-                    foundVerifierOutput = true;
-                    break;
-                }
-            }
-
-            assertTrue(foundVerifierOutput);
-        } catch (Exception e) {
-            fail("Unable to parse verification results: " + e.getMessage()
-                    + " line=" + line);
-        } finally {
-            // Finally, uninstall the app
-            mDevice.uninstallPackage(HOST_VERIFICATION_PKG);
-        }
-    }
-
-    /*
-     * Helper: find a test apk
-     */
-    private File getTestAppFile(String fileName) throws FileNotFoundException {
-        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
-        return buildHelper.getTestFile(fileName);
-    }
 }
diff --git a/hostsidetests/os/test-apps/HostLinkVerificationApp/Android.bp b/hostsidetests/os/test-apps/HostLinkVerificationApp/Android.bp
deleted file mode 100644
index 3fb73fe..0000000
--- a/hostsidetests/os/test-apps/HostLinkVerificationApp/Android.bp
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// Copyright (C) 2016 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 {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-android_test_helper_app {
-    name: "CtsHostLinkVerificationApp",
-    defaults: ["cts_support_defaults"],
-    sdk_version: "current",
-    // Tag this module as a cts test artifact
-    test_suites: [
-        "cts",
-        "general-tests",
-    ],
-}
diff --git a/hostsidetests/os/test-apps/HostLinkVerificationApp/AndroidManifest.xml b/hostsidetests/os/test-apps/HostLinkVerificationApp/AndroidManifest.xml
deleted file mode 100644
index ace8c82..0000000
--- a/hostsidetests/os/test-apps/HostLinkVerificationApp/AndroidManifest.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 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.
--->
-<!-- Declare the contents of this Android application.  The namespace
-     attribute brings in the Android platform namespace, and the package
-     supplies a unique name for the application.  When writing your
-     own application, the package name must be changed from "com.example.*"
-     to come from a domain that you own or have control over. -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-     package="com.android.cts.openlinksskeleton"
-     android:versionCode="1"
-     android:versionName="1.0">
-
-    <application android:label="Open Links Skeleton"
-         android:hasCode="false">
-
-        <activity android:name="DummyWebLinkActivity"
-             android:exported="true">
-            <intent-filter android:autoVerify="true">
-                <action android:name="android.intent.action.VIEW"/>
-                <category android:name="android.intent.category.DEFAULT"/>
-                <category android:name="android.intent.category.BROWSABLE"/>
-                <data android:scheme="http"/>
-                <data android:scheme="https"/>
-                <data android:host="*.wildcard.tld"/>
-            </intent-filter>
-
-            <!-- Also make sure that verification picks up web navigation
-                                 handling even when the filter matches non-web schemes -->
-            <intent-filter>
-                <action android:name="android.intent.action.VIEW"/>
-                <category android:name="android.intent.category.DEFAULT"/>
-                <category android:name="android.intent.category.BROWSABLE"/>
-                <data android:scheme="http"/>
-                <data android:scheme="https"/>
-                <data android:scheme="nonweb"/>
-                <data android:host="explicit.example.com"/>
-            </intent-filter>
-        </activity>
-
-    </application>
-</manifest>
diff --git a/hostsidetests/scopedstorage/Android.bp b/hostsidetests/scopedstorage/Android.bp
index edd6f7a..8bba0ef 100644
--- a/hostsidetests/scopedstorage/Android.bp
+++ b/hostsidetests/scopedstorage/Android.bp
@@ -47,6 +47,16 @@
     test_suites: ["device-tests", "mts-mediaprovider", "cts"],
 }
 android_test_helper_app {
+    name: "CtsScopedStorageTestAppC30",
+    manifest: "ScopedStorageTestHelper/TestAppC.xml",
+    static_libs: ["cts-scopedstorage-lib"],
+    sdk_version: "test_current",
+    target_sdk_version: "30",
+    srcs: ["ScopedStorageTestHelper/src/**/*.java"],
+    // Tag as a CTS artifact
+    test_suites: ["device-tests", "mts", "cts"],
+}
+android_test_helper_app {
     name: "CtsScopedStorageTestAppCLegacy",
     manifest: "ScopedStorageTestHelper/TestAppCLegacy.xml",
     static_libs: ["cts-scopedstorage-lib"],
@@ -79,6 +89,34 @@
     // Tag as a CTS artifact
     test_suites: ["device-tests", "mts-mediaprovider", "cts"],
 }
+android_test_helper_app {
+    name: "CtsScopedStorageTestAppFileManagerBypassDB",
+    manifest: "ScopedStorageTestHelper/TestAppFileManagerBypassDB.xml",
+    static_libs: ["cts-scopedstorage-lib"],
+    sdk_version: "test_current",
+    srcs: ["ScopedStorageTestHelper/src/**/*.java"],
+    // Tag as a CTS artifact
+    test_suites: ["device-tests", "mts", "cts"],
+}
+android_test_helper_app {
+    name: "CtsScopedStorageTestAppSystemGalleryBypassDB",
+    manifest: "ScopedStorageTestHelper/TestAppSystemGalleryBypassDB.xml",
+    static_libs: ["cts-scopedstorage-lib"],
+    sdk_version: "test_current",
+    srcs: ["ScopedStorageTestHelper/src/**/*.java"],
+    // Tag as a CTS artifact
+    test_suites: ["device-tests", "mts", "cts"],
+}
+android_test_helper_app {
+    name: "CtsScopedStorageTestAppSystemGallery30BypassDB",
+    manifest: "ScopedStorageTestHelper/TestAppSystemGalleryBypassDB.xml",
+    static_libs: ["cts-scopedstorage-lib"],
+    sdk_version: "test_current",
+    target_sdk_version: "30",
+    srcs: ["ScopedStorageTestHelper/src/**/*.java"],
+    // Tag as a CTS artifact
+    test_suites: ["device-tests", "mts", "cts"],
+}
 
 android_test_helper_app {
     name: "CtsLegacyStorageTestAppRequestLegacy",
@@ -177,8 +215,12 @@
         ":CtsScopedStorageTestAppA",
         ":CtsScopedStorageTestAppB",
         ":CtsScopedStorageTestAppC",
+        ":CtsScopedStorageTestAppC30",
         ":CtsScopedStorageTestAppCLegacy",
         ":CtsScopedStorageTestAppDLegacy",
         ":CtsScopedStorageTestAppFileManager",
+        ":CtsScopedStorageTestAppFileManagerBypassDB",
+        ":CtsScopedStorageTestAppSystemGalleryBypassDB",
+        ":CtsScopedStorageTestAppSystemGallery30BypassDB",
     ]
 }
diff --git a/hostsidetests/scopedstorage/AndroidManifest.xml b/hostsidetests/scopedstorage/AndroidManifest.xml
index da158c3..b05c1a9 100644
--- a/hostsidetests/scopedstorage/AndroidManifest.xml
+++ b/hostsidetests/scopedstorage/AndroidManifest.xml
@@ -20,7 +20,7 @@
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
-    <application>
+    <application android:requestOptimizedExternalStorageAccess="true">
         <uses-library android:name="android.test.runner" />
     </application>
 
diff --git a/hostsidetests/scopedstorage/ScopedStorageTestHelper/TestAppFileManagerBypassDB.xml b/hostsidetests/scopedstorage/ScopedStorageTestHelper/TestAppFileManagerBypassDB.xml
new file mode 100644
index 0000000..b997bc9
--- /dev/null
+++ b/hostsidetests/scopedstorage/ScopedStorageTestHelper/TestAppFileManagerBypassDB.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.scopedstorage.cts.testapp.filemanagerbypassdb"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
+
+    <application android:label="TestAppFileManagerBypassDB" android:requestOptimizedExternalStorageAccess="true">
+        <activity android:name="android.scopedstorage.cts.ScopedStorageTestHelper" android:exported="true" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT"/>
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <provider
+            android:name="androidx.core.content.FileProvider"
+            android:authorities="android.scopedstorage.cts.testapp.filemanagerbypassdb"
+            android:exported="false"
+            android:grantUriPermissions="true">
+          <meta-data
+              android:name="android.support.FILE_PROVIDER_PATHS"
+              android:resource="@xml/file_paths" />
+        </provider>
+    </application>
+</manifest>
diff --git a/hostsidetests/scopedstorage/ScopedStorageTestHelper/TestAppSystemGalleryBypassDB.xml b/hostsidetests/scopedstorage/ScopedStorageTestHelper/TestAppSystemGalleryBypassDB.xml
new file mode 100644
index 0000000..b2dcf6e
--- /dev/null
+++ b/hostsidetests/scopedstorage/ScopedStorageTestHelper/TestAppSystemGalleryBypassDB.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 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="android.scopedstorage.cts.testapp.SystemGalleryBypassDB"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+  <uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
+  <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
+
+    <application android:label="TestAppSystemGalleryBypassDB" android:requestOptimizedExternalStorageAccess="true">
+        <activity android:name="android.scopedstorage.cts.ScopedStorageTestHelper" android:exported="true" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT"/>
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <provider
+            android:name="androidx.core.content.FileProvider"
+            android:authorities="android.scopedstorage.cts.testapp.SystemGalleryBypassDB"
+            android:exported="false"
+            android:grantUriPermissions="true">
+          <meta-data
+              android:name="android.support.FILE_PROVIDER_PATHS"
+              android:resource="@xml/file_paths" />
+        </provider>
+    </application>
+</manifest>
diff --git a/hostsidetests/scopedstorage/ScopedStorageTestHelper/src/android/scopedstorage/cts/ScopedStorageTestHelper.java b/hostsidetests/scopedstorage/ScopedStorageTestHelper/src/android/scopedstorage/cts/ScopedStorageTestHelper.java
index 11efea1..4c1e8ec 100644
--- a/hostsidetests/scopedstorage/ScopedStorageTestHelper/src/android/scopedstorage/cts/ScopedStorageTestHelper.java
+++ b/hostsidetests/scopedstorage/ScopedStorageTestHelper/src/android/scopedstorage/cts/ScopedStorageTestHelper.java
@@ -20,6 +20,7 @@
 import static android.scopedstorage.cts.lib.TestUtils.CAN_OPEN_FILE_FOR_READ_QUERY;
 import static android.scopedstorage.cts.lib.TestUtils.CAN_OPEN_FILE_FOR_WRITE_QUERY;
 import static android.scopedstorage.cts.lib.TestUtils.CAN_READ_WRITE_QUERY;
+import static android.scopedstorage.cts.lib.TestUtils.CHECK_DATABASE_ROW_EXISTS_QUERY;
 import static android.scopedstorage.cts.lib.TestUtils.CREATE_FILE_QUERY;
 import static android.scopedstorage.cts.lib.TestUtils.CREATE_IMAGE_ENTRY_QUERY;
 import static android.scopedstorage.cts.lib.TestUtils.DELETE_FILE_QUERY;
@@ -30,8 +31,11 @@
 import static android.scopedstorage.cts.lib.TestUtils.OPEN_FILE_FOR_WRITE_QUERY;
 import static android.scopedstorage.cts.lib.TestUtils.QUERY_TYPE;
 import static android.scopedstorage.cts.lib.TestUtils.READDIR_QUERY;
+import static android.scopedstorage.cts.lib.TestUtils.RENAME_FILE_PARAMS_SEPARATOR;
+import static android.scopedstorage.cts.lib.TestUtils.RENAME_FILE_QUERY;
 import static android.scopedstorage.cts.lib.TestUtils.SETATTR_QUERY;
 import static android.scopedstorage.cts.lib.TestUtils.canOpen;
+import static android.scopedstorage.cts.lib.TestUtils.getFileRowIdFromDatabase;
 import static android.scopedstorage.cts.lib.TestUtils.getImageContentUri;
 
 import android.app.Activity;
@@ -94,6 +98,12 @@
                 case CREATE_IMAGE_ENTRY_QUERY:
                     returnIntent = createImageEntry(queryType);
                     break;
+                case RENAME_FILE_QUERY:
+                    returnIntent = renameFile(queryType);
+                    break;
+                case CHECK_DATABASE_ROW_EXISTS_QUERY:
+                    returnIntent = checkDatabaseRowExists(queryType);
+                    break;
                 case "null":
                 default:
                     throw new IllegalStateException(
@@ -214,6 +224,36 @@
         }
     }
 
+    private Intent renameFile(String queryType) {
+        if (getIntent().hasExtra(INTENT_EXTRA_PATH)) {
+            String[] paths = getIntent().getStringExtra(INTENT_EXTRA_PATH)
+                    .split(RENAME_FILE_PARAMS_SEPARATOR);
+            File src = new File(paths[0]);
+            File dst = new File(paths[1]);
+            boolean result = src.renameTo(dst);
+            final Intent intent = new Intent(queryType);
+            intent.putExtra(queryType, result);
+            return intent;
+        } else {
+            throw new IllegalStateException(
+                    queryType + ": File paths not set from launcher app");
+        }
+    }
+
+    private Intent checkDatabaseRowExists(String queryType) {
+        if (getIntent().hasExtra(INTENT_EXTRA_PATH)) {
+            final String filePath = getIntent().getStringExtra(INTENT_EXTRA_PATH);
+            boolean result =
+                    getFileRowIdFromDatabase(getContentResolver(), new File(filePath)) != -1;
+            final Intent intent = new Intent(queryType);
+            intent.putExtra(queryType, result);
+            return intent;
+        } else {
+            throw new IllegalStateException(
+                    queryType + ": File path not set from launcher app");
+        }
+    }
+
     private void maybeCreateParentDirInAndroid(File file) {
         final String ownedPathType = getOwnedDirectoryType(file);
         if (ownedPathType == null) {
diff --git a/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/BypassDatabaseOperationsTest.java b/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/BypassDatabaseOperationsTest.java
new file mode 100644
index 0000000..086a0d4
--- /dev/null
+++ b/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/BypassDatabaseOperationsTest.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2021 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.scopedstorage.cts.device;
+
+import static android.app.AppOpsManager.permissionToOp;
+import static android.scopedstorage.cts.lib.TestUtils.allowAppOpsToUid;
+import static android.scopedstorage.cts.lib.TestUtils.createFileAs;
+import static android.scopedstorage.cts.lib.TestUtils.deleteFileAs;
+import static android.scopedstorage.cts.lib.TestUtils.deleteFileAsNoThrow;
+import static android.scopedstorage.cts.lib.TestUtils.denyAppOpsToUid;
+import static android.scopedstorage.cts.lib.TestUtils.getContentResolver;
+import static android.scopedstorage.cts.lib.TestUtils.getDcimDir;
+import static android.scopedstorage.cts.lib.TestUtils.getPicturesDir;
+import static android.scopedstorage.cts.lib.TestUtils.installApp;
+import static android.scopedstorage.cts.lib.TestUtils.installAppWithStoragePermissions;
+import static android.scopedstorage.cts.lib.TestUtils.renameFileAs;
+import static android.scopedstorage.cts.lib.TestUtils.uninstallAppNoThrow;
+
+import static androidx.test.InstrumentationRegistry.getContext;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import android.Manifest;
+import android.app.AppOpsManager;
+import android.provider.MediaStore;
+import android.scopedstorage.cts.lib.TestUtils;
+import android.util.Log;
+
+import com.android.cts.install.lib.TestApp;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.io.File;
+
+/**
+ * Device-side test suite to verify file path operations optionally bypassing database operations.
+ */
+@RunWith(Parameterized.class)
+public class BypassDatabaseOperationsTest extends ScopedStorageBaseDeviceTest {
+    static final String TAG = "BypassDatabaseOperationsTest";
+    // An app with READ_EXTERNAL_STORAGE permission. Targets current SDK and is preinstalled
+    private static final TestApp APP_SYSTEM_GALLERY_DEFAULT = new TestApp("TestAppA",
+            "android.scopedstorage.cts.testapp.A.withres", 1, false,
+            "CtsScopedStorageTestAppA.apk");
+    // An app with READ_EXTERNAL_STORAGE_PERMISSION. Targets current SDK and has
+    // requestOptimizedExternalStorageAccess=true
+    private static final TestApp APP_SYSTEM_GALLERY_BYPASS_DB = new TestApp(
+            "TestAppSystemGalleryBypassDB",
+            "android.scopedstorage.cts.testapp.SystemGalleryBypassDB", 1, false,
+            "CtsScopedStorageTestAppSystemGalleryBypassDB.apk");
+    // An app with READ_EXTERNAL_STORAGE_PERMISSION. Targets targetSDK=30.
+    private static final TestApp APP_SYSTEM_GALLERY_30 = new TestApp("TestAppC",
+            "android.scopedstorage.cts.testapp.C", 1, false,
+            "CtsScopedStorageTestAppC30.apk");
+    // An app with READ_EXTERNAL_STORAGE_PERMISSION. Targets targetSDK=30 and has
+    // requestOptimizedExternalStorageAccess=true
+    private static final TestApp APP_SYSTEM_GALLERY_30_BYPASS_DB = new TestApp(
+            "TestAppSystemGalleryBypassDB",
+            "android.scopedstorage.cts.testapp.SystemGalleryBypassDB", 1, false,
+            "CtsScopedStorageTestAppSystemGallery30BypassDB.apk");
+    // An app that has file manager (MANAGE_EXTERNAL_STORAGE) permission.
+    // Targets current SDK and preinstalled
+    private static final TestApp APP_FM_DEFAULT = new TestApp(
+            "TestAppFileManager", "android.scopedstorage.cts.testapp.filemanager", 1, false,
+            "CtsScopedStorageTestAppFileManager.apk");
+    // An app that has file manager (MANAGE_EXTERNAL_STORAGE) permission.
+    // Targets current SDK and has requestOptimizedExternalStorageAccess=true
+    private static final TestApp APP_FM_BYPASS_DATABASE_OPS = new TestApp(
+            "TestAppFileManagerBypassDB", "android.scopedstorage.cts.testapp.filemanagerbypassdb",
+            1, false, "CtsScopedStorageTestAppFileManagerBypassDB.apk");
+    // An app that has file manager (MANAGE_EXTERNAL_STORAGE) permission and targets targetSDK=30
+    private static final TestApp APP_FM_TARGETS_30 = new TestApp("TestAppC",
+            "android.scopedstorage.cts.testapp.C", 1, false,
+            "CtsScopedStorageTestAppC30.apk");
+
+    private static final String OPSTR_MANAGE_EXTERNAL_STORAGE =
+            permissionToOp(Manifest.permission.MANAGE_EXTERNAL_STORAGE);
+    private static final String[] SYSTEM_GALLERY_APPOPS = {
+            AppOpsManager.OPSTR_WRITE_MEDIA_IMAGES, AppOpsManager.OPSTR_WRITE_MEDIA_VIDEO};
+
+    /**
+     * To help avoid flaky tests, give ourselves a unique nonce to be used for
+     * all filesystem paths, so that we don't risk conflicting with previous
+     * test runs.
+     */
+    static final String NONCE = String.valueOf(System.nanoTime());
+
+    static final String IMAGE_FILE_NAME = "BypassDatabaseOperations_file_" + NONCE + ".jpg";
+
+    @BeforeClass
+    public static void setupApps() throws Exception {
+        // File manager needs to be explicitly granted MES app op.
+        final int fmUid =
+                getContext().getPackageManager().getPackageUid(
+                        APP_FM_DEFAULT.getPackageName(), 0);
+        allowAppOpsToUid(fmUid, OPSTR_MANAGE_EXTERNAL_STORAGE);
+    }
+
+    @Parameter(0)
+    public String mVolumeName;
+
+    @Parameters(name = "volume={0}")
+    public static Iterable<? extends Object> data() {
+        return ScopedStorageBaseDeviceTest.getTestParameters();
+    }
+
+    @Before
+    public void setupExternalStorage() {
+        super.setupExternalStorage(mVolumeName);
+        Log.i(TAG, "Using volume : " + mVolumeName);
+    }
+
+
+    /**
+     * Test that app with MANAGE_EXTERNAL_STORAGE permission and targeting
+     * targetSDK=31 or higher will not bypass database operations by default.
+     */
+    @Test
+    public void testManageExternalStorage_DoesntBypassDatabase() throws Exception {
+        testAppDoesntBypassDatabaseOps(APP_FM_DEFAULT);
+    }
+
+    /**
+     * Test that app with MANAGE_EXTERNAL_STORAGE permission, targeting
+     * targetSDK=31 or higher and with requestOptimizedExternalStorageAccess=true
+     * will bypass database operations.
+     */
+    @Test
+    public void testManageExternalStorage_WithBypassFlag_BypassesDatabase() throws Exception {
+        installApp(APP_FM_BYPASS_DATABASE_OPS);
+        try {
+            final int fmUid =
+                    getContext().getPackageManager().getPackageUid(
+                            APP_FM_BYPASS_DATABASE_OPS.getPackageName(), 0);
+            allowAppOpsToUid(fmUid, OPSTR_MANAGE_EXTERNAL_STORAGE);
+            testAppBypassesDatabaseOps(APP_FM_BYPASS_DATABASE_OPS);
+        } finally {
+            uninstallAppNoThrow(APP_FM_BYPASS_DATABASE_OPS);
+        }
+    }
+
+    /**
+     * Test that app with MANAGE_EXTERNAL_STORAGE permission and targeting
+     * targetSDK=30 or lower will bypass database operations by default.
+     */
+    @Test
+    public void testManageExternalStorage_targets30_BypassesDatabase() throws Exception {
+        installApp(APP_FM_TARGETS_30);
+        try {
+            final int fmUid =
+                    getContext().getPackageManager().getPackageUid(
+                            APP_FM_TARGETS_30.getPackageName(), 0);
+            allowAppOpsToUid(fmUid, OPSTR_MANAGE_EXTERNAL_STORAGE);
+            testAppBypassesDatabaseOps(APP_FM_TARGETS_30);
+        } finally {
+            uninstallAppNoThrow(APP_FM_TARGETS_30);
+        }
+    }
+
+    /**
+     * Test that app with SYSTEM_GALLERY role and targeting
+     * targetSDK=current or higher will not bypass database operations by default.
+     */
+    @Test
+    public void testSystemGallery_DoesntBypassDatabase() throws Exception {
+        final int sgUid =
+                getContext().getPackageManager().getPackageUid(
+                        APP_SYSTEM_GALLERY_DEFAULT.getPackageName(), 0);
+        try {
+            allowAppOpsToUid(sgUid, SYSTEM_GALLERY_APPOPS);
+            testAppDoesntBypassDatabaseOps(APP_SYSTEM_GALLERY_DEFAULT);
+        } finally {
+            denyAppOpsToUid(sgUid, SYSTEM_GALLERY_APPOPS);
+        }
+    }
+
+
+    /**
+     * Test that app with SYSTEM_GALLERY role, targeting
+     * targetSDK=current or higher and with requestOptimizedSystemGalleryAccess=true
+     * will bypass database operations.
+     */
+    @Test
+    public void testSystemGallery_WithBypassFlag_BypassesDatabase() throws Exception {
+        installAppWithStoragePermissions(APP_SYSTEM_GALLERY_BYPASS_DB);
+        try {
+            final int sgUid =
+                    getContext().getPackageManager().getPackageUid(
+                            APP_SYSTEM_GALLERY_BYPASS_DB.getPackageName(), 0);
+            allowAppOpsToUid(sgUid, SYSTEM_GALLERY_APPOPS);
+            testAppBypassesDatabaseOps(APP_SYSTEM_GALLERY_BYPASS_DB);
+        } finally {
+            uninstallAppNoThrow(APP_SYSTEM_GALLERY_BYPASS_DB);
+        }
+    }
+
+    /**
+     * Test that app with SYSTEM_GALLERY role and targeting
+     * targetSDK=30 or higher will not bypass database operations by default.
+     */
+    @Test
+    public void testSystemGallery_targets30_DoesntBypassDatabase() throws Exception {
+        installAppWithStoragePermissions(APP_SYSTEM_GALLERY_30);
+        try {
+            final int sgUid =
+                    getContext().getPackageManager().getPackageUid(
+                            APP_SYSTEM_GALLERY_30.getPackageName(), 0);
+            allowAppOpsToUid(sgUid, SYSTEM_GALLERY_APPOPS);
+            testAppDoesntBypassDatabaseOps(APP_SYSTEM_GALLERY_30);
+        } finally {
+            uninstallAppNoThrow(APP_SYSTEM_GALLERY_30);
+        }
+    }
+
+    /**
+     * Test that app with SYSTEM_GALLERY role, targeting
+     * targetSDK=30 or higher and with requestOptimizedSystemGalleryAccess=true
+     * will bypass database operations.
+     */
+    @Test
+    public void testSystemGallery_targets30_WithBypassFlag_BypassesDatabase() throws Exception {
+        installAppWithStoragePermissions(APP_SYSTEM_GALLERY_30_BYPASS_DB);
+        try {
+            final int sgUid =
+                    getContext().getPackageManager().getPackageUid(
+                            APP_SYSTEM_GALLERY_30_BYPASS_DB.getPackageName(), 0);
+            allowAppOpsToUid(sgUid, SYSTEM_GALLERY_APPOPS);
+            testAppBypassesDatabaseOps(APP_SYSTEM_GALLERY_30_BYPASS_DB);
+        } finally {
+            uninstallAppNoThrow(APP_SYSTEM_GALLERY_30_BYPASS_DB);
+        }
+    }
+
+    private void testAppDoesntBypassDatabaseOps(TestApp app) throws Exception {
+        final File file = new File(getDcimDir(), IMAGE_FILE_NAME);
+        final File renamedFile = new File(getPicturesDir(), IMAGE_FILE_NAME);
+        try {
+            assertThat(createFileAs(app, file.getAbsolutePath())).isTrue();
+            // File path create() added file to database.
+            assertThat(TestUtils.checkDatabaseRowExistsAs(app, file)).isTrue();
+
+            assertThat(renameFileAs(app, file, renamedFile)).isTrue();
+            // File path rename() also updates the database row
+            assertThat(TestUtils.checkDatabaseRowExistsAs(app, file)).isFalse();
+            assertThat(TestUtils.checkDatabaseRowExistsAs(app, renamedFile)).isTrue();
+
+            assertThat(deleteFileAs(app, renamedFile.getAbsolutePath())).isTrue();
+            // File path delete() removes database row.
+            assertThat(TestUtils.checkDatabaseRowExistsAs(app, renamedFile)).isFalse();
+        } finally {
+            if (file.exists()) {
+                deleteFileAsNoThrow(app, file.getAbsolutePath());
+            }
+            if (renamedFile.exists()) {
+                deleteFileAsNoThrow(app, renamedFile.getAbsolutePath());
+            }
+        }
+    }
+
+    private void testAppBypassesDatabaseOps(TestApp app) throws Exception {
+        final File file = new File(getDcimDir(), IMAGE_FILE_NAME);
+        final File renamedFile = new File(getPicturesDir(), IMAGE_FILE_NAME);
+        try {
+            assertThat(createFileAs(app, file.getAbsolutePath())).isTrue();
+            // File path create() didn't add the file to database.
+            assertThat(TestUtils.checkDatabaseRowExistsAs(app, file)).isFalse();
+
+            // Ensure file is added to database.
+            assertNotNull(MediaStore.scanFile(getContentResolver(), file));
+
+            assertThat(renameFileAs(app, file, renamedFile)).isTrue();
+            // Rename() didn't update the database row.
+            assertThat(TestUtils.checkDatabaseRowExistsAs(app, file)).isTrue();
+            assertThat(TestUtils.checkDatabaseRowExistsAs(app, renamedFile)).isFalse();
+
+            // Ensure database is updated with renamed path
+            assertNull(MediaStore.scanFile(getContentResolver(), file));
+            assertNotNull(MediaStore.scanFile(getContentResolver(), renamedFile));
+            assertThat(TestUtils.checkDatabaseRowExistsAs(app, renamedFile)).isTrue();
+
+            assertThat(deleteFileAs(app, renamedFile.getAbsolutePath())).isTrue();
+            // Unlink() didn't remove the database row.
+            assertThat(TestUtils.checkDatabaseRowExistsAs(app, renamedFile)).isTrue();
+        } finally {
+            if (file.exists()) {
+                deleteFileAsNoThrow(app, file.getAbsolutePath());
+            }
+            if (renamedFile.exists()) {
+                deleteFileAsNoThrow(app, renamedFile.getAbsolutePath());
+            }
+            MediaStore.scanFile(getContentResolver(), file);
+            MediaStore.scanFile(getContentResolver(), renamedFile);
+        }
+    }
+}
diff --git a/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java b/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java
index ef8fc14..12c1b2c 100644
--- a/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java
+++ b/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java
@@ -107,6 +107,9 @@
             "android.scopedstorage.cts.can_read_and_write";
     public static final String READDIR_QUERY = "android.scopedstorage.cts.readdir";
     public static final String SETATTR_QUERY = "android.scopedstorage.cts.setattr";
+    public static final String CHECK_DATABASE_ROW_EXISTS_QUERY =
+            "android.scopedstorage.cts.check_database_row_exists";
+    public static final String RENAME_FILE_QUERY = "android.scopedstorage.cts.renamefile";
 
     public static final String STR_DATA1 = "Just some random text";
     public static final String STR_DATA2 = "More arbitrary stuff";
@@ -114,6 +117,8 @@
     public static final byte[] BYTES_DATA1 = STR_DATA1.getBytes();
     public static final byte[] BYTES_DATA2 = STR_DATA2.getBytes();
 
+    public static final String RENAME_FILE_PARAMS_SEPARATOR = ";";
+
     // Root of external storage
     private static File sExternalStorageDirectory = Environment.getExternalStorageDirectory();
     private static String sStorageVolumeName = MediaStore.VOLUME_EXTERNAL;
@@ -298,6 +303,30 @@
         return getResultFromTestApp(testApp, file.getPath(), actionName);
     }
 
+    /**
+     * Makes the given {@code testApp} rename give {@code src} to {@code dst}.
+     *
+     * The method concatenates source and destination paths while sending the request to
+     * {@code testApp}. Hence, {@link TestUtils#RENAME_FILE_PARAMS_SEPARATOR} shouldn't be used
+     * in path names.
+     *
+     * <p>This method drops shell permission identity.
+     */
+    public static boolean renameFileAs(TestApp testApp, File src, File dst) throws Exception {
+        final String paths = String.format("%s%s%s",
+                src.getAbsolutePath(), RENAME_FILE_PARAMS_SEPARATOR, dst.getAbsolutePath());
+        return getResultFromTestApp(testApp, paths, RENAME_FILE_QUERY);
+    }
+
+    /**
+     * Makes the given {@code testApp} check if a database row exists for given {@code file}
+     *
+     * <p>This method drops shell permission identity.
+     */
+    public static boolean checkDatabaseRowExistsAs(TestApp testApp, File file) throws Exception {
+        return getResultFromTestApp(testApp, file.getPath(), CHECK_DATABASE_ROW_EXISTS_QUERY);
+    }
+
     public static Uri insertFileFromExternalMedia(boolean useRelative) throws IOException {
         ContentValues values = new ContentValues();
         String filePath =
@@ -579,8 +608,16 @@
      * entry in the database. Returns {@code -1} if file is not found.
      */
     public static int getFileRowIdFromDatabase(@NonNull File file) {
+        return getFileRowIdFromDatabase(getContentResolver(), file);
+    }
+
+    /**
+     * Queries given {@link ContentResolver} for a file and returns the corresponding row ID for
+     * its entry in the database. Returns {@code -1} if file is not found.
+     */
+    public static int getFileRowIdFromDatabase(ContentResolver cr, @NonNull File file) {
         int id = -1;
-        try (Cursor c = queryFile(file, MediaStore.MediaColumns._ID)) {
+        try (Cursor c = queryFile(cr, file, MediaStore.MediaColumns._ID)) {
             if (c.moveToFirst()) {
                 id = c.getInt(0);
             }
@@ -624,7 +661,8 @@
      */
     @NonNull
     public static Cursor queryVideoFile(File file, String... projection) {
-        return queryFile(MediaStore.Video.Media.getContentUri(sStorageVolumeName), file,
+        return queryFile(getContentResolver(),
+                MediaStore.Video.Media.getContentUri(sStorageVolumeName), file,
                 /*includePending*/ true, projection);
     }
 
@@ -634,7 +672,8 @@
      */
     @NonNull
     public static Cursor queryImageFile(File file, String... projection) {
-        return queryFile(MediaStore.Images.Media.getContentUri(sStorageVolumeName), file,
+        return queryFile(getContentResolver(),
+                MediaStore.Images.Media.getContentUri(sStorageVolumeName), file,
                 /*includePending*/ true, projection);
     }
 
@@ -1282,19 +1321,25 @@
      */
     @NonNull
     public static Cursor queryFileExcludingPending(@NonNull File file, String... projection) {
-        return queryFile(MediaStore.Files.getContentUri(sStorageVolumeName), file,
-                /*includePending*/ false, projection);
+        return queryFile(getContentResolver(), MediaStore.Files.getContentUri(sStorageVolumeName),
+                file, /*includePending*/ false, projection);
+    }
+
+    @NonNull
+    public static Cursor queryFile(ContentResolver cr, @NonNull File file, String... projection) {
+        return queryFile(cr, MediaStore.Files.getContentUri(sStorageVolumeName),
+                file, /*includePending*/ true, projection);
     }
 
     @NonNull
     public static Cursor queryFile(@NonNull File file, String... projection) {
-        return queryFile(MediaStore.Files.getContentUri(sStorageVolumeName), file,
-                /*includePending*/ true, projection);
+        return queryFile(getContentResolver(), MediaStore.Files.getContentUri(sStorageVolumeName),
+                file, /*includePending*/ true, projection);
     }
 
     @NonNull
-    private static Cursor queryFile(@NonNull Uri uri, @NonNull File file, boolean includePending,
-            String... projection) {
+    private static Cursor queryFile(ContentResolver cr, @NonNull Uri uri, @NonNull File file,
+            boolean includePending, String... projection) {
         Bundle queryArgs = new Bundle();
         queryArgs.putString(ContentResolver.QUERY_ARG_SQL_SELECTION,
                 MediaStore.MediaColumns.DATA + " = ?");
@@ -1308,7 +1353,7 @@
             queryArgs.putInt(MediaStore.QUERY_ARG_MATCH_PENDING, MediaStore.MATCH_EXCLUDE);
         }
 
-        final Cursor c = getContentResolver().query(uri, projection, queryArgs, null);
+        final Cursor c = cr.query(uri, projection, queryArgs, null);
         assertThat(c).isNotNull();
         return c;
     }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
index 5dc4590..d643084 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
@@ -20,6 +20,7 @@
 import com.android.compatibility.common.util.ResultType;
 import com.android.compatibility.common.util.ResultUnit;
 import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
 import com.android.tradefed.testtype.IBuildReceiver;
 import com.android.tradefed.testtype.IAbi;
 import com.android.tradefed.testtype.IAbiReceiver;
@@ -68,6 +69,11 @@
     private static Map<ITestDevice, String> sTestName = new HashMap<>();
     private static Map<ITestDevice, PocPusher> sPocPusher = new HashMap<>();
 
+    @Option(name = "set-kptr_restrict",
+            description = "If kptr_restrict should be set to 2 after every reboot")
+    private boolean setKptr_restrict = false;
+    private boolean ignoreKernelAddress = false;
+
     /**
      * Waits for device to be online, marks the most recent boottime of the device
      */
@@ -85,6 +91,17 @@
 
         pocPusher.setDevice(getDevice()).setBuild(getBuild()).setAbi(getAbi());
         sPocPusher.put(getDevice(), pocPusher);
+
+        if (setKptr_restrict) {
+            if (getDevice().enableAdbRoot()) {
+                CLog.i("setting kptr_restrict to 2");
+                getDevice().executeShellCommand("echo 2 > /proc/sys/kernel/kptr_restrict");
+                getDevice().disableAdbRoot();
+            } else {
+                // not a rootable device
+                ignoreKernelAddress = true;
+            }
+        }
     }
 
     /**
@@ -160,6 +177,7 @@
      */
     public void assertNotKernelPointer(Callable<String> getPtrFunction, ITestDevice deviceToReboot)
             throws Exception {
+        assumeFalse("Cannot set kptr_restrict to 2, ignoring kptr test.", ignoreKernelAddress);
         String ptr = null;
         for (int i = 0; i < 4; i++) { // ~0.4% chance of false positive
             ptr = getPtrFunction.call();
diff --git a/tests/DropBoxManager/src/android/dropboxmanager/cts/DropBoxTests.java b/tests/DropBoxManager/src/android/dropboxmanager/cts/DropBoxTests.java
index 3b6c7da..879286f 100644
--- a/tests/DropBoxManager/src/android/dropboxmanager/cts/DropBoxTests.java
+++ b/tests/DropBoxManager/src/android/dropboxmanager/cts/DropBoxTests.java
@@ -133,12 +133,18 @@
         restoreDropboxDefaults();
     }
 
-    private void sendExcessiveDropBoxEntries(String tag, int count, long delayPerEntry)
+    private void sendExcessiveDropBoxEntries(String tag, int count, long interval)
             throws Exception {
+        // addText() can take dozens of milliseconds. In order to ensure addText is called at the
+        // given interval, we keep track of the timestamp when the next addText call should occur.
+        long nextTime = SystemClock.elapsedRealtime();
         int i = 0;
         mDropBoxManager.addText(tag, String.valueOf(i++));
         for (; i < count; i++) {
-            Thread.sleep(delayPerEntry);
+            nextTime += interval;
+            // Sleep until when we should send the next entry.
+            final long delay = nextTime - SystemClock.elapsedRealtime();
+            if (delay > 0) Thread.sleep(delay);
             mDropBoxManager.addText(tag, String.valueOf(i));
         }
     }
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
index 8cd1cc4..d9ecad5 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
@@ -290,6 +290,52 @@
                 mTestAppInterface.getLastParams().getStopReason());
     }
 
+    @Test
+    public void testEJStoppedWhenRestricted() throws Exception {
+        mTestAppInterface.scheduleJob(false, false, true);
+        runJob();
+        assertTrue("Job did not start after scheduling",
+                mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
+        setTestPackageRestricted(true);
+        assertTrue("Job did not stop after test app was restricted",
+                mTestAppInterface.awaitJobStop(DEFAULT_WAIT_TIMEOUT));
+        assertEquals(JobParameters.STOP_REASON_BACKGROUND_RESTRICTION,
+                mTestAppInterface.getLastParams().getStopReason());
+    }
+
+    @Test
+    public void testRestrictedEJStartedWhenUnrestricted() throws Exception {
+        setTestPackageRestricted(true);
+        mTestAppInterface.scheduleJob(false, false, true);
+        assertFalse("Job started for restricted app",
+                mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
+        setTestPackageRestricted(false);
+        assertTrue("Job did not start when app was unrestricted",
+                mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
+    }
+
+    @Test
+    public void testRestrictedEJAllowedWhenUidActive() throws Exception {
+        setTestPackageRestricted(true);
+        mTestAppInterface.scheduleJob(false, false, true);
+        assertFalse("Job started for restricted app",
+                mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
+        // Turn the screen on to ensure the app gets into the TOP state.
+        setScreenState(true);
+        mTestAppInterface.startAndKeepTestActivity(true);
+        assertTrue("Job did not start when app had an activity",
+                mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
+
+        mTestAppInterface.closeActivity();
+        // Don't put full minute as the timeout to give some leeway with test timing/processing.
+        assertFalse("Job stopped within grace period after activity closed",
+                mTestAppInterface.awaitJobStop(55_000L));
+        assertTrue("Job did not stop after grace period ended",
+                mTestAppInterface.awaitJobStop(15_000L));
+        assertEquals(JobParameters.STOP_REASON_BACKGROUND_RESTRICTION,
+                mTestAppInterface.getLastParams().getStopReason());
+    }
+
     @RequiresDevice // Emulators don't always have access to wifi/network
     @Test
     public void testBackgroundConnectivityJobsThrottled() throws Exception {
diff --git a/tests/MediaProviderTranscode/res/raw/testVideo_HEVC_long.mp4 b/tests/MediaProviderTranscode/res/raw/testVideo_HEVC_long.mp4
new file mode 100755
index 0000000..6b37153
--- /dev/null
+++ b/tests/MediaProviderTranscode/res/raw/testVideo_HEVC_long.mp4
Binary files differ
diff --git a/tests/MediaProviderTranscode/src/android/mediaprovidertranscode/cts/TranscodeTest.java b/tests/MediaProviderTranscode/src/android/mediaprovidertranscode/cts/TranscodeTest.java
index e7ef396..d91e090 100644
--- a/tests/MediaProviderTranscode/src/android/mediaprovidertranscode/cts/TranscodeTest.java
+++ b/tests/MediaProviderTranscode/src/android/mediaprovidertranscode/cts/TranscodeTest.java
@@ -964,6 +964,28 @@
         }
     }
 
+    @Test
+    public void testTranscodeMultipleFilesConcurrently_longDurationLowVolume() throws Exception {
+        ModernFileOpenerThread[] modernFileOpenerThreads = new ModernFileOpenerThread[5];
+        for (int i = 0; i < modernFileOpenerThreads.length; ++i) {
+            modernFileOpenerThreads[i] = new ModernFileOpenerThread(
+                    ModernFileOpenerThread.FileDurationSeconds.HUNDRED);
+        }
+
+        for (int i = 0; i < modernFileOpenerThreads.length; ++i) {
+            modernFileOpenerThreads[i].start();
+        }
+
+        for (int i = 0; i < modernFileOpenerThreads.length; ++i) {
+            modernFileOpenerThreads[i].join();
+            if (modernFileOpenerThreads[i].mException != null) {
+                throw new Exception("Failed ModernFileOpenerThread - " + i + ": "
+                        + modernFileOpenerThreads[i].mException.getMessage(),
+                        modernFileOpenerThreads[i].mException);
+            }
+        }
+    }
+
     private static final class ModernFileOpenerThread extends Thread {
         private final FileDurationSeconds mFileDurationSeconds;
         Throwable mException;
@@ -993,6 +1015,9 @@
                     case TWENTIES:
                         TranscodeTestUtils.stageMediumHevcVideoFile(modernFile);
                         break;
+                    case HUNDRED:
+                        TranscodeTestUtils.stageLongHevcVideoFile(modernFile);
+                        break;
                     default:
                         throw new IllegalStateException(
                                 "Unknown mFileDurationSeconds: " + mFileDurationSeconds);
@@ -1010,7 +1035,8 @@
 
         enum FileDurationSeconds {
             FEW,
-            TWENTIES
+            TWENTIES,
+            HUNDRED
         }
     }
 }
diff --git a/tests/MediaProviderTranscode/src/android/mediaprovidertranscode/cts/TranscodeTestUtils.java b/tests/MediaProviderTranscode/src/android/mediaprovidertranscode/cts/TranscodeTestUtils.java
index e13dd46..200dfa3 100644
--- a/tests/MediaProviderTranscode/src/android/mediaprovidertranscode/cts/TranscodeTestUtils.java
+++ b/tests/MediaProviderTranscode/src/android/mediaprovidertranscode/cts/TranscodeTestUtils.java
@@ -88,6 +88,10 @@
         return stageVideoFile(videoFile, R.raw.testVideo_HEVC_medium);
     }
 
+    public static Uri stageLongHevcVideoFile(File videoFile) throws IOException {
+        return stageVideoFile(videoFile, R.raw.testVideo_HEVC_long);
+    }
+
     public static Uri stageLegacyVideoFile(File videoFile) throws IOException {
         return stageVideoFile(videoFile, R.raw.testVideo_Legacy);
     }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java b/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
index 4e0c05e..d127589 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
@@ -111,6 +111,8 @@
 import android.util.Log;
 import android.util.Size;
 
+import androidx.test.filters.FlakyTest;
+
 import com.android.compatibility.common.util.AppOpsUtils;
 import com.android.compatibility.common.util.SystemUtil;
 
@@ -596,6 +598,7 @@
         assertEquals(1, mWmState.countStacks(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD));
     }
 
+    @FlakyTest(bugId = 183538974)
     @Test
     public void testDisallowMultipleTasksInPinnedStack() throws Exception {
         // Launch a test activity so that we have multiple fullscreen tasks
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlViewHostTests.java b/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlViewHostTests.java
index 324fb67..571fa9d 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlViewHostTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlViewHostTests.java
@@ -19,6 +19,7 @@
 import static android.server.wm.UiDeviceUtils.pressHomeButton;
 import static android.server.wm.UiDeviceUtils.pressUnlockButton;
 import static android.server.wm.UiDeviceUtils.pressWakeupButton;
+import static android.view.SurfaceControlViewHost.*;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
 import static org.junit.Assert.assertEquals;
@@ -377,4 +378,59 @@
         // assert host has focus
         assertWindowFocused(mSurfaceView, true);
     }
+
+    private static class SurfaceCreatedCallback implements SurfaceHolder.Callback {
+        private final CountDownLatch mSurfaceCreated;
+        SurfaceCreatedCallback(CountDownLatch latch) {
+            mSurfaceCreated = latch;
+        }
+        @Override
+        public void surfaceCreated(SurfaceHolder holder) {
+            mSurfaceCreated.countDown();
+        }
+
+        @Override
+        public void surfaceDestroyed(SurfaceHolder holder) {}
+
+        @Override
+        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
+    }
+
+    @Test
+    public void testCanCopySurfacePackage() throws Throwable {
+        // Create a surface view and wait for its surface to be created.
+        CountDownLatch surfaceCreated = new CountDownLatch(1);
+        mActivityRule.runOnUiThread(() -> {
+            final FrameLayout content = new FrameLayout(mActivity);
+            mSurfaceView = new SurfaceView(mActivity);
+            mSurfaceView.setZOrderOnTop(true);
+            content.addView(mSurfaceView, new FrameLayout.LayoutParams(
+                    DEFAULT_SURFACE_VIEW_WIDTH, DEFAULT_SURFACE_VIEW_HEIGHT, Gravity.LEFT | Gravity.TOP));
+            mActivity.setContentView(content, new ViewGroup.LayoutParams(DEFAULT_SURFACE_VIEW_WIDTH, DEFAULT_SURFACE_VIEW_HEIGHT));
+            mSurfaceView.getHolder().addCallback(new SurfaceCreatedCallback(surfaceCreated));
+
+            // Create an embedded view.
+            mVr = new SurfaceControlViewHost(mActivity, mActivity.getDisplay(),
+                    mSurfaceView.getHostToken());
+            mEmbeddedView = new Button(mActivity);
+            mEmbeddedView.setOnClickListener((View v) -> mClicked = true);
+            mVr.setView(mEmbeddedView, mEmbeddedViewWidth, mEmbeddedViewHeight);
+
+        });
+        surfaceCreated.await();
+
+        // Make a copy of the SurfacePackage and release the original package.
+        SurfacePackage surfacePackage = mVr.getSurfacePackage();
+        SurfacePackage copy = new SurfacePackage(surfacePackage);
+        surfacePackage.release();
+        mSurfaceView.setChildSurfacePackage(copy);
+
+        mInstrumentation.waitForIdleSync();
+        waitUntilEmbeddedViewDrawn();
+
+        // Check if SurfacePackage copy remains valid even though the original package has
+        // been released.
+        CtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mActivityRule, mSurfaceView);
+        assertTrue(mClicked);
+    }
 }
diff --git a/tests/media/src/android/mediav2/cts/EncoderProfileLevelTest.java b/tests/media/src/android/mediav2/cts/EncoderProfileLevelTest.java
index 5d780f0..07e0914 100644
--- a/tests/media/src/android/mediav2/cts/EncoderProfileLevelTest.java
+++ b/tests/media/src/android/mediav2/cts/EncoderProfileLevelTest.java
@@ -209,7 +209,8 @@
                         AVCProfileConstrainedBaseline, AVCProfileConstrainedHigh});
         mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_HEVC,
                 new int[]{HEVCProfileMain, HEVCProfileMain10, HEVCProfileMainStill,
-                        HEVCProfileMain10HDR10, HEVCProfileMain10HDR10Plus});
+                          // TODO: test HDR profiles once they are supported by MediaMuxer
+                          /* HEVCProfileMain10HDR10, HEVCProfileMain10HDR10Plus */});
         mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_H263,
                 new int[]{H263ProfileBaseline, H263ProfileH320Coding,
                         H263ProfileBackwardCompatible, H263ProfileISWV2, H263ProfileISWV3,
@@ -229,8 +230,9 @@
         mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_VP8, new int[]{VP8ProfileMain});
         mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_VP9, new int[]{VP9Profile0, VP9Profile1});
         mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_AV1,
-                new int[]{AV1ProfileMain8, AV1ProfileMain10, AV1ProfileMain10HDR10,
-                        AV1ProfileMain10HDR10Plus});
+                new int[]{AV1ProfileMain8, AV1ProfileMain10,
+                          // TODO: test HDR profiles once they are supported by MediaMuxer
+                          /* AV1ProfileMain10HDR10, AV1ProfileMain10HDR10Plus */});
         mProfileMap.put(MediaFormat.MIMETYPE_AUDIO_AAC,
                 new int[]{AACObjectMain, AACObjectLC, AACObjectSSR, AACObjectLTP, AACObjectHE,
                         AACObjectScalable, AACObjectERLC, AACObjectERScalable, AACObjectLD,
diff --git a/tests/tests/appenumeration/app/source/src/android/appenumeration/cts/query/TestActivity.java b/tests/tests/appenumeration/app/source/src/android/appenumeration/cts/query/TestActivity.java
index a78574b..c304806 100644
--- a/tests/tests/appenumeration/app/source/src/android/appenumeration/cts/query/TestActivity.java
+++ b/tests/tests/appenumeration/app/source/src/android/appenumeration/cts/query/TestActivity.java
@@ -36,6 +36,7 @@
 import static android.appenumeration.cts.Constants.EXTRA_ERROR;
 import static android.appenumeration.cts.Constants.EXTRA_FLAGS;
 import static android.appenumeration.cts.Constants.EXTRA_REMOTE_CALLBACK;
+import static android.appenumeration.cts.Constants.EXTRA_REMOTE_READY_CALLBACK;
 import static android.content.Intent.EXTRA_RETURN_RESULT;
 import static android.content.pm.PackageManager.CERT_INPUT_RAW_X509;
 import static android.os.Process.INVALID_UID;
@@ -68,6 +69,9 @@
 import android.util.SparseArray;
 
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
 
 public class TestActivity extends Activity {
 
@@ -87,6 +91,7 @@
         backgroundHandler = new Handler(backgroundThread.getLooper());
         super.onCreate(savedInstanceState);
         handleIntent(getIntent());
+        onCommandReady(getIntent());
     }
 
     @Override
@@ -184,6 +189,11 @@
                 bindService(remoteCallback, packageName);
             } else if (Constants.ACTION_GET_SYNCADAPTER_TYPES.equals(action)) {
                 sendSyncAdapterTypes(remoteCallback);
+            } else if (Constants.ACTION_AWAIT_PACKAGES_SUSPENDED.equals(action)) {
+                final String[] awaitPackages = intent.getBundleExtra(EXTRA_DATA)
+                        .getStringArray(Intent.EXTRA_PACKAGES);
+                awaitSuspendedPackagesBroadcast(remoteCallback, Arrays.asList(awaitPackages),
+                        Intent.ACTION_PACKAGES_SUSPENDED, TIMEOUT_MS);
             } else {
                 sendError(remoteCallback, new Exception("unknown action " + action));
             }
@@ -192,6 +202,13 @@
         }
     }
 
+    private void onCommandReady(Intent intent) {
+        final RemoteCallback callback = intent.getParcelableExtra(EXTRA_REMOTE_READY_CALLBACK);
+        if (callback != null) {
+            callback.sendResult(null);
+        }
+    }
+
     private void awaitPackageBroadcast(RemoteCallback remoteCallback, String packageName,
             String action, long timeoutMs) {
         final IntentFilter filter = new IntentFilter(action);
@@ -214,6 +231,34 @@
                 token, timeoutMs);
     }
 
+    private void awaitSuspendedPackagesBroadcast(RemoteCallback remoteCallback,
+            List<String> awaitList, String action, long timeoutMs) {
+        final IntentFilter filter = new IntentFilter(action);
+        final ArrayList<String> suspendedList = new ArrayList<>();
+        final Object token = new Object();
+        final Runnable sendResult = () -> {
+            final Bundle result = new Bundle();
+            result.putStringArray(Intent.EXTRA_PACKAGES, suspendedList.toArray(new String[] {}));
+            remoteCallback.sendResult(result);
+            finish();
+        };
+        registerReceiver(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                final Bundle extras = intent.getExtras();
+                final String[] changedList = extras.getStringArray(
+                        Intent.EXTRA_CHANGED_PACKAGE_LIST);
+                suspendedList.addAll(Arrays.stream(changedList).filter(
+                        p -> awaitList.contains(p)).collect(Collectors.toList()));
+                if (suspendedList.size() == awaitList.size()) {
+                    mainHandler.removeCallbacksAndMessages(token);
+                    sendResult.run();
+                }
+            }
+        }, filter);
+        mainHandler.postDelayed(() -> sendResult.run(), token, timeoutMs);
+    }
+
     private void sendGetInstalledPackages(RemoteCallback remoteCallback, int flags) {
         String[] packages =
                 getPackageManager().getInstalledPackages(flags)
diff --git a/tests/tests/appenumeration/lib/src/android/appenumeration/cts/Constants.java b/tests/tests/appenumeration/lib/src/android/appenumeration/cts/Constants.java
index 5a3c12e..6321d04 100644
--- a/tests/tests/appenumeration/lib/src/android/appenumeration/cts/Constants.java
+++ b/tests/tests/appenumeration/lib/src/android/appenumeration/cts/Constants.java
@@ -178,8 +178,11 @@
     public static final String ACTION_BIND_SERVICE = PKG_BASE + "cts.action.BIND_SERVICE";
     public static final String ACTION_GET_SYNCADAPTER_TYPES =
             PKG_BASE + "cts.action.GET_SYNCADAPTER_TYPES";
+    public static final String ACTION_AWAIT_PACKAGES_SUSPENDED =
+            PKG_BASE + "cts.action.AWAIT_PACKAGES_SUSPENDED";
 
     public static final String EXTRA_REMOTE_CALLBACK = "remoteCallback";
+    public static final String EXTRA_REMOTE_READY_CALLBACK = "remoteReadyCallback";
     public static final String EXTRA_ERROR = "error";
     public static final String EXTRA_FLAGS = "flags";
     public static final String EXTRA_DATA = "data";
diff --git a/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java b/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java
index a1adf19..39a8537 100644
--- a/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java
+++ b/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java
@@ -42,6 +42,7 @@
 import static android.appenumeration.cts.Constants.EXTRA_ERROR;
 import static android.appenumeration.cts.Constants.EXTRA_FLAGS;
 import static android.appenumeration.cts.Constants.EXTRA_REMOTE_CALLBACK;
+import static android.appenumeration.cts.Constants.EXTRA_REMOTE_READY_CALLBACK;
 import static android.appenumeration.cts.Constants.QUERIES_ACTIVITY_ACTION;
 import static android.appenumeration.cts.Constants.QUERIES_NOTHING;
 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_PERM;
@@ -92,6 +93,7 @@
 
 import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
 
+import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
 import static org.hamcrest.Matchers.greaterThan;
 import static org.hamcrest.Matchers.greaterThanOrEqualTo;
 import static org.hamcrest.Matchers.hasItemInArray;
@@ -626,7 +628,7 @@
     public void broadcastAdded_notVisibleDoesNotReceive() throws Exception {
         final Result result = sendCommand(QUERIES_NOTHING, TARGET_FILTERS,
                 /* targetUid */ INVALID_UID, /* intentExtra */ null,
-                Constants.ACTION_AWAIT_PACKAGE_ADDED);
+                Constants.ACTION_AWAIT_PACKAGE_ADDED, /* waitForReady */ false);
         runShellCommand("pm install " + TARGET_FILTERS_APK);
         try {
             result.await();
@@ -640,7 +642,7 @@
     public void broadcastAdded_visibleReceives() throws Exception {
         final Result result = sendCommand(QUERIES_ACTIVITY_ACTION, TARGET_FILTERS,
                 /* targetUid */ INVALID_UID, /* intentExtra */ null,
-                Constants.ACTION_AWAIT_PACKAGE_ADDED);
+                Constants.ACTION_AWAIT_PACKAGE_ADDED, /* waitForReady */ false);
         runShellCommand("pm install " + TARGET_FILTERS_APK);
         try {
             Assert.assertEquals(TARGET_FILTERS,
@@ -654,7 +656,7 @@
     public void broadcastRemoved_notVisibleDoesNotReceive() throws Exception {
         final Result result = sendCommand(QUERIES_NOTHING, TARGET_FILTERS,
                 /* targetUid */ INVALID_UID, /* intentExtra */ null,
-                Constants.ACTION_AWAIT_PACKAGE_REMOVED);
+                Constants.ACTION_AWAIT_PACKAGE_REMOVED, /* waitForReady */ false);
         runShellCommand("pm install " + TARGET_FILTERS_APK);
         try {
             result.await();
@@ -668,7 +670,7 @@
     public void broadcastRemoved_visibleReceives() throws Exception {
         final Result result = sendCommand(QUERIES_ACTIVITY_ACTION, TARGET_FILTERS,
                 /* targetUid */ INVALID_UID, /* intentExtra */ null,
-                Constants.ACTION_AWAIT_PACKAGE_REMOVED);
+                Constants.ACTION_AWAIT_PACKAGE_REMOVED, /* waitForReady */ false);
         runShellCommand("pm install " + TARGET_FILTERS_APK);
         try {
             Assert.assertEquals(TARGET_FILTERS,
@@ -679,6 +681,27 @@
     }
 
     @Test
+    public void broadcastSuspended_visibleReceives() throws Exception {
+        assertBroadcastSuspendedVisible(QUERIES_PACKAGE,
+                Arrays.asList(TARGET_NO_API, TARGET_SYNCADAPTER),
+                Arrays.asList(TARGET_NO_API, TARGET_SYNCADAPTER));
+    }
+
+    @Test
+    public void broadcastSuspended_notVisibleDoesNotReceive() throws Exception {
+        assertBroadcastSuspendedVisible(QUERIES_NOTHING,
+                Arrays.asList(),
+                Arrays.asList(TARGET_NO_API, TARGET_SYNCADAPTER));
+    }
+
+    @Test
+    public void broadcastSuspended_visibleReceivesAndNotVisibleDoesNotReceive() throws Exception {
+        assertBroadcastSuspendedVisible(QUERIES_ACTIVITY_ACTION,
+                Arrays.asList(TARGET_FILTERS),
+                Arrays.asList(TARGET_NO_API, TARGET_FILTERS));
+    }
+
+    @Test
     public void queriesResolver_grantsVisibilityToProvider() throws Exception {
         assertNotVisible(QUERIES_NOTHING_PROVIDER, QUERIES_NOTHING_PERM);
 
@@ -796,6 +819,24 @@
                 packageNames, not(hasItemInArray(targetPackageName)));
     }
 
+    private void assertBroadcastSuspendedVisible(String sourcePackageName,
+            List<String> expectedVisiblePackages, List<String> packagesToSuspend)
+            throws Exception {
+        final Bundle extras = new Bundle();
+        extras.putStringArray(Intent.EXTRA_PACKAGES, packagesToSuspend.toArray(new String[] {}));
+        final Result result = sendCommand(sourcePackageName, /* targetPackageName */ null,
+                /* targetUid */ INVALID_UID, extras, Constants.ACTION_AWAIT_PACKAGES_SUSPENDED,
+                /* waitForReady */ true);
+        try {
+            setPackagesSuspended(true, packagesToSuspend);
+            final String[] suspendedPackages = result.await().getStringArray(Intent.EXTRA_PACKAGES);
+            assertThat(suspendedPackages, arrayContainingInAnyOrder(
+                    expectedVisiblePackages.toArray()));
+        } finally {
+            setPackagesSuspended(false, packagesToSuspend);
+        }
+    }
+
     private PackageInfo getPackageInfo(String sourcePackageName, String targetPackageName)
             throws Exception {
         Bundle response = sendCommandBlocking(sourcePackageName, targetPackageName,
@@ -935,12 +976,24 @@
                 .toArray(String[]::new);
     }
 
+    private void setPackagesSuspended(boolean suspend, List<String> packages) {
+        final StringBuilder cmd = new StringBuilder("pm ");
+        if (suspend) {
+            cmd.append("suspend");
+        } else {
+            cmd.append("unsuspend");
+        }
+        packages.stream().forEach(p -> cmd.append(" ").append(p));
+        runShellCommand(cmd.toString());
+    }
+
     interface Result {
         Bundle await() throws Exception;
     }
 
     private Result sendCommand(String sourcePackageName, @Nullable String targetPackageName,
-            int targetUid, @Nullable Parcelable intentExtra, String action) {
+            int targetUid, @Nullable Parcelable intentExtra, String action, boolean waitForReady)
+            throws Exception {
         final Intent intent = new Intent(action)
                 .setComponent(new ComponentName(sourcePackageName, ACTIVITY_CLASS_TEST))
                 // data uri unique to each activity start to ensure actual launch and not just
@@ -972,7 +1025,11 @@
                 },
                 sResponseHandler);
         intent.putExtra(EXTRA_REMOTE_CALLBACK, callback);
-        InstrumentationRegistry.getInstrumentation().getContext().startActivity(intent);
+        if (waitForReady) {
+            startAndWaitForCommandReady(intent);
+        } else {
+            InstrumentationRegistry.getInstrumentation().getContext().startActivity(intent);
+        }
         return () -> {
             if (!latch.block(TimeUnit.SECONDS.toMillis(10))) {
                 throw new TimeoutException(
@@ -986,11 +1043,23 @@
         };
     }
 
+    private void startAndWaitForCommandReady(Intent intent) throws Exception {
+        final ConditionVariable latchForReady = new ConditionVariable();
+        final RemoteCallback readyCallback = new RemoteCallback(bundle -> latchForReady.open(),
+                sResponseHandler);
+        intent.putExtra(EXTRA_REMOTE_READY_CALLBACK, readyCallback);
+        InstrumentationRegistry.getInstrumentation().getContext().startActivity(intent);
+        if (!latchForReady.block(TimeUnit.SECONDS.toMillis(10))) {
+            throw new TimeoutException(
+                    "Latch timed out while awiating a response from command " + intent.getAction());
+        }
+    }
+
     private Bundle sendCommandBlocking(String sourcePackageName, @Nullable String targetPackageName,
             @Nullable Parcelable intentExtra, String action)
             throws Exception {
         final Result result = sendCommand(sourcePackageName, targetPackageName,
-                /* targetUid */ INVALID_UID, intentExtra, action);
+                /* targetUid */ INVALID_UID, intentExtra, action, /* waitForReady */ false);
         return result.await();
     }
 
@@ -998,7 +1067,7 @@
             @Nullable Parcelable intentExtra, String action)
             throws Exception {
         final Result result = sendCommand(sourcePackageName, /* targetPackageName */ null,
-                targetUid, intentExtra, action);
+                targetUid, intentExtra, action, /* waitForReady */ false);
         return result.await();
     }
 }
diff --git a/tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt b/tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt
index dae5d3a..6c4fcc6 100644
--- a/tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt
+++ b/tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt
@@ -28,6 +28,7 @@
 import android.app.AppOpsManager.MODE_DEFAULT
 import android.app.AppOpsManager.MODE_ERRORED
 import android.app.AppOpsManager.MODE_IGNORED
+import android.app.AppOpsManager.OPSTR_PICTURE_IN_PICTURE
 import android.app.AppOpsManager.OPSTR_READ_CALENDAR
 import android.app.AppOpsManager.OPSTR_RECORD_AUDIO
 import android.app.AppOpsManager.OPSTR_WIFI_SCAN
@@ -510,33 +511,33 @@
     fun testNonHistoricalStatePersistence() {
         // Put a package and uid level data
         runWithShellPermissionIdentity {
-            mAppOps.setMode(OPSTR_RECORD_AUDIO, Process.myUid(),
+            mAppOps.setMode(OPSTR_PICTURE_IN_PICTURE, Process.myUid(),
                     mOpPackageName, MODE_IGNORED)
-            mAppOps.setUidMode(OPSTR_RECORD_AUDIO, Process.myUid(), MODE_ERRORED)
+            mAppOps.setUidMode(OPSTR_PICTURE_IN_PICTURE, Process.myUid(), MODE_ERRORED)
 
             // Write the data to disk and read it
             mAppOps.reloadNonHistoricalState()
         }
 
         // Verify the uid state is preserved
-        assertSame(mAppOps.unsafeCheckOpNoThrow(OPSTR_RECORD_AUDIO,
+        assertSame(mAppOps.unsafeCheckOpNoThrow(OPSTR_PICTURE_IN_PICTURE,
                 Process.myUid(), mOpPackageName), MODE_ERRORED)
 
         runWithShellPermissionIdentity {
             // Clear the uid state
-            mAppOps.setUidMode(OPSTR_RECORD_AUDIO, Process.myUid(),
-                    AppOpsManager.opToDefaultMode(OPSTR_RECORD_AUDIO))
+            mAppOps.setUidMode(OPSTR_PICTURE_IN_PICTURE, Process.myUid(),
+                    AppOpsManager.opToDefaultMode(OPSTR_PICTURE_IN_PICTURE))
         }
 
         // Verify the package state is preserved
-        assertSame(mAppOps.unsafeCheckOpNoThrow(OPSTR_RECORD_AUDIO,
+        assertSame(mAppOps.unsafeCheckOpNoThrow(OPSTR_PICTURE_IN_PICTURE,
                 Process.myUid(), mOpPackageName), MODE_IGNORED)
 
         runWithShellPermissionIdentity {
             // Clear the uid state
-            val defaultMode = AppOpsManager.opToDefaultMode(OPSTR_RECORD_AUDIO)
-            mAppOps.setUidMode(OPSTR_RECORD_AUDIO, Process.myUid(), defaultMode)
-            mAppOps.setMode(OPSTR_RECORD_AUDIO, Process.myUid(),
+            val defaultMode = AppOpsManager.opToDefaultMode(OPSTR_PICTURE_IN_PICTURE)
+            mAppOps.setUidMode(OPSTR_PICTURE_IN_PICTURE, Process.myUid(), defaultMode)
+            mAppOps.setMode(OPSTR_PICTURE_IN_PICTURE, Process.myUid(),
                     mOpPackageName, defaultMode)
         }
     }
diff --git a/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java b/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java
index 9e14260..05ecb78 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java
@@ -809,6 +809,24 @@
         doTestInstallSysTrace(TEST_APK_PROFILEABLE);
     }
 
+    @LargeTest
+    @Test
+    public void testInstallSysTraceNoReadlogs() throws Exception {
+        setSystemProperty("debug.incremental.enforce_readlogs_max_interval_for_system_dataloaders",
+                "1");
+        setSystemProperty("debug.incremental.readlogs_max_interval_sec", "0");
+
+        final int atraceDumpIterations = 30;
+        final int atraceDumpDelayMs = 100;
+        final String expected = "|page_read:";
+
+        // We don't expect any readlogs with 0sec interval.
+        assertFalse(
+                "Page reads (" + expected + ") were found in atrace dump",
+                checkSysTraceForSubstring(TEST_APK, expected, atraceDumpIterations,
+                        atraceDumpDelayMs));
+    }
+
     private boolean checkSysTraceForSubstring(String testApk, final String expected,
             int atraceDumpIterations, int atraceDumpDelayMs) throws Exception {
         final int installIterations = 3;
@@ -1094,6 +1112,9 @@
         assertEquals(null, getSplits(TEST_APP_PACKAGE));
         setDeviceProperty("incfs_default_timeouts", null);
         setDeviceProperty("known_digesters_list", null);
+        setSystemProperty("debug.incremental.enforce_readlogs_max_interval_for_system_dataloaders",
+                "0");
+        setSystemProperty("debug.incremental.readlogs_max_interval_sec", "10000");
         IoUtils.closeQuietly(mSession);
         mSession = null;
     }
@@ -1108,5 +1129,9 @@
         }
     }
 
+    private void setSystemProperty(String name, String value) throws Exception {
+        executeShellCommand("setprop " + name + " " + value);
+    }
+
 }
 
diff --git a/tests/tests/gamemanager/AndroidManifest.xml b/tests/tests/gamemanager/AndroidManifest.xml
index 2433674..ca874b9 100644
--- a/tests/tests/gamemanager/AndroidManifest.xml
+++ b/tests/tests/gamemanager/AndroidManifest.xml
@@ -18,7 +18,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="android.gamemanager.cts">
 
-    <application>
+    <application android:appCategory="game">
         <uses-library android:name="android.test.runner"/>
         <activity android:name=".GameManagerCtsActivity"
                   android:label="GameManagerCtsActivity"
diff --git a/tests/tests/gamemanager/src/android/settings/cts/GameManagerCtsActivity.java b/tests/tests/gamemanager/src/android/gamemanager/cts/GameManagerCtsActivity.java
similarity index 100%
rename from tests/tests/gamemanager/src/android/settings/cts/GameManagerCtsActivity.java
rename to tests/tests/gamemanager/src/android/gamemanager/cts/GameManagerCtsActivity.java
diff --git a/tests/tests/gamemanager/src/android/settings/cts/GameManagerTest.java b/tests/tests/gamemanager/src/android/gamemanager/cts/GameManagerTest.java
similarity index 100%
rename from tests/tests/gamemanager/src/android/settings/cts/GameManagerTest.java
rename to tests/tests/gamemanager/src/android/gamemanager/cts/GameManagerTest.java
diff --git a/tests/tests/graphics/src/android/graphics/cts/SystemPalette.java b/tests/tests/graphics/src/android/graphics/cts/SystemPalette.java
index 5718aeb..d9dded5 100644
--- a/tests/tests/graphics/src/android/graphics/cts/SystemPalette.java
+++ b/tests/tests/graphics/src/android/graphics/cts/SystemPalette.java
@@ -31,7 +31,6 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Assert;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -42,7 +41,8 @@
 @RunWith(AndroidJUnit4.class)
 public class SystemPalette {
 
-    private static final double MAX_CHROMA_DISTANCE = 0.1;
+    // Hue goes from 0 to 360
+    private static final int MAX_HUE_DISTANCE = 30;
 
     @Test
     public void testShades0and1000() {
@@ -64,8 +64,6 @@
         }
     }
 
-    // b/183457641
-    @Ignore
     @Test
     public void testAllColorsBelongToSameFamily() {
         final Context context = getInstrumentation().getTargetContext();
@@ -74,35 +72,33 @@
                 getAllNeutral1Colors(context), getAllNeutral2Colors(context));
 
         for (int[] palette : allPalettes) {
-            for (int i = 2; i < palette.length; i++) {
+            for (int i = 2; i < palette.length - 1; i++) {
                 assertWithMessage("Color " + Integer.toHexString((palette[i - 1]))
-                        + " has different chroma compared to " + Integer.toHexString(palette[i]))
-                        .that(similarChroma(palette[i - 1], palette[i])).isTrue();
+                        + " has different chroma compared to " + Integer.toHexString(palette[i])
+                        + " for palette: " + Arrays.toString(palette))
+                        .that(similarHue(palette[i - 1], palette[i])).isTrue();
             }
         }
     }
 
     /**
-     * Compare if color A and B have similar color, in LAB space.
+     * Compare if color A and B have similar hue, in HSL space.
      *
      * @param colorA Color 1
      * @param colorB Color 2
      * @return True when colors have similar chroma.
      */
-    private boolean similarChroma(@ColorInt int colorA, @ColorInt int colorB) {
-        final double[] labColor1 = new double[3];
-        final double[] labColor2 = new double[3];
+    private boolean similarHue(@ColorInt int colorA, @ColorInt int colorB) {
+        final float[] hslColor1 = new float[3];
+        final float[] hslColor2 = new float[3];
 
-        ColorUtils.RGBToLAB(Color.red(colorA), Color.green(colorA), Color.blue(colorA), labColor1);
-        ColorUtils.RGBToLAB(Color.red(colorB), Color.green(colorB), Color.blue(colorB), labColor2);
+        ColorUtils.RGBToHSL(Color.red(colorA), Color.green(colorA), Color.blue(colorA), hslColor1);
+        ColorUtils.RGBToHSL(Color.red(colorB), Color.green(colorB), Color.blue(colorB), hslColor2);
 
-        labColor1[1] = (labColor1[1] + 128.0) / 256;
-        labColor1[2] = (labColor1[2] + 128.0) / 256;
-        labColor2[1] = (labColor2[1] + 128.0) / 256;
-        labColor2[2] = (labColor2[2] + 128.0) / 256;
+        float hue1 = Math.max(hslColor1[0], hslColor2[0]);
+        float hue2 = Math.min(hslColor1[0], hslColor2[0]);
 
-        return (Math.abs(labColor1[1] - labColor2[1]) < MAX_CHROMA_DISTANCE)
-                && (Math.abs(labColor1[2] - labColor2[2]) < MAX_CHROMA_DISTANCE);
+        return hue1 - hue2 < MAX_HUE_DISTANCE;
     }
 
     @Test
diff --git a/tests/tests/graphics/src/android/graphics/text/cts/LineBreakerTest.java b/tests/tests/graphics/src/android/graphics/text/cts/LineBreakerTest.java
index 9fa5fd5..5a20570 100644
--- a/tests/tests/graphics/src/android/graphics/text/cts/LineBreakerTest.java
+++ b/tests/tests/graphics/src/android/graphics/text/cts/LineBreakerTest.java
@@ -582,4 +582,20 @@
         assertEquals(50.0f, r.getLineWidth(1), 0.0f);
         assertEquals(70.0f, r.getLineWidth(2), 0.0f);
     }
+
+    @Test
+    public void testLineBreak_ZeroWidthTab() {
+        final String text = "Hi, \tWorld.";
+        final LineBreaker lb = new LineBreaker.Builder()
+                .setBreakStrategy(BREAK_STRATEGY_SIMPLE)
+                .build();
+        final ParagraphConstraints c = new ParagraphConstraints();
+        c.setWidth(70.0f);
+        c.setTabStops(null, 0);
+        Result r = lb.computeLineBreaks(new MeasuredText.Builder(text.toCharArray())
+                .appendStyleRun(sPaint, text.length(), false)
+                .build(), c, 0);
+        float lw = r.getLineWidth(0);
+        assertFalse(Float.isNaN(lw));
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java b/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
index c545beb..9f46d39 100644
--- a/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
@@ -15,6 +15,8 @@
  */
 package android.media.cts;
 
+import static android.Manifest.permission.MEDIA_CONTENT_CONTROL;
+
 import android.platform.test.annotations.AppModeFull;
 import com.android.compatibility.common.util.SystemUtil;
 
@@ -36,7 +38,6 @@
 import android.os.Process;
 import android.test.InstrumentationTestCase;
 import android.test.UiThreadTest;
-import android.util.Log;
 import android.view.KeyEvent;
 
 import java.io.IOException;
@@ -44,6 +45,7 @@
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 
 @AppModeFull(reason = "TODO: evaluate and port to instant")
@@ -63,6 +65,7 @@
 
     @Override
     protected void tearDown() throws Exception {
+        getInstrumentation().getUiAutomation().dropShellPermissionIdentity();
         super.tearDown();
     }
 
@@ -76,6 +79,15 @@
         // TODO enable a notification listener, test again, disable, test again
     }
 
+    public void testGetMediaKeyEventSession() throws Exception {
+        try {
+            mSessionManager.getMediaKeyEventSession();
+            fail("Expected security exception for call to getMediaKeyEventSession");
+        } catch (SecurityException ex) {
+            // Expected
+        }
+    }
+
     @UiThreadTest
     public void testAddOnActiveSessionsListener() throws Exception {
         try {
@@ -528,6 +540,23 @@
         }
     }
 
+    private class MediaKeyEventSessionListener
+            implements MediaSessionManager.OnMediaKeyEventSessionChangedListener {
+        final CountDownLatch mCountDownLatch;
+        MediaSession.Token mSessionToken;
+
+        MediaKeyEventSessionListener() {
+            mCountDownLatch = new CountDownLatch(1);
+        }
+
+        @Override
+        public void onMediaKeyEventSessionChanged(String packageName,
+                MediaSession.Token sessionToken) {
+            mCountDownLatch.countDown();
+            mSessionToken = sessionToken;
+        }
+    }
+
     private static class HandlerExecutor implements Executor {
         private final Handler mHandler;
 
diff --git a/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/NotificationAssistantServiceTest.java b/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/NotificationAssistantServiceTest.java
index 36d52e6..af70d69 100644
--- a/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/NotificationAssistantServiceTest.java
+++ b/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/NotificationAssistantServiceTest.java
@@ -25,6 +25,7 @@
 
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
 
 import android.app.Instrumentation;
 import android.app.Notification;
@@ -77,6 +78,10 @@
     private Context mContext;
     private UiAutomation mUi;
 
+    private boolean isWatch() {
+      return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
+    }
+
     @Before
     public void setUp() throws IOException {
         mUi = InstrumentationRegistry.getInstrumentation().getUiAutomation();
@@ -556,6 +561,7 @@
         if (isTelevision()) {
             return;
         }
+        assumeFalse("Status bar service not supported", isWatch());
         setUpListeners();
         turnScreenOn();
         mUi.adoptShellPermissionIdentity("android.permission.EXPAND_STATUS_BAR");
@@ -587,6 +593,7 @@
         if (isTelevision()) {
             return;
         }
+        assumeFalse("Status bar service not supported", isWatch());
         setUpListeners();
         turnScreenOn();
         mUi.adoptShellPermissionIdentity("android.permission.EXPAND_STATUS_BAR");
@@ -612,6 +619,7 @@
         if (isTelevision()) {
             return;
         }
+        assumeFalse("Status bar service not supported", isWatch());
         setUpListeners();
         turnScreenOn();
         mUi.adoptShellPermissionIdentity("android.permission.EXPAND_STATUS_BAR");
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index 0acd373..4969752 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -1987,6 +1987,12 @@
     <permission android:name="android.permission.BLUETOOTH_STACK"
         android:protectionLevel="signature" />
 
+    <!-- Allows uhid write access for creating virtual input devices
+         @hide
+    -->
+    <permission android:name="android.permission.VIRTUAL_INPUT_DEVICE"
+        android:protectionLevel="signature" />
+
     <!-- Allows applications to perform I/O operations over NFC.
          <p>Protection level: normal
     -->
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0394.java b/tests/tests/security/src/android/security/cts/CVE_2021_0394.java
index d3278ee..6d504f6 100644
--- a/tests/tests/security/src/android/security/cts/CVE_2021_0394.java
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0394.java
@@ -16,12 +16,12 @@
 
 package android.security.cts;
 
-import static org.junit.Assert.assertFalse;
-
 import android.platform.test.annotations.SecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import androidx.test.filters.RequiresDevice;
 import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+import static org.junit.Assert.assertFalse;
 
 @RunWith(AndroidJUnit4.class)
 public class CVE_2021_0394 {
@@ -34,6 +34,9 @@
      */
     @SecurityTest(minPatchLevel = "2021-03")
     @Test
+    @RequiresDevice
+    // emulators always have checkJNI enabled which causes the test
+    // to abort the VM while passing invalid input to NewStringUTF
     public void testPocCVE_2021_0394() throws Exception {
         assertFalse(poc());
     }
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
index 21abe14..4a550fe 100755
--- a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
@@ -40,6 +40,7 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
+import android.net.Uri;
 import android.os.Looper;
 import android.os.ParcelUuid;
 import android.os.PersistableBundle;
@@ -89,6 +90,11 @@
     private static final String TAG = "SubscriptionManagerTest";
     private static final String MODIFY_PHONE_STATE = "android.permission.MODIFY_PHONE_STATE";
     private SubscriptionManager mSm;
+    private static final List<Uri> CONTACTS = new ArrayList<>();
+    static {
+        CONTACTS.add(Uri.fromParts("tel", "+16505551212", null));
+        CONTACTS.add(Uri.fromParts("tel", "+16505552323", null));
+    }
 
     private int mSubId;
     private String mPackageName;
@@ -956,6 +962,17 @@
         uiAutomation.dropShellPermissionIdentity();
     }
 
+    @Test
+    public void testSetAndGetD2DSharingContacts() {
+        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        uiAutomation.adoptShellPermissionIdentity(MODIFY_PHONE_STATE);
+        List<Uri> originalD2DSharingContacts = mSm.getDeviceToDeviceStatusSharingContacts(mSubId);
+        mSm.setDeviceToDeviceStatusSharingContacts(CONTACTS, mSubId);
+        assertEquals(CONTACTS, mSm.getDeviceToDeviceStatusSharingContacts(mSubId));
+        mSm.setDeviceToDeviceStatusSharingContacts(originalD2DSharingContacts, mSubId);
+        uiAutomation.dropShellPermissionIdentity();
+    }
+
     @Nullable
     private PersistableBundle getBundleFromBackupData(byte[] data) {
         try (ByteArrayInputStream bis = new ByteArrayInputStream(data)) {
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
index 9c8aba4..d3861c6 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
@@ -1134,8 +1134,8 @@
         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
             int networkResp = 200;
             String reason = "";
-            listener.onPublish();
             cb.onNetworkResponse(networkResp, reason);
+            listener.onPublish();
         });
 
         // Unregister the publish state callback
@@ -1278,8 +1278,8 @@
             pidfQueue.offer(pidfXml);
             int networkResp = 200;
             String reason = "";
-            listener.onPublish();
             cb.onNetworkResponse(networkResp, reason);
+            listener.onPublish();
         });
 
         LinkedBlockingQueue<ImsRegistrationAttributes> mQueue = new LinkedBlockingQueue<>();
@@ -1409,8 +1409,8 @@
         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
             int networkResp = 200;
             String reason = "OK";
-            listener.onPublish();
             cb.onNetworkResponse(networkResp, reason);
+            listener.onPublish();
         });
 
         // IMS registers
@@ -1449,8 +1449,8 @@
             String reason = "";
             int reasonHeaderCause = 400;
             String reasonHeaderText = "Bad Request";
-            listener.onPublish();
             cb.onNetworkResponse(networkResp, reason, reasonHeaderCause, reasonHeaderText);
+            listener.onPublish();
         });
 
         // ImsService triggers to notify framework publish device's capabilities.
@@ -1504,8 +1504,8 @@
         capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
             int networkResp = 200;
             String reason = "OK";
-            listener.onPublish();
             cb.onNetworkResponse(networkResp, reason);
+            listener.onPublish();
         });
 
         // Register the callback to listen to the publish state changed
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/SipDelegateManagerTest.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/SipDelegateManagerTest.java
index 95935ac..84916bc 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/SipDelegateManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/SipDelegateManagerTest.java
@@ -83,6 +83,9 @@
     private static final String FILE_TRANSFER_HTTP_TAG =
             "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gppapplication.ims.iari.rcs.fthttp\"";
 
+    private static final String[] DEFAULT_FEATURE_TAGS = {
+            ONE_TO_ONE_CHAT_TAG, GROUP_CHAT_TAG, FILE_TRANSFER_HTTP_TAG};
+
     private static class CarrierConfigReceiver extends BroadcastReceiver {
         private CountDownLatch mLatch = new CountDownLatch(1);
         private final int mSubId;
@@ -149,6 +152,8 @@
             // APIs.
             sServiceConnector.setDeviceSingleRegistrationEnabled(true);
         }
+
+        setFeatureTagsCarrierAllowed(DEFAULT_FEATURE_TAGS);
     }
 
     @AfterClass
@@ -871,6 +876,41 @@
         assertTrue(Arrays.equals(decodedMsg.getContent(), m.getContent()));
     }
 
+    @Test
+    public void testFeatureTagDeniedByCarrierConfig() throws Exception {
+        if (!ImsUtils.shouldTestImsService()) {
+            return;
+        }
+
+        setFeatureTagsCarrierAllowed(new String[]{FILE_TRANSFER_HTTP_TAG});
+        assertTrue(sServiceConnector.setDefaultSmsApp());
+        connectTestImsServiceWithSipTransportAndConfig();
+        TestSipTransport transportImpl = sServiceConnector.getCarrierService().getSipTransport();
+        TestImsRegistration regImpl = sServiceConnector.getCarrierService().getImsRegistration();
+        SipDelegateManager manager = getSipDelegateManager();
+        DelegateRequest request = getDefaultRequest();
+        TestSipDelegateConnection delegateConn = new TestSipDelegateConnection(request);
+        Set<String> deniedTags = new ArraySet<>(request.getFeatureTags());
+        deniedTags.remove(FILE_TRANSFER_HTTP_TAG);
+
+        TestSipDelegate delegate = createSipDelegateConnectionAndVerify(manager, delegateConn,
+                transportImpl, getDeniedTagsForReason(deniedTags,
+                        SipDelegateManager.DENIED_REASON_NOT_ALLOWED), 0);
+        assertNotNull(delegate);
+
+        Set<String> registeredTags = new ArraySet<>(
+                Arrays.asList(new String[]{FILE_TRANSFER_HTTP_TAG}));
+        delegateConn.setOperationCountDownLatch(1);
+        DelegateRegistrationState s = getRegisteredRegistrationState(registeredTags);
+        delegate.notifyImsRegistrationUpdate(s);
+        delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS);
+        delegateConn.verifyRegistrationStateEquals(s);
+        destroySipDelegateAndVerify(manager, transportImpl, delegateConn, delegate, registeredTags);
+        assertEquals("There should be no more delegates", 0,
+                transportImpl.getDelegates().size());
+        setFeatureTagsCarrierAllowed(getDefaultRequest().getFeatureTags().toArray(new String[0]));
+    }
+
     private SipMessage generateSipMessage(String str) {
         String crlf = "\r\n";
         String[] components = str.split(crlf);
@@ -1151,17 +1191,14 @@
     }
 
     private DelegateRequest getDefaultRequest() {
-        ArraySet<String> features = new ArraySet<>(3);
-        features.add(TestSipTransport.ONE_TO_ONE_CHAT_TAG);
-        features.add(TestSipTransport.GROUP_CHAT_TAG);
-        features.add(TestSipTransport.FILE_TRANSFER_HTTP_TAG);
+        ArraySet<String> features = new ArraySet<>(Arrays.asList(DEFAULT_FEATURE_TAGS));
         return new DelegateRequest(features);
     }
 
     private DelegateRequest getChatOnlyRequest() {
         ArraySet<String> features = new ArraySet<>(3);
-        features.add(TestSipTransport.ONE_TO_ONE_CHAT_TAG);
-        features.add(TestSipTransport.GROUP_CHAT_TAG);
+        features.add(ONE_TO_ONE_CHAT_TAG);
+        features.add(GROUP_CHAT_TAG);
         return new DelegateRequest(features);
     }
 
@@ -1172,12 +1209,18 @@
                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
                 .build();
     }
+
     private ImsFeatureConfiguration getConfigForRcs() {
         return new ImsFeatureConfiguration.Builder()
                 .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
                 .build();
     }
 
+    private Set<FeatureTagState> getDeniedTagsForReason(Set<String> deniedTags, int reason) {
+        return deniedTags.stream().map(t -> new FeatureTagState(t, reason))
+                .collect(Collectors.toSet());
+    }
+
     private static void overrideCarrierConfig(PersistableBundle bundle) throws Exception {
         CarrierConfigManager carrierConfigManager = InstrumentationRegistry.getInstrumentation()
                 .getContext().getSystemService(CarrierConfigManager.class);
@@ -1187,6 +1230,13 @@
         sReceiver.waitForCarrierConfigChanged();
     }
 
+    private static void setFeatureTagsCarrierAllowed(String[] tags) throws Exception {
+        PersistableBundle bundle = new PersistableBundle();
+        bundle.putStringArray(CarrierConfigManager.Ims.KEY_RCS_FEATURE_TAG_ALLOWED_STRING_ARRAY,
+                tags);
+        overrideCarrierConfig(bundle);
+    }
+
     private SipDelegateManager getSipDelegateManager() {
         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
         assertNotNull(imsManager);
diff --git a/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/ServiceStateTest.java b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/ServiceStateTest.java
index 8fab865..7318e8b 100644
--- a/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/ServiceStateTest.java
+++ b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/ServiceStateTest.java
@@ -17,6 +17,8 @@
 package android.telephonyprovider.cts;
 
 import static android.provider.Telephony.ServiceStateTable.DATA_NETWORK_TYPE;
+import static android.provider.Telephony.ServiceStateTable.DATA_REG_STATE;
+import static android.provider.Telephony.ServiceStateTable.DUPLEX_MODE;
 import static android.provider.Telephony.ServiceStateTable.VOICE_REG_STATE;
 import static android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
 
@@ -215,6 +217,99 @@
     }
 
     /**
+     * Verifies that the duplex mode is valid and matches ServiceState#getDuplexMode().
+     */
+    @Test
+    public void testGetDuplexMode_query() {
+        try (Cursor cursor = mContentResolver.query(Telephony.ServiceStateTable.CONTENT_URI,
+                new String[]{DUPLEX_MODE}, null, null)) {
+            assertThat(cursor.getCount()).isEqualTo(1);
+            cursor.moveToNext();
+
+            int duplexMode = cursor.getInt(cursor.getColumnIndex(DUPLEX_MODE));
+            assertThat(duplexMode).isEqualTo(mTelephonyManager.getServiceState().getDuplexMode());
+        }
+    }
+
+    /**
+     * Verifies that even we have duplex mode change, the observer should not receive the
+     * notification (duplex mode is a poll-only field).
+     */
+    @Test
+    public void testGetDuplexMode_noChangeObserved() throws Exception {
+        ServiceState oldSS = new ServiceState();
+        oldSS.setStateOutOfService();
+
+        ServiceState newSS = new ServiceState();
+        newSS.setStateOutOfService();
+
+        // Add NRI to trigger SS with duplex mode updated
+        NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder()
+                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
+                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
+                .build();
+        newSS.addNetworkRegistrationInfo(nri);
+        newSS.setChannelNumber(65536); // EutranBand.BAND_65, DUPLEX_MODE_FDD
+
+        verifyNotificationObservedWhenFieldChanged(
+                DUPLEX_MODE, oldSS, newSS, false /*expectChange*/);
+    }
+
+    /**
+     * Verifies that the data reg state is valid and matches ServiceState#getDataRegState()
+     */
+    @Test
+    public void testGetDataRegState_query() {
+        try (Cursor cursor = mContentResolver.query(Telephony.ServiceStateTable.CONTENT_URI,
+                new String[]{DATA_REG_STATE}, null, null)) {
+            assertThat(cursor.getCount()).isEqualTo(1);
+            cursor.moveToNext();
+
+            int dataRegState = cursor.getInt(cursor.getColumnIndex(DATA_REG_STATE));
+            assertThat(dataRegState).isEqualTo(
+                    mTelephonyManager.getServiceState().getDataRegState());
+        }
+    }
+
+    /**
+     * Verifies that when data reg state did not change, the observer should not receive the
+     * notification.
+     */
+    @Test
+    public void testGetDataRegState_noChangeObserved() throws Exception {
+        ServiceState oldSS = new ServiceState();
+        oldSS.setStateOutOfService();
+        oldSS.setState(ServiceState.STATE_OUT_OF_SERVICE);
+
+        ServiceState copyOfOldSS = new ServiceState();
+        copyOfOldSS.setStateOutOfService();
+        copyOfOldSS.setState(ServiceState.STATE_OUT_OF_SERVICE);
+        // set additional fields which is not related to data reg state
+        copyOfOldSS.setChannelNumber(65536);
+        copyOfOldSS.setIsManualSelection(true);
+
+        verifyNotificationObservedWhenFieldChanged(
+                DATA_REG_STATE, oldSS, copyOfOldSS, false /*expectChange*/);
+    }
+
+    /**
+     * Verifies that when data reg state changed, the observer should receive the notification.
+     */
+    @Test
+    public void testGetDataRegState_changeObserved() throws Exception {
+        ServiceState oldSS = new ServiceState();
+        oldSS.setStateOutOfService();
+
+        ServiceState newSS = new ServiceState();
+        newSS.setStateOutOfService();
+        newSS.setStateOff();
+
+        verifyNotificationObservedWhenFieldChanged(
+                DATA_REG_STATE, oldSS, newSS, true /*expectChange*/);
+    }
+
+    /**
      * Insert new ServiceState over the old ServiceState and expect the observer receiving the
      * notification over the observed field change.
      */
diff --git a/tests/tests/vcn/src/android/net/vcn/cts/VcnManagerTest.java b/tests/tests/vcn/src/android/net/vcn/cts/VcnManagerTest.java
index 81e0a01..71d6835 100644
--- a/tests/tests/vcn/src/android/net/vcn/cts/VcnManagerTest.java
+++ b/tests/tests/vcn/src/android/net/vcn/cts/VcnManagerTest.java
@@ -232,14 +232,14 @@
 
     /** Test implementation of VcnStatusCallback for verification purposes. */
     private static class TestVcnStatusCallback extends VcnManager.VcnStatusCallback {
-        private final CompletableFuture<Integer> mFutureOnVcnStatusChanged =
+        private final CompletableFuture<Integer> mFutureOnStatusChanged =
                 new CompletableFuture<>();
         private final CompletableFuture<GatewayConnectionError> mFutureOnGatewayConnectionError =
                 new CompletableFuture<>();
 
         @Override
-        public void onVcnStatusChanged(int statusCode) {
-            mFutureOnVcnStatusChanged.complete(statusCode);
+        public void onStatusChanged(int statusCode) {
+            mFutureOnStatusChanged.complete(statusCode);
         }
 
         @Override
@@ -249,8 +249,8 @@
                     new GatewayConnectionError(networkCapabilities, errorCode, detail));
         }
 
-        public int awaitOnVcnStatusChanged() throws Exception {
-            return mFutureOnVcnStatusChanged.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        public int awaitOnStatusChanged() throws Exception {
+            return mFutureOnStatusChanged.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
         }
 
         public GatewayConnectionError awaitOnGatewayConnectionError() throws Exception {
@@ -289,7 +289,7 @@
         try {
             registerVcnStatusCallbackForSubId(callback, subId);
 
-            final int statusCode = callback.awaitOnVcnStatusChanged();
+            final int statusCode = callback.awaitOnStatusChanged();
             assertEquals(VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED, statusCode);
         } finally {
             mVcnManager.unregisterVcnStatusCallback(callback);
diff --git a/tests/tests/view/src/android/view/cts/FrameMetricsListenerTest.java b/tests/tests/view/src/android/view/cts/FrameMetricsListenerTest.java
index 6ee1441..c6476bf 100644
--- a/tests/tests/view/src/android/view/cts/FrameMetricsListenerTest.java
+++ b/tests/tests/view/src/android/view/cts/FrameMetricsListenerTest.java
@@ -209,8 +209,11 @@
         assertTrue(intended_vsync < now);
         assertTrue(vsync < now);
         assertTrue(vsync >= intended_vsync);
+
+        // swapBuffers and gpuDuration may happen in parallel, so instead of counting both we need
+        // to take the longer of the two.
         assertTrue(totalDuration >= unknownDelay + input + animation + layoutMeasure + draw + sync
-                + commandIssue + swapBuffers + gpuDuration);
+                + commandIssue + Math.max(gpuDuration, swapBuffers));
 
         // This is the only boolean metric so far
         final long firstDrawFrameMetric = frameMetrics.getMetric(FrameMetrics.FIRST_DRAW_FRAME);
diff --git a/tests/tests/voiceinteraction/common/Android.bp b/tests/tests/voiceinteraction/common/Android.bp
index 1d8d77e..e9052de 100644
--- a/tests/tests/voiceinteraction/common/Android.bp
+++ b/tests/tests/voiceinteraction/common/Android.bp
@@ -18,8 +18,6 @@
 
 java_library {
     name: "CtsVoiceInteractionCommon",
-    srcs: ["src/**/*.java",
-           "src/**/*.aidl"
-    ],
+    srcs: ["src/**/*.java"],
     sdk_version: "current",
 }
diff --git a/tests/tests/voiceinteraction/common/src/android/voiceinteraction/common/ICtsHotwordDetectionServiceCallback.aidl b/tests/tests/voiceinteraction/common/src/android/voiceinteraction/common/ICtsHotwordDetectionServiceCallback.aidl
deleted file mode 100644
index 3955dc0..0000000
--- a/tests/tests/voiceinteraction/common/src/android/voiceinteraction/common/ICtsHotwordDetectionServiceCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2021 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.voiceinteraction.common;
-
-/**
- * Callback for returning the test result from the HotwordDetectionService.
- */
-oneway interface ICtsHotwordDetectionServiceCallback {
-    /**
-     * Called to return the test result.
-     */
-    void onTestResult(int result);
-}
diff --git a/tests/tests/voiceinteraction/common/src/android/voiceinteraction/common/Utils.java b/tests/tests/voiceinteraction/common/src/android/voiceinteraction/common/Utils.java
index 553cbb4..dd60884 100644
--- a/tests/tests/voiceinteraction/common/src/android/voiceinteraction/common/Utils.java
+++ b/tests/tests/voiceinteraction/common/src/android/voiceinteraction/common/Utils.java
@@ -139,7 +139,6 @@
     public static final String KEY_SERVICE_TYPE = "serviceType";
     public static final String KEY_TEST_EVENT = "testEvent";
     public static final String KEY_TEST_RESULT = "testResult";
-    public static final String KEY_TEST_FAKE_BINDER = "testFakeBinder";
 
     public static final String toBundleString(Bundle bundle) {
         if (bundle == null) {
diff --git a/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/BasicVoiceInteractionService.java b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/BasicVoiceInteractionService.java
index 4b6bb95..29b35b7 100644
--- a/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/BasicVoiceInteractionService.java
+++ b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/BasicVoiceInteractionService.java
@@ -19,14 +19,12 @@
 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
 
 import android.content.Intent;
-import android.os.Bundle;
-import android.os.RemoteException;
+import android.os.PersistableBundle;
 import android.os.SharedMemory;
 import android.service.voice.AlwaysOnHotwordDetector;
 import android.service.voice.VoiceInteractionService;
 import android.system.ErrnoException;
 import android.util.Log;
-import android.voiceinteraction.common.ICtsHotwordDetectionServiceCallback;
 import android.voiceinteraction.common.Utils;
 
 import java.nio.ByteBuffer;
@@ -39,6 +37,8 @@
     // TODO: (b/182236586) Refactor the voice interaction service logic
     static final String TAG = "BasicVoiceInteractionService";
 
+    public static String KEY_FAKE_DATA = "fakeData";
+    public static String VALUE_FAKE_DATA = "fakeData";
     public static byte[] FAKE_BYTE_ARRAY_DATA = new byte[] {1, 2, 3};
 
     private boolean mReady = false;
@@ -76,7 +76,7 @@
         try {
             createAlwaysOnHotwordDetector(/* keyphrase */ "Hello Google",
                     Locale.forLanguageTag("en-US"),
-                    createFakeBundleData(),
+                    createFakePersistableBundleData(),
                     createFakeSharedMemoryData(),
                     new AlwaysOnHotwordDetector.Callback() {
                         @Override
@@ -137,21 +137,10 @@
         }
     }
 
-    private Bundle createFakeBundleData() {
+    private PersistableBundle createFakePersistableBundleData() {
         // TODO : Add more data for testing
-        Bundle bundle = new Bundle();
-        bundle.putByteArray("fakeData", FAKE_BYTE_ARRAY_DATA);
-        ICtsHotwordDetectionServiceCallback callback =
-                new ICtsHotwordDetectionServiceCallback.Stub() {
-            @Override
-            public void onTestResult(int result) throws RemoteException {
-                Log.d(TAG, "onTestResult result = " + result);
-                broadcastIntentWithResult(
-                        Utils.BROADCAST_HOTWORD_DETECTION_SERVICE_TRIGGER_RESULT_INTENT,
-                        result);
-            }
-        };
-        bundle.putBinder(Utils.KEY_TEST_FAKE_BINDER, callback.asBinder());
-        return bundle;
+        PersistableBundle persistableBundle = new PersistableBundle();
+        persistableBundle.putString(KEY_FAKE_DATA, VALUE_FAKE_DATA);
+        return persistableBundle;
     }
 }
diff --git a/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainHotwordDetectionService.java b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainHotwordDetectionService.java
index 2ebdc4e..9bfe321 100644
--- a/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainHotwordDetectionService.java
+++ b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainHotwordDetectionService.java
@@ -17,16 +17,13 @@
 package android.voiceinteraction.service;
 
 import android.media.AudioFormat;
-import android.os.Bundle;
-import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
+import android.os.PersistableBundle;
 import android.os.SharedMemory;
 import android.service.voice.HotwordDetectionService;
 import android.system.ErrnoException;
+import android.text.TextUtils;
 import android.util.Log;
-import android.voiceinteraction.common.ICtsHotwordDetectionServiceCallback;
-import android.voiceinteraction.common.Utils;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -49,29 +46,22 @@
     }
 
     @Override
-    public void onUpdateState(@Nullable Bundle options, @Nullable SharedMemory sharedMemory) {
+    public void onUpdateState(@Nullable PersistableBundle options,
+            @Nullable SharedMemory sharedMemory) {
         Log.d(TAG, "onUpdateState");
 
-        ICtsHotwordDetectionServiceCallback callback = null;
         if (options != null) {
-            IBinder binder = options.getBinder(Utils.KEY_TEST_FAKE_BINDER);
-            callback = ICtsHotwordDetectionServiceCallback.Stub.asInterface(binder);
-        }
-
-        if (callback == null) {
-            Log.w(TAG, "no callback to return the test result");
-            return;
+            String fakeData = options.getString(BasicVoiceInteractionService.KEY_FAKE_DATA);
+            if (!TextUtils.equals(fakeData, BasicVoiceInteractionService.VALUE_FAKE_DATA)) {
+                Log.d(TAG, "options : data is not the same");
+                return;
+            }
         }
 
         if (sharedMemory != null) {
             try {
                 sharedMemory.mapReadWrite();
-                try {
-                    callback.onTestResult(
-                            Utils.HOTWORD_DETECTION_SERVICE_TRIGGER_SHARED_MEMORY_NOT_READ_ONLY);
-                } catch (RemoteException e) {
-                    Log.d(TAG, "call onTestResult RemoteException : " + e);
-                }
+                Log.d(TAG, "sharedMemory : is not read-only");
                 return;
             } catch (ErrnoException e) {
                 // For read-only case
@@ -79,11 +69,7 @@
                 sharedMemory.close();
             }
         }
-        try {
-            callback.onTestResult(
-                    Utils.HOTWORD_DETECTION_SERVICE_TRIGGER_SUCCESS);
-        } catch (RemoteException e) {
-            Log.d(TAG, "call onTestResult RemoteException : " + e);
-        }
+        // Report success
+        Log.d(TAG, "onUpdateState success");
     }
 }
diff --git a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceBasicTest.java b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceBasicTest.java
index 6fe406e..0b11257 100644
--- a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceBasicTest.java
+++ b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceBasicTest.java
@@ -26,6 +26,7 @@
 
 import com.android.compatibility.common.util.BlockingBroadcastReceiver;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -39,6 +40,7 @@
     static final String TAG = "HotwordDetectionServiceBasicTest";
 
     @Test
+    @Ignore
     public void testHotwordDetectionService_validHotwordDetectionComponentName_triggerSuccess()
             throws Throwable {
         final BlockingBroadcastReceiver receiver = new BlockingBroadcastReceiver(mContext,
diff --git a/tests/tests/wifi/TEST_MAPPING b/tests/tests/wifi/TEST_MAPPING
index e80f848..7ddc308 100644
--- a/tests/tests/wifi/TEST_MAPPING
+++ b/tests/tests/wifi/TEST_MAPPING
@@ -9,8 +9,7 @@
       ]
     }
   ],
-  // TODO(b/179512200): move to mainline-presubmit once passing
-  "mainline-postsubmit": [
+  "mainline-presubmit": [
     {
       "name": "CtsWifiTestCases[com.google.android.wifi.apex]",
       "options": [
diff --git a/tests/translation/AndroidManifest.xml b/tests/translation/AndroidManifest.xml
index d1803bf..3ea50e9 100644
--- a/tests/translation/AndroidManifest.xml
+++ b/tests/translation/AndroidManifest.xml
@@ -37,6 +37,10 @@
             <intent-filter>
                 <action android:name="android.service.translation.TranslationService"/>
             </intent-filter>
+            <meta-data
+                android:name="android.translation_service"
+                android:resource="@xml/translation_config">
+            </meta-data>
         </service>
         <service android:name=".CtsContentCaptureService"
                  android:label="CtsContentCaptureService"
diff --git a/tests/translation/res/xml/translation_config.xml b/tests/translation/res/xml/translation_config.xml
new file mode 100644
index 0000000..6ab30d5
--- /dev/null
+++ b/tests/translation/res/xml/translation_config.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2021, 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.
+*/
+-->
+<translation-service xmlns:android="http://schemas.android.com/apk/res/android"
+                     android:settingsActivity="android.translation.cts.SimpleActivity">
+</translation-service>
\ No newline at end of file
diff --git a/tests/translation/src/android/translation/cts/TranslationManagerTest.java b/tests/translation/src/android/translation/cts/TranslationManagerTest.java
index a34d99b..38bd34f 100644
--- a/tests/translation/src/android/translation/cts/TranslationManagerTest.java
+++ b/tests/translation/src/android/translation/cts/TranslationManagerTest.java
@@ -16,9 +16,13 @@
 
 package android.translation.cts;
 
+import static com.android.compatibility.common.util.ActivitiesWatcher.ActivityLifecycle.RESUMED;
+
 import static com.google.common.truth.Truth.assertThat;
 
+import android.app.Application;
 import android.app.Instrumentation;
+import android.app.PendingIntent;
 import android.content.pm.PackageManager;
 import android.platform.test.annotations.AppModeFull;
 import android.util.ArraySet;
@@ -34,8 +38,11 @@
 import android.view.translation.Translator;
 
 import androidx.test.InstrumentationRegistry;
+import androidx.test.core.app.ApplicationProvider;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.compatibility.common.util.ActivitiesWatcher;
+import com.android.compatibility.common.util.ActivitiesWatcher.ActivityWatcher;
 import com.android.compatibility.common.util.RequiredFeatureRule;
 import com.android.compatibility.common.util.RequiredServiceRule;
 
@@ -77,6 +84,7 @@
     private static final String TAG = "BasicTranslationTest";
 
     private CtsTranslationService.ServiceWatcher mServiceWatcher;
+    private ActivitiesWatcher mActivitiesWatcher;
 
     private static Instrumentation sInstrumentation;
     private static CtsTranslationService.TranslationReplier sTranslationReplier;
@@ -95,6 +103,10 @@
     @After
     public void cleanup() {
         Helper.resetTemporaryTranslationService();
+        if (mActivitiesWatcher != null) {
+            final Application app = (Application) ApplicationProvider.getApplicationContext();
+            app.unregisterActivityLifecycleCallbacks(mActivitiesWatcher);
+        }
     }
 
     @Test
@@ -210,6 +222,28 @@
         });
     }
 
+    @Test
+    public void testGetTranslationSettingsActivityIntent() throws Exception{
+        enableCtsTranslationService();
+
+        final TranslationManager manager = sInstrumentation.getContext().getSystemService(
+                TranslationManager.class);
+        final PendingIntent pendingIntent = manager.getTranslationSettingsActivityIntent();
+
+        assertThat(pendingIntent).isNotNull();
+        assertThat(pendingIntent.isImmutable()).isTrue();
+
+        // Start Settings Activity and verify if the expected Activity resumed
+        mActivitiesWatcher = new ActivitiesWatcher(5_000);
+        final Application app = (Application) ApplicationProvider.getApplicationContext();
+        app.registerActivityLifecycleCallbacks(mActivitiesWatcher);
+        final ActivityWatcher watcher = mActivitiesWatcher.watch(SimpleActivity.class);
+
+        pendingIntent.send();
+
+        watcher.waitFor(RESUMED);
+    }
+
     protected void enableCtsTranslationService() {
         mServiceWatcher = CtsTranslationService.setServiceWatcher();
         Helper.setTemporaryTranslationService(CtsTranslationService.SERVICE_NAME);
diff --git a/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml b/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml
index 398c221..1323093 100644
--- a/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml
+++ b/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml
@@ -56,4 +56,7 @@
     <!-- No AccessibilityService -->
     <option name="compatibility:exclude-filter" value="CtsAccessibilityServiceTestCases android.accessibilityservice.cts" />
 
+    <!-- No Statsd -->
+    <option name="compatibility:exclude-filter" value="CtsStatsdHostTestCases" />
+
 </configuration>