Merge "Change the allowed lower bound for date changes"
diff --git a/apct-tests/perftests/core/Android.bp b/apct-tests/perftests/core/Android.bp
index 2182f0b..ab20fdb 100644
--- a/apct-tests/perftests/core/Android.bp
+++ b/apct-tests/perftests/core/Android.bp
@@ -43,12 +43,14 @@
         "apct-perftests-resources-manager-apps",
         "apct-perftests-utils",
         "collector-device-lib",
+        "compatibility-device-util-axt",
+        "core-tests-support",
         "guava",
     ],
 
     libs: ["android.test.base"],
 
-    java_resources: [ ":GoogleFontDancingScript", ],
+    java_resources: [":GoogleFontDancingScript"],
 
     data: [":perfetto_artifacts"],
 
diff --git a/apct-tests/perftests/core/AndroidManifest.xml b/apct-tests/perftests/core/AndroidManifest.xml
index 56fa70c..c153201 100644
--- a/apct-tests/perftests/core/AndroidManifest.xml
+++ b/apct-tests/perftests/core/AndroidManifest.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
     package="com.android.perftests.core">
 
     <permission android:name="com.android.perftests.core.TestPermission" />
@@ -33,6 +34,17 @@
             android:exported="false"
             android:process=":some_provider" />
 
+        <!-- We remove EmojiCompat initializer here because it may crash the test process
+             if the initializer runs while TypefaceSerializationPerfTest is running. -->
+        <provider
+            android:name="androidx.startup.InitializationProvider"
+            android:authorities="${applicationId}.androidx-startup"
+            android:exported="false"
+            tools:node="merge">
+            <meta-data android:name="androidx.emoji2.text.EmojiCompatInitializer"
+                tools:node="remove" />
+        </provider>
+
         <service
             android:name="android.view.autofill.MyAutofillService"
             android:label="PERF AutofillService"
@@ -43,6 +55,16 @@
             </intent-filter>
         </service>
 
+        <service android:name="android.view.HandwritingImeService"
+                 android:label="Handwriting IME"
+                 android:permission="android.permission.BIND_INPUT_METHOD"
+                 android:exported="true">
+            <intent-filter>
+                <action android:name="android.view.InputMethod"/>
+            </intent-filter>
+            <meta-data android:name="android.view.im"
+                       android:resource="@xml/ime_meta_handwriting"/>
+        </service>
     </application>
 
     <instrumentation android:name="androidx.benchmark.junit4.AndroidBenchmarkRunner"
diff --git a/apct-tests/perftests/core/res/xml/ime_meta_handwriting.xml b/apct-tests/perftests/core/res/xml/ime_meta_handwriting.xml
new file mode 100644
index 0000000..24c0c25
--- /dev/null
+++ b/apct-tests/perftests/core/res/xml/ime_meta_handwriting.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 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.
+  -->
+
+<input-method
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:settingsActivity="com.android.inputmethod.latin.settings.SettingsActivity"
+    android:supportsStylusHandwriting="true"/>
diff --git a/apct-tests/perftests/core/src/android/graphics/perftests/TypefaceCreatePerfTest.java b/apct-tests/perftests/core/src/android/graphics/perftests/TypefaceCreatePerfTest.java
index e83c64c..9e0cf39 100644
--- a/apct-tests/perftests/core/src/android/graphics/perftests/TypefaceCreatePerfTest.java
+++ b/apct-tests/perftests/core/src/android/graphics/perftests/TypefaceCreatePerfTest.java
@@ -16,10 +16,13 @@
 
 package android.graphics.perftests;
 
+import static org.junit.Assume.assumeNotNull;
+
 import android.content.Context;
 import android.content.res.AssetManager;
 import android.content.res.Resources;
 import android.graphics.Typeface;
+import android.graphics.fonts.FontVariationAxis;
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
 
@@ -39,6 +42,8 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.List;
 
 @LargeTest
 @RunWith(AndroidJUnit4.class)
@@ -140,4 +145,18 @@
         }
     }
 
+    @Test
+    public void testCreate_fromTypefaceWithVariation() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        final List<FontVariationAxis> axes = Arrays.asList(
+                new FontVariationAxis("wght", 100f),
+                new FontVariationAxis("wdth", 0.8f));
+
+        while (state.keepRunning()) {
+            Typeface face = Typeface.createFromTypefaceWithVariation(Typeface.SANS_SERIF, axes);
+            // Make sure that the test device has variable fonts.
+            assumeNotNull(face);
+        }
+    }
+
 }
diff --git a/apct-tests/perftests/core/src/android/graphics/perftests/TypefaceSerializationPerfTest.java b/apct-tests/perftests/core/src/android/graphics/perftests/TypefaceSerializationPerfTest.java
index d272507..d3fcaa1 100644
--- a/apct-tests/perftests/core/src/android/graphics/perftests/TypefaceSerializationPerfTest.java
+++ b/apct-tests/perftests/core/src/android/graphics/perftests/TypefaceSerializationPerfTest.java
@@ -17,10 +17,13 @@
 package android.graphics.perftests;
 
 import android.graphics.Typeface;
+import android.os.Debug;
 import android.os.SharedMemory;
-import android.perftests.utils.BenchmarkState;
-import android.perftests.utils.PerfStatusReporter;
+import android.os.SystemClock;
+import android.perftests.utils.ManualBenchmarkState;
+import android.perftests.utils.PerfManualStatusReporter;
 import android.util.ArrayMap;
+import android.util.Log;
 
 import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -37,39 +40,108 @@
 @RunWith(AndroidJUnit4.class)
 public class TypefaceSerializationPerfTest {
 
-    @Rule
-    public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    private static final String TAG = "TypefaceSerializationPerfTest";
 
+    // Those values were taken from android.perftests.utils.BenchmarkState.
+    // Note: we cannot use TimeUnit.toNanos() because these constants are used in annotation.
+    private static final long WARMUP_DURATION_NS = 250_000_000; // 250ms
+    private static final long TARGET_TEST_DURATION_NS = 500_000_000; // 500ms
+
+    @Rule
+    public PerfManualStatusReporter mPerfManualStatusReporter = new PerfManualStatusReporter();
+
+    @ManualBenchmarkState.ManualBenchmarkTest(
+            warmupDurationNs = WARMUP_DURATION_NS,
+            targetTestDurationNs = TARGET_TEST_DURATION_NS)
     @Test
     public void testSerializeFontMap() throws Exception {
         Map<String, Typeface> systemFontMap = Typeface.getSystemFontMap();
-        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        ManualBenchmarkState state = mPerfManualStatusReporter.getBenchmarkState();
 
-        while (state.keepRunning()) {
+        long elapsedTime = 0;
+        while (state.keepRunning(elapsedTime)) {
+            long startTime = System.nanoTime();
             Typeface.serializeFontMap(systemFontMap);
+            elapsedTime = System.nanoTime() - startTime;
         }
     }
 
+    @ManualBenchmarkState.ManualBenchmarkTest(
+            warmupDurationNs = WARMUP_DURATION_NS,
+            targetTestDurationNs = TARGET_TEST_DURATION_NS)
+    @Test
+    public void testSerializeFontMap_memory() throws Exception {
+        Map<String, Typeface> systemFontMap = Typeface.getSystemFontMap();
+        SharedMemory memory = Typeface.serializeFontMap(systemFontMap);
+        ManualBenchmarkState state = mPerfManualStatusReporter.getBenchmarkState();
+
+        while (state.keepRunning(memory.getSize())) {
+            // Rate-limiting
+            SystemClock.sleep(100);
+        }
+    }
+
+    @ManualBenchmarkState.ManualBenchmarkTest(
+            warmupDurationNs = WARMUP_DURATION_NS,
+            targetTestDurationNs = TARGET_TEST_DURATION_NS)
     @Test
     public void testDeserializeFontMap() throws Exception {
         SharedMemory memory = Typeface.serializeFontMap(Typeface.getSystemFontMap());
         ByteBuffer buffer = memory.mapReadOnly().order(ByteOrder.BIG_ENDIAN);
-        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        ManualBenchmarkState state = mPerfManualStatusReporter.getBenchmarkState();
 
         ArrayMap<String, Typeface> out = new ArrayMap<>();
-        while (state.keepRunning()) {
+        long elapsedTime = 0;
+        while (state.keepRunning(elapsedTime)) {
+            long startTime = System.nanoTime();
             buffer.position(0);
             Typeface.deserializeFontMap(buffer, out);
+            elapsedTime = System.nanoTime() - startTime;
         }
     }
 
+    @ManualBenchmarkState.ManualBenchmarkTest(
+            warmupDurationNs = WARMUP_DURATION_NS,
+            targetTestDurationNs = TARGET_TEST_DURATION_NS)
+    @Test
+    public void testDeserializeFontMap_memory() throws Exception {
+        SharedMemory memory = Typeface.serializeFontMap(Typeface.getSystemFontMap());
+        ByteBuffer buffer = memory.mapReadOnly().order(ByteOrder.BIG_ENDIAN);
+        ManualBenchmarkState state = mPerfManualStatusReporter.getBenchmarkState();
+
+        ArrayMap<String, Typeface> out = new ArrayMap<>();
+        // Diff of native heap allocation size (in bytes) before and after deserializeFontMap.
+        // Note: we don't measure memory usage of setSystemFontMap because setSystemFontMap sets
+        // some global variables, and it's hard to clear them.
+        long heapDiff = 0;
+        // Sometimes heapDiff may become negative due to GC.
+        // Use 0 in that case to avoid crashing in keepRunning.
+        while (state.keepRunning(Math.max(0, heapDiff))) {
+            buffer.position(0);
+            long baselineSize = Debug.getNativeHeapAllocatedSize();
+            Typeface.deserializeFontMap(buffer, out);
+            long currentSize = Debug.getNativeHeapAllocatedSize();
+            heapDiff = currentSize - baselineSize;
+            Log.i(TAG, String.format("native heap alloc: current = %d, baseline = %d, diff = %d",
+                    currentSize, baselineSize, heapDiff));
+            // Release native objects here to minimize the impact of GC.
+            for (Typeface typeface : out.values()) {
+                typeface.releaseNativeObjectForTest();
+            }
+            out.clear();
+        }
+    }
+
+    @ManualBenchmarkState.ManualBenchmarkTest(
+            warmupDurationNs = WARMUP_DURATION_NS,
+            targetTestDurationNs = TARGET_TEST_DURATION_NS)
     @Test
     public void testSetSystemFontMap() throws Exception {
         SharedMemory memory = null;
-        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        ManualBenchmarkState state = mPerfManualStatusReporter.getBenchmarkState();
 
-        while (state.keepRunning()) {
-            state.pauseTiming();
+        long elapsedTime = 0;
+        while (state.keepRunning(elapsedTime)) {
             // Explicitly destroy lazy-loaded typefaces, so that we don't hit the mmap limit
             // (max_map_count).
             Typeface.destroySystemFontMap();
@@ -78,8 +150,9 @@
                 memory.close();
             }
             memory = Typeface.serializeFontMap(Typeface.getSystemFontMap());
-            state.resumeTiming();
+            long startTime = System.nanoTime();
             Typeface.setSystemFontMap(memory);
+            elapsedTime = System.nanoTime() - startTime;
         }
     }
 }
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CharsetUtf8PerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CharsetUtf8PerfTest.java
index f31e9c1..b753006 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/CharsetUtf8PerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/CharsetUtf8PerfTest.java
@@ -37,9 +37,7 @@
 public class CharsetUtf8PerfTest {
     @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
 
-    private final int mNoOfBytes = 0x100; // 4MB
-
-    private void makeUnicodeRange(int startingCodePoint, int endingCodePoint, int repeated) {
+    private void makeUnicodeRange(int startingCodePoint, int endingCodePoint) {
         StringBuilder builder = new StringBuilder();
         for (int codePoint = startingCodePoint; codePoint <= endingCodePoint; codePoint++) {
             if (codePoint < Character.MIN_SURROGATE || codePoint > Character.MAX_SURROGATE) {
@@ -48,35 +46,30 @@
         }
 
         String str = builder.toString();
-        StringBuilder builder2 = new StringBuilder();
         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
         while (state.keepRunning()) {
-            for (int i = 0; i < repeated; i++) {
-                builder2.append(str);
-            }
+            StringBuilder builder2 = new StringBuilder();
+            builder2.append(str);
         }
     }
 
     @Test
     public void time_ascii() {
-        makeUnicodeRange(0, 0x7f, mNoOfBytes / 0x80);
+        makeUnicodeRange(0, 0x7f);
     }
 
     @Test
     public void time_bmp2() {
-        makeUnicodeRange(0x0080, 0x07ff, mNoOfBytes / 2 / 0x780);
+        makeUnicodeRange(0x0080, 0x07ff);
     }
 
     @Test
     public void time_bmp3() {
-        makeUnicodeRange(
-                0x0800,
-                0xffff,
-                mNoOfBytes / 3 / 0xf000 /* 0x10000 - 0x0800 - no of surrogate code points */);
+        makeUnicodeRange(0x0800, 0xffff);
     }
 
     @Test
     public void time_supplementary() {
-        makeUnicodeRange(0x10000, 0x10ffff, mNoOfBytes / 4 / 0x100000);
+        makeUnicodeRange(0x10000, 0x10ffff);
     }
 }
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java
index 03c9d43..adcd571 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java
@@ -158,14 +158,6 @@
     }
 
     @Test
-    public void timeNewSimpleDateFormat() {
-        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
-        while (state.keepRunning()) {
-            new SimpleDateFormat();
-        }
-    }
-
-    @Test
     public void timeClonedSimpleDateFormat() {
         SimpleDateFormat sdf = new SimpleDateFormat();
         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SSLLoopbackPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SSLLoopbackPerfTest.java
new file mode 100644
index 0000000..694d609
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/SSLLoopbackPerfTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 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.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import libcore.java.security.TestKeyStore;
+import libcore.javax.net.ssl.TestSSLContext;
+import libcore.javax.net.ssl.TestSSLSocketPair;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.net.ssl.SSLSocket;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class SSLLoopbackPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void time() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            TestSSLContext context =
+                    TestSSLContext.create(TestKeyStore.getClient(), TestKeyStore.getServer());
+            SSLSocket[] sockets = TestSSLSocketPair.connect(context, null, null);
+            context.close();
+            sockets[0].close();
+            sockets[1].close();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SSLSocketFactoryPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SSLSocketFactoryPerfTest.java
new file mode 100644
index 0000000..bdbbcb0
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/SSLSocketFactoryPerfTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 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.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.net.ssl.SSLSocketFactory;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class SSLSocketFactoryPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void time() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            SSLSocketFactory.getDefault();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SchemePrefixPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SchemePrefixPerfTest.java
new file mode 100644
index 0000000..42dc581
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/SchemePrefixPerfTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2022 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.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public final class SchemePrefixPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    enum Strategy {
+        JAVA() {
+            @Override
+            String execute(String spec) {
+                int colon = spec.indexOf(':');
+
+                if (colon < 1) {
+                    return null;
+                }
+
+                for (int i = 0; i < colon; i++) {
+                    char c = spec.charAt(i);
+                    if (!isValidSchemeChar(i, c)) {
+                        return null;
+                    }
+                }
+
+                return spec.substring(0, colon).toLowerCase(Locale.US);
+            }
+
+            private boolean isValidSchemeChar(int index, char c) {
+                if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
+                    return true;
+                }
+                if (index > 0 && ((c >= '0' && c <= '9') || c == '+' || c == '-' || c == '.')) {
+                    return true;
+                }
+                return false;
+            }
+        },
+
+        REGEX() {
+            private final Pattern mPattern = Pattern.compile("^([a-zA-Z][a-zA-Z0-9+\\-.]*):");
+
+            @Override
+            String execute(String spec) {
+                Matcher matcher = mPattern.matcher(spec);
+                if (matcher.find()) {
+                    return matcher.group(1).toLowerCase(Locale.US);
+                } else {
+                    return null;
+                }
+            }
+        };
+
+        abstract String execute(String spec);
+    }
+
+    @Parameters(name = "mStrategy={0}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] {{Strategy.REGEX}, {Strategy.JAVA}});
+    }
+
+    @Parameterized.Parameter(0)
+    public Strategy mStrategy;
+
+    @Test
+    public void timeSchemePrefix() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mStrategy.execute("http://android.com");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SerializationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SerializationPerfTest.java
new file mode 100644
index 0000000..1ec22d2
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/SerializationPerfTest.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2022 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.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.Serializable;
+import java.util.ArrayList;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class SerializationPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private static byte[] bytes(Object o) throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+        ObjectOutputStream out = new ObjectOutputStream(baos);
+        out.writeObject(o);
+        out.close();
+        return baos.toByteArray();
+    }
+
+    @Test
+    public void timeReadIntArray() throws Exception {
+        int[] intArray = new int[256];
+        readSingleObject(intArray);
+    }
+
+    @Test
+    public void timeWriteIntArray() throws Exception {
+        int[] intArray = new int[256];
+        writeSingleObject(intArray);
+    }
+
+    @Test
+    public void timeReadArrayListInteger() throws Exception {
+        ArrayList<Integer> object = new ArrayList<Integer>();
+        for (int i = 0; i < 256; ++i) {
+            object.add(i);
+        }
+        readSingleObject(object);
+    }
+
+    @Test
+    public void timeWriteArrayListInteger() throws Exception {
+        ArrayList<Integer> object = new ArrayList<Integer>();
+        for (int i = 0; i < 256; ++i) {
+            object.add(i);
+        }
+        writeSingleObject(object);
+    }
+
+    @Test
+    public void timeReadString() throws Exception {
+        readSingleObject("hello");
+    }
+
+    @Test
+    public void timeReadObjectStreamClass() throws Exception {
+        // A special case because serialization itself requires this class.
+        // (This should really be a unit test.)
+        ObjectStreamClass osc = ObjectStreamClass.lookup(String.class);
+        readSingleObject(osc);
+    }
+
+    @Test
+    public void timeWriteString() throws Exception {
+        // String is a special case that avoids JNI.
+        writeSingleObject("hello");
+    }
+
+    @Test
+    public void timeWriteObjectStreamClass() throws Exception {
+        // A special case because serialization itself requires this class.
+        // (This should really be a unit test.)
+        ObjectStreamClass osc = ObjectStreamClass.lookup(String.class);
+        writeSingleObject(osc);
+    }
+
+    // This is
+    //
+    // @Testa baseline for the others.
+    public void timeWriteNoObjects() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+        ObjectOutputStream out = new ObjectOutputStream(baos);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            out.reset();
+            baos.reset();
+        }
+        out.close();
+    }
+
+    private void readSingleObject(Object object) throws Exception {
+        byte[] bytes = bytes(object);
+        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            ObjectInputStream in = new ObjectInputStream(bais);
+            in.readObject();
+            in.close();
+            bais.reset();
+        }
+    }
+
+    private void writeSingleObject(Object o) throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+        ObjectOutputStream out = new ObjectOutputStream(baos);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            out.writeObject(o);
+            out.reset();
+            baos.reset();
+        }
+        out.close();
+    }
+
+    @Test
+    public void timeWriteEveryKindOfField() throws Exception {
+        writeSingleObject(new LittleBitOfEverything());
+    }
+
+    @Test
+    public void timeWriteSerializableBoolean() throws Exception {
+        writeSingleObject(new SerializableBoolean());
+    }
+
+    @Test
+    public void timeWriteSerializableByte() throws Exception {
+        writeSingleObject(new SerializableByte());
+    }
+
+    @Test
+    public void timeWriteSerializableChar() throws Exception {
+        writeSingleObject(new SerializableChar());
+    }
+
+    @Test
+    public void timeWriteSerializableDouble() throws Exception {
+        writeSingleObject(new SerializableDouble());
+    }
+
+    @Test
+    public void timeWriteSerializableFloat() throws Exception {
+        writeSingleObject(new SerializableFloat());
+    }
+
+    @Test
+    public void timeWriteSerializableInt() throws Exception {
+        writeSingleObject(new SerializableInt());
+    }
+
+    @Test
+    public void timeWriteSerializableLong() throws Exception {
+        writeSingleObject(new SerializableLong());
+    }
+
+    @Test
+    public void timeWriteSerializableShort() throws Exception {
+        writeSingleObject(new SerializableShort());
+    }
+
+    @Test
+    public void timeWriteSerializableReference() throws Exception {
+        writeSingleObject(new SerializableReference());
+    }
+
+    @Test
+    public void timeReadEveryKindOfField() throws Exception {
+        readSingleObject(new LittleBitOfEverything());
+    }
+
+    @Test
+    public void timeReadSerializableBoolean() throws Exception {
+        readSingleObject(new SerializableBoolean());
+    }
+
+    @Test
+    public void timeReadSerializableByte() throws Exception {
+        readSingleObject(new SerializableByte());
+    }
+
+    @Test
+    public void timeReadSerializableChar() throws Exception {
+        readSingleObject(new SerializableChar());
+    }
+
+    @Test
+    public void timeReadSerializableDouble() throws Exception {
+        readSingleObject(new SerializableDouble());
+    }
+
+    @Test
+    public void timeReadSerializableFloat() throws Exception {
+        readSingleObject(new SerializableFloat());
+    }
+
+    @Test
+    public void timeReadSerializableInt() throws Exception {
+        readSingleObject(new SerializableInt());
+    }
+
+    @Test
+    public void timeReadSerializableLong() throws Exception {
+        readSingleObject(new SerializableLong());
+    }
+
+    @Test
+    public void timeReadSerializableShort() throws Exception {
+        readSingleObject(new SerializableShort());
+    }
+
+    @Test
+    public void timeReadSerializableReference() throws Exception {
+        readSingleObject(new SerializableReference());
+    }
+
+    public static class SerializableBoolean implements Serializable {
+        boolean mZ;
+    }
+
+    public static class SerializableByte implements Serializable {
+        byte mB;
+    }
+
+    public static class SerializableChar implements Serializable {
+        char mC;
+    }
+
+    public static class SerializableDouble implements Serializable {
+        double mD;
+    }
+
+    public static class SerializableFloat implements Serializable {
+        float mF;
+    }
+
+    public static class SerializableInt implements Serializable {
+        int mI;
+    }
+
+    public static class SerializableLong implements Serializable {
+        long mJ;
+    }
+
+    public static class SerializableShort implements Serializable {
+        short mS;
+    }
+
+    public static class SerializableReference implements Serializable {
+        Object mL;
+    }
+
+    public static class LittleBitOfEverything implements Serializable {
+        boolean mZ;
+        byte mB;
+        char mC;
+        double mD;
+        float mF;
+        int mI;
+        long mJ;
+        short mS;
+        Object mL;
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SignaturePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SignaturePerfTest.java
new file mode 100644
index 0000000..96e7cb2
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/SignaturePerfTest.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2022 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.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/** Tests RSA and DSA mSignature creation and verification. */
+@RunWith(Parameterized.class)
+@LargeTest
+public class SignaturePerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Parameters(name = "mAlgorithm={0}, mImplementation={1}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(
+                new Object[][] {
+                    {Algorithm.MD5WithRSA, Implementation.OpenSSL},
+                    {Algorithm.SHA1WithRSA, Implementation.OpenSSL},
+                    {Algorithm.SHA256WithRSA, Implementation.OpenSSL},
+                    {Algorithm.SHA384WithRSA, Implementation.OpenSSL},
+                    {Algorithm.SHA512WithRSA, Implementation.OpenSSL},
+                    {Algorithm.SHA1withDSA, Implementation.BouncyCastle}
+                });
+    }
+
+    @Parameterized.Parameter(0)
+    public Algorithm mAlgorithm;
+
+    @Parameterized.Parameter(1)
+    public Implementation mImplementation;
+
+    private static final int DATA_SIZE = 8192;
+    private static final byte[] DATA = new byte[DATA_SIZE];
+
+    static {
+        for (int i = 0; i < DATA_SIZE; i++) {
+            DATA[i] = (byte) i;
+        }
+    }
+
+    public enum Algorithm {
+        MD5WithRSA,
+        SHA1WithRSA,
+        SHA256WithRSA,
+        SHA384WithRSA,
+        SHA512WithRSA,
+        SHA1withDSA
+    };
+
+    public enum Implementation {
+        OpenSSL,
+        BouncyCastle
+    };
+
+    // Key generation and signing aren't part of the benchmark for verification
+    // so cache the results
+    private static Map<String, KeyPair> sKeyPairs = new HashMap<String, KeyPair>();
+    private static Map<String, byte[]> sSignatures = new HashMap<String, byte[]>();
+
+    private String mSignatureAlgorithm;
+    private byte[] mSignature;
+    private PrivateKey mPrivateKey;
+    private PublicKey mPublicKey;
+
+    @Before
+    public void setUp() throws Exception {
+        this.mSignatureAlgorithm = mAlgorithm.toString();
+
+        String keyAlgorithm =
+                mSignatureAlgorithm.substring(
+                        mSignatureAlgorithm.length() - 3, mSignatureAlgorithm.length());
+        KeyPair keyPair = sKeyPairs.get(keyAlgorithm);
+        if (keyPair == null) {
+            KeyPairGenerator generator = KeyPairGenerator.getInstance(keyAlgorithm);
+            keyPair = generator.generateKeyPair();
+            sKeyPairs.put(keyAlgorithm, keyPair);
+        }
+        this.mPrivateKey = keyPair.getPrivate();
+        this.mPublicKey = keyPair.getPublic();
+
+        this.mSignature = sSignatures.get(mSignatureAlgorithm);
+        if (this.mSignature == null) {
+            Signature signer = Signature.getInstance(mSignatureAlgorithm);
+            signer.initSign(keyPair.getPrivate());
+            signer.update(DATA);
+            this.mSignature = signer.sign();
+            sSignatures.put(mSignatureAlgorithm, mSignature);
+        }
+    }
+
+    @Test
+    public void timeSign() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Signature signer;
+            switch (mImplementation) {
+                case OpenSSL:
+                    signer = Signature.getInstance(mSignatureAlgorithm, "AndroidOpenSSL");
+                    break;
+                case BouncyCastle:
+                    signer = Signature.getInstance(mSignatureAlgorithm, "BC");
+                    break;
+                default:
+                    throw new RuntimeException(mImplementation.toString());
+            }
+            signer.initSign(mPrivateKey);
+            signer.update(DATA);
+            signer.sign();
+        }
+    }
+
+    @Test
+    public void timeVerify() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Signature verifier;
+            switch (mImplementation) {
+                case OpenSSL:
+                    verifier = Signature.getInstance(mSignatureAlgorithm, "AndroidOpenSSL");
+                    break;
+                case BouncyCastle:
+                    verifier = Signature.getInstance(mSignatureAlgorithm, "BC");
+                    break;
+                default:
+                    throw new RuntimeException(mImplementation.toString());
+            }
+            verifier.initVerify(mPublicKey);
+            verifier.update(DATA);
+            verifier.verify(mSignature);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SimpleDateFormatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SimpleDateFormatPerfTest.java
new file mode 100644
index 0000000..c25b0ce
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/SimpleDateFormatPerfTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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 android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Benchmark for java.text.SimpleDateFormat. This tests common formatting, parsing and creation
+ * operations with a specific focus on TimeZone handling.
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class SimpleDateFormatPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void time_createFormatWithTimeZone() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd z");
+        }
+    }
+
+    @Test
+    public void time_parseWithTimeZoneShort() throws ParseException {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd z");
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            sdf.parse("2000.01.01 PST");
+        }
+    }
+
+    @Test
+    public void time_parseWithTimeZoneLong() throws ParseException {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd zzzz");
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            sdf.parse("2000.01.01 Pacific Standard Time");
+        }
+    }
+
+    @Test
+    public void time_parseWithoutTimeZone() throws ParseException {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            sdf.parse("2000.01.01");
+        }
+    }
+
+    @Test
+    public void time_createAndParseWithTimeZoneShort() throws ParseException {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd z");
+            sdf.parse("2000.01.01 PST");
+        }
+    }
+
+    @Test
+    public void time_createAndParseWithTimeZoneLong() throws ParseException {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd zzzz");
+            sdf.parse("2000.01.01 Pacific Standard Time");
+        }
+    }
+
+    @Test
+    public void time_formatWithTimeZoneShort() {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd z");
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            sdf.format(new Date());
+        }
+    }
+
+    @Test
+    public void time_formatWithTimeZoneLong() {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd zzzz");
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            sdf.format(new Date());
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StrictMathPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StrictMathPerfTest.java
new file mode 100644
index 0000000..eeccb5b
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StrictMathPerfTest.java
@@ -0,0 +1,510 @@
+/*
+ * Copyright (C) 2022 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.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Many of these tests are bogus in that the cost will vary wildly depending on inputs. For _my_
+ * current purposes, that's okay. But beware!
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class StrictMathPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private final double mDouble = 1.2;
+    private final float mFloat = 1.2f;
+    private final int mInt = 1;
+    private final long mLong = 1L;
+
+    /* Values for full line coverage of ceiling function */
+    private static final double[] CEIL_DOUBLES =
+            new double[] {
+                3245817.2018463886,
+                1418139.083668501,
+                3.572936802189103E15,
+                -4.7828929737254625E249,
+                213596.58636369856,
+                6.891928421440976E-96,
+                -7.9318566885477E-36,
+                -1.9610339084804148E15,
+                -4.696725715628246E10,
+                3742491.296880909,
+                7.140274745333553E11
+            };
+
+    /* Values for full line coverage of floor function */
+    private static final double[] FLOOR_DOUBLES =
+            new double[] {
+                7.140274745333553E11,
+                3742491.296880909,
+                -4.696725715628246E10,
+                -1.9610339084804148E15,
+                7.049948629370372E-56,
+                -7.702933170334643E-16,
+                -1.99657681810579,
+                -1.1659287182288336E236,
+                4.085518816513057E15,
+                -1500948.440658056,
+                -2.2316479921415575E7
+            };
+
+    @Test
+    public void timeAbsD() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.abs(mDouble);
+        }
+    }
+
+    @Test
+    public void timeAbsF() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.abs(mFloat);
+        }
+    }
+
+    @Test
+    public void timeAbsI() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.abs(mInt);
+        }
+    }
+
+    @Test
+    public void timeAbsL() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.abs(mLong);
+        }
+    }
+
+    @Test
+    public void timeAcos() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.acos(mDouble);
+        }
+    }
+
+    @Test
+    public void timeAsin() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.asin(mDouble);
+        }
+    }
+
+    @Test
+    public void timeAtan() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.atan(mDouble);
+        }
+    }
+
+    @Test
+    public void timeAtan2() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.atan2(3, 4);
+        }
+    }
+
+    @Test
+    public void timeCbrt() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.cbrt(mDouble);
+        }
+    }
+
+    @Test
+    public void timeCeilOverInterestingValues() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < CEIL_DOUBLES.length; ++i) {
+                StrictMath.ceil(CEIL_DOUBLES[i]);
+            }
+        }
+    }
+
+    @Test
+    public void timeCopySignD() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.copySign(mDouble, mDouble);
+        }
+    }
+
+    @Test
+    public void timeCopySignF() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.copySign(mFloat, mFloat);
+        }
+    }
+
+    @Test
+    public void timeCos() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.cos(mDouble);
+        }
+    }
+
+    @Test
+    public void timeCosh() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.cosh(mDouble);
+        }
+    }
+
+    @Test
+    public void timeExp() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.exp(mDouble);
+        }
+    }
+
+    @Test
+    public void timeExpm1() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.expm1(mDouble);
+        }
+    }
+
+    @Test
+    public void timeFloorOverInterestingValues() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < FLOOR_DOUBLES.length; ++i) {
+                StrictMath.floor(FLOOR_DOUBLES[i]);
+            }
+        }
+    }
+
+    @Test
+    public void timeGetExponentD() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.getExponent(mDouble);
+        }
+    }
+
+    @Test
+    public void timeGetExponentF() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.getExponent(mFloat);
+        }
+    }
+
+    @Test
+    public void timeHypot() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.hypot(mDouble, mDouble);
+        }
+    }
+
+    @Test
+    public void timeIEEEremainder() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.IEEEremainder(mDouble, mDouble);
+        }
+    }
+
+    @Test
+    public void timeLog() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.log(mDouble);
+        }
+    }
+
+    @Test
+    public void timeLog10() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.log10(mDouble);
+        }
+    }
+
+    @Test
+    public void timeLog1p() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.log1p(mDouble);
+        }
+    }
+
+    @Test
+    public void timeMaxD() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.max(mDouble, mDouble);
+        }
+    }
+
+    @Test
+    public void timeMaxF() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.max(mFloat, mFloat);
+        }
+    }
+
+    @Test
+    public void timeMaxI() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.max(mInt, mInt);
+        }
+    }
+
+    @Test
+    public void timeMaxL() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.max(mLong, mLong);
+        }
+    }
+
+    @Test
+    public void timeMinD() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.min(mDouble, mDouble);
+        }
+    }
+
+    @Test
+    public void timeMinF() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.min(mFloat, mFloat);
+        }
+    }
+
+    @Test
+    public void timeMinI() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.min(mInt, mInt);
+        }
+    }
+
+    @Test
+    public void timeMinL() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.min(mLong, mLong);
+        }
+    }
+
+    @Test
+    public void timeNextAfterD() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.nextAfter(mDouble, mDouble);
+        }
+    }
+
+    @Test
+    public void timeNextAfterF() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.nextAfter(mFloat, mFloat);
+        }
+    }
+
+    @Test
+    public void timeNextUpD() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.nextUp(mDouble);
+        }
+    }
+
+    @Test
+    public void timeNextUpF() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.nextUp(mFloat);
+        }
+    }
+
+    @Test
+    public void timePow() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.pow(mDouble, mDouble);
+        }
+    }
+
+    @Test
+    public void timeRandom() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.random();
+        }
+    }
+
+    @Test
+    public void timeRint() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.rint(mDouble);
+        }
+    }
+
+    @Test
+    public void timeRoundD() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.round(mDouble);
+        }
+    }
+
+    @Test
+    public void timeRoundF() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.round(mFloat);
+        }
+    }
+
+    @Test
+    public void timeScalbD() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.scalb(mDouble, 5);
+        }
+    }
+
+    @Test
+    public void timeScalbF() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.scalb(mFloat, 5);
+        }
+    }
+
+    @Test
+    public void timeSignumD() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.signum(mDouble);
+        }
+    }
+
+    @Test
+    public void timeSignumF() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.signum(mFloat);
+        }
+    }
+
+    @Test
+    public void timeSin() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.sin(mDouble);
+        }
+    }
+
+    @Test
+    public void timeSinh() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.sinh(mDouble);
+        }
+    }
+
+    @Test
+    public void timeSqrt() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.sqrt(mDouble);
+        }
+    }
+
+    @Test
+    public void timeTan() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.tan(mDouble);
+        }
+    }
+
+    @Test
+    public void timeTanh() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.tanh(mDouble);
+        }
+    }
+
+    @Test
+    public void timeToDegrees() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.toDegrees(mDouble);
+        }
+    }
+
+    @Test
+    public void timeToRadians() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.toRadians(mDouble);
+        }
+    }
+
+    @Test
+    public void timeUlpD() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.ulp(mDouble);
+        }
+    }
+
+    @Test
+    public void timeUlpF() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StrictMath.ulp(mFloat);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringBuilderPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringBuilderPerfTest.java
new file mode 100644
index 0000000..34fb88b
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringBuilderPerfTest.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2022 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.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+/** Tests the performance of various StringBuilder methods. */
+@RunWith(Parameterized.class)
+@LargeTest
+public class StringBuilderPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Parameters(name = "mLength={0}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] {{1}, {10}, {100}});
+    }
+
+    @Parameterized.Parameter(0)
+    public int mLength;
+
+    @Test
+    public void timeAppendBoolean() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StringBuilder sb = new StringBuilder();
+            for (int j = 0; j < mLength; ++j) {
+                sb.append(true);
+            }
+        }
+    }
+
+    @Test
+    public void timeAppendChar() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StringBuilder sb = new StringBuilder();
+            for (int j = 0; j < mLength; ++j) {
+                sb.append('c');
+            }
+        }
+    }
+
+    @Test
+    public void timeAppendCharArray() {
+        char[] chars = "chars".toCharArray();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StringBuilder sb = new StringBuilder();
+            for (int j = 0; j < mLength; ++j) {
+                sb.append(chars);
+            }
+        }
+    }
+
+    @Test
+    public void timeAppendCharSequence() {
+        CharSequence cs = "chars";
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StringBuilder sb = new StringBuilder();
+            for (int j = 0; j < mLength; ++j) {
+                sb.append(cs);
+            }
+        }
+    }
+
+    @Test
+    public void timeAppendSubCharSequence() {
+        CharSequence cs = "chars";
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StringBuilder sb = new StringBuilder();
+            for (int j = 0; j < mLength; ++j) {
+                sb.append(cs);
+            }
+        }
+    }
+
+    @Test
+    public void timeAppendDouble() {
+        double d = 1.2;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StringBuilder sb = new StringBuilder();
+            for (int j = 0; j < mLength; ++j) {
+                sb.append(d);
+            }
+        }
+    }
+
+    @Test
+    public void timeAppendFloat() {
+        float f = 1.2f;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StringBuilder sb = new StringBuilder();
+            for (int j = 0; j < mLength; ++j) {
+                sb.append(f);
+            }
+        }
+    }
+
+    @Test
+    public void timeAppendInt() {
+        int n = 123;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StringBuilder sb = new StringBuilder();
+            for (int j = 0; j < mLength; ++j) {
+                sb.append(n);
+            }
+        }
+    }
+
+    @Test
+    public void timeAppendLong() {
+        long l = 123;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StringBuilder sb = new StringBuilder();
+            for (int j = 0; j < mLength; ++j) {
+                sb.append(l);
+            }
+        }
+    }
+
+    @Test
+    public void timeAppendObject() {
+        // We don't want to time the toString, so ensure we're calling a trivial one...
+        Object o =
+                new Object() {
+                    @Override
+                    public String toString() {
+                        return "constant";
+                    }
+                };
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StringBuilder sb = new StringBuilder();
+            for (int j = 0; j < mLength; ++j) {
+                sb.append(o);
+            }
+        }
+    }
+
+    @Test
+    public void timeAppendString() {
+        String s = "chars";
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StringBuilder sb = new StringBuilder();
+            for (int j = 0; j < mLength; ++j) {
+                sb.append(s);
+            }
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringEqualsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringEqualsPerfTest.java
new file mode 100644
index 0000000..6854c0d
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringEqualsPerfTest.java
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2022 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.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import junit.framework.Assert;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Benchmarks to measure the performance of String.equals for Strings of varying lengths. Each
+ * benchmarks makes 5 measurements, aiming at covering cases like strings of equal length that are
+ * not equal, identical strings with different references, strings with different endings, interned
+ * strings, and strings of different lengths.
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class StringEqualsPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private final String mLong1 =
+            "Ahead-of-time compilation is possible as the compiler may just convert an instruction"
+                + " thus: dex code: add-int v1000, v2000, v3000 C code: setIntRegter(1000,"
+                + " call_dex_add_int(getIntRegister(2000), getIntRegister(3000)) This means even"
+                + " lidinstructions may have code generated, however, it is not expected that code"
+                + " generate inthis way will perform well. The job of AOT verification is to tell"
+                + " the compiler thatinstructions are sound and provide tests to detect unsound"
+                + " sequences so slow path codemay be generated. Other than for totally invalid"
+                + " code, the verification may fail at AOrrun-time. At AOT time it can be because"
+                + " of incomplete information, at run-time it can ethat code in a different apk"
+                + " that the application depends upon has changed. The Dalvikverifier would return"
+                + " a bool to state whether a Class were good or bad. In ART the fail case becomes"
+                + " either a soft or hard failure. Classes have new states to represent that a soft"
+                + " failure occurred at compile time and should be re-verified at run-time.";
+
+    private final String mVeryLong =
+            "Garbage collection has two phases. The first distinguishes live objects from garbage"
+                + " objects.  The second is reclaiming the rage of garbage objectIn the mark-sweep"
+                + " algorithm used by Dalvik, the first phase is achievd by computing the closure"
+                + " of all reachable objects in a process known as tracing from theoots.  After"
+                + " thetrace has completed, garbage objects are reclaimed.  Each of these"
+                + " operations can beparallelized and can be interleaved with the operation of the"
+                + " applicationTraditionally,the tracing phase dominates the time spent in garbage"
+                + " collection.  The greatreduction ipause time can be achieved by interleaving as"
+                + " much of this phase as possible with theapplication. If we simply ran the GC in"
+                + " a separate thread with no other changes, normaloperation of an application"
+                + " would confound the trace.  Abstractly, the GC walks the h oall reachable"
+                + " objects.  When the application is paused, the object graph cannot change.The GC"
+                + " can therefore walk this structure and assume that all reachable objects"
+                + " live.When the application is running, this graph may be altered. New nodes may"
+                + " be addnd edgemay be changed.  These changes may cause live objects to be hidden"
+                + " and falsely recla bythe GC.  To avoid this problem a write barrier is used to"
+                + " intercept and record modifionto objects in a separate structure.  After"
+                + " performing its walk, the GC will revisit theupdated objects and re-validate its"
+                + " assumptions.  Without a card table, the garbagecollector would have to visit"
+                + " all objects reached during the trace looking for dirtied objects.  The cost of"
+                + " this operation would be proportional to the amount of live data.With a card"
+                + " table, the cost of this operation is proportional to the amount of updateatThe"
+                + " write barrier in Dalvik is a card marking write barrier.  Card marking is the"
+                + " proceof noting the location of object connectivity changes on a sub-page"
+                + " granularity.  A caris merely a colorful term for a contiguous extent of memory"
+                + " smaller than a page, commonsomewhere between 128- and 512-bytes.  Card marking"
+                + " is implemented by instrumenting alllocations in the virtual machine which can"
+                + " assign a pointer to an object.  After themalpointer assignment has occurred, a"
+                + " byte is written to a byte-map spanning the heap whiccorresponds to the location"
+                + " of the updated object.  This byte map is known as a card taThe garbage"
+                + " collector visits this card table and looks for written bytes to reckon"
+                + " thelocation of updated objects.  It then rescans all objects located on the"
+                + " dirty card,correcting liveness assumptions that were invalidated by the"
+                + " application.  While cardmarking imposes a small burden on the application"
+                + " outside of a garbage collection, theoverhead of maintaining the card table is"
+                + " paid for by the reduced time spent insidegarbage collection. With the"
+                + " concurrent garbage collection thread and a write barriersupported by the"
+                + " interpreter, JIT, and Runtime we modify garbage collection";
+
+    private final String[][] mShortStrings =
+            new String[][] {
+                // Equal, constant comparison
+                {"a", "a"},
+                // Different constants, first character different
+                {":", " :"},
+                // Different constants, last character different, same length
+                {"ja M", "ja N"},
+                // Different constants, different lengths
+                {"$$$", "$$"},
+                // Force execution of code beyond reference equality check
+                {"hi", new String("hi")}
+            };
+
+    private final String[][] mMediumStrings =
+            new String[][] {
+                // Equal, constant comparison
+                {"Hello my name is ", "Hello my name is "},
+                // Different constants, different lengths
+                {"What's your name?", "Whats your name?"},
+                // Force execution of code beyond reference equality check
+                {"Android Runtime", new String("Android Runtime")},
+                // Different constants, last character different, same length
+                {"v3ry Cre@tiVe?****", "v3ry Cre@tiVe?***."},
+                // Different constants, first character different, same length
+                {"!@#$%^&*()_++*^$#@", "0@#$%^&*()_++*^$#@"}
+            };
+
+    private final String[][] mLongStrings =
+            new String[][] {
+                // Force execution of code beyond reference equality check
+                {mLong1, new String(mLong1)},
+                // Different constants, last character different, same length
+                {mLong1 + "fun!", mLong1 + "----"},
+                // Equal, constant comparison
+                {mLong1 + mLong1, mLong1 + mLong1},
+                // Different constants, different lengths
+                {mLong1 + "123456789", mLong1 + "12345678"},
+                // Different constants, first character different, same length
+                {"Android Runtime" + mLong1, "android Runtime" + mLong1}
+            };
+
+    private final String[][] mVeryLongStrings =
+            new String[][] {
+                // Force execution of code beyond reference equality check
+                {mVeryLong, new String(mVeryLong)},
+                // Different constants, different lengths
+                {mVeryLong + mVeryLong, mVeryLong + " " + mVeryLong},
+                // Equal, constant comparison
+                {mVeryLong + mVeryLong + mVeryLong, mVeryLong + mVeryLong + mVeryLong},
+                // Different constants, last character different, same length
+                {mVeryLong + "77777", mVeryLong + "99999"},
+                // Different constants, first character different
+                {"Android Runtime" + mVeryLong, "android Runtime" + mVeryLong}
+            };
+
+    private final String[][] mEndStrings =
+            new String[][] {
+                // Different constants, medium but different lengths
+                {"Hello", "Hello "},
+                // Different constants, long but different lengths
+                {mLong1, mLong1 + "x"},
+                // Different constants, very long but different lengths
+                {mVeryLong, mVeryLong + "?"},
+                // Different constants, same medium lengths
+                {"How are you doing today?", "How are you doing today "},
+                // Different constants, short but different lengths
+                {"1", "1."}
+            };
+
+    private final String mTmpStr1 =
+            "012345678901234567890"
+                    + "0123456789012345678901234567890123456789"
+                    + "0123456789012345678901234567890123456789"
+                    + "0123456789012345678901234567890123456789"
+                    + "0123456789012345678901234567890123456789";
+
+    private final String mTmpStr2 =
+            "z012345678901234567890"
+                    + "0123456789012345678901234567890123456789"
+                    + "0123456789012345678901234567890123456789"
+                    + "0123456789012345678901234567890123456789"
+                    + "012345678901234567890123456789012345678x";
+
+    private final String[][] mNonalignedStrings =
+            new String[][] {
+                // Different non-word aligned medium length strings
+                {mTmpStr1, mTmpStr1.substring(1)},
+                // Different differently non-word aligned medium length strings
+                {mTmpStr2, mTmpStr2.substring(2)},
+                // Different non-word aligned long length strings
+                {mLong1, mLong1.substring(3)},
+                // Different non-word aligned very long length strings
+                {mVeryLong, mVeryLong.substring(1)},
+                // Equal non-word aligned constant strings
+                {"hello", "hello".substring(1)}
+            };
+
+    private final Object[] mObjects =
+            new Object[] {
+                // Compare to Double object
+                new Double(1.5),
+                // Compare to Integer object
+                new Integer(9999999),
+                // Compare to String array
+                new String[] {"h", "i"},
+                // Compare to int array
+                new int[] {1, 2, 3},
+                // Compare to Character object
+                new Character('a')
+            };
+
+    // Check assumptions about how the compiler, new String(String), and String.intern() work.
+    // Any failures here would invalidate these benchmarks.
+    @Before
+    public void setUp() throws Exception {
+        // String constants are the same object
+        Assert.assertSame("abc", "abc");
+        // new String(String) makes a copy
+        Assert.assertNotSame("abc", new String("abc"));
+        // Interned strings are treated like constants, so it is not necessary to
+        // separately benchmark interned strings.
+        Assert.assertSame("abc", "abc".intern());
+        Assert.assertSame("abc", new String("abc").intern());
+        // Compiler folds constant strings into new constants
+        Assert.assertSame(mLong1 + mLong1, mLong1 + mLong1);
+    }
+
+    // Benchmark cases of String.equals(null)
+    @Test
+    public void timeEqualsNull() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < mMediumStrings.length; i++) {
+                mMediumStrings[i][0].equals(null);
+            }
+        }
+    }
+
+    // Benchmark cases with very short (<5 character) Strings
+    @Test
+    public void timeEqualsShort() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < mShortStrings.length; i++) {
+                mShortStrings[i][0].equals(mShortStrings[i][1]);
+            }
+        }
+    }
+
+    // Benchmark cases with medium length (10-15 character) Strings
+    @Test
+    public void timeEqualsMedium() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < mMediumStrings.length; i++) {
+                mMediumStrings[i][0].equals(mMediumStrings[i][1]);
+            }
+        }
+    }
+
+    // Benchmark cases with long (>100 character) Strings
+    @Test
+    public void timeEqualsLong() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < mLongStrings.length; i++) {
+                mLongStrings[i][0].equals(mLongStrings[i][1]);
+            }
+        }
+    }
+
+    // Benchmark cases with very long (>1000 character) Strings
+    @Test
+    public void timeEqualsVeryLong() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < mVeryLongStrings.length; i++) {
+                mVeryLongStrings[i][0].equals(mVeryLongStrings[i][1]);
+            }
+        }
+    }
+
+    // Benchmark cases with non-word aligned Strings
+    @Test
+    public void timeEqualsNonWordAligned() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < mNonalignedStrings.length; i++) {
+                mNonalignedStrings[i][0].equals(mNonalignedStrings[i][1]);
+            }
+        }
+    }
+
+    // Benchmark cases with slight differences in the endings
+    @Test
+    public void timeEqualsEnd() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < mEndStrings.length; i++) {
+                mEndStrings[i][0].equals(mEndStrings[i][1]);
+            }
+        }
+    }
+
+    // Benchmark cases of comparing a string to a non-string object
+    @Test
+    public void timeEqualsNonString() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < mMediumStrings.length; i++) {
+                mMediumStrings[i][0].equals(mObjects[i]);
+            }
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringIsEmptyPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringIsEmptyPerfTest.java
new file mode 100644
index 0000000..79ff646
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringIsEmptyPerfTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2022 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.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class StringIsEmptyPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeIsEmpty_NonEmpty() {
+        boolean result = true;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result &= !("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".isEmpty());
+        }
+        if (!result) throw new RuntimeException();
+    }
+
+    @Test
+    public void timeIsEmpty_Empty() {
+        boolean result = true;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result &= ("".isEmpty());
+        }
+        if (!result) throw new RuntimeException();
+    }
+
+    @Test
+    public void timeLengthEqualsZero() {
+        boolean result = true;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result &= !("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".length() == 0);
+        }
+        if (!result) throw new RuntimeException();
+    }
+
+    @Test
+    public void timeEqualsEmpty() {
+        boolean result = true;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result &= !"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".equals("");
+        }
+        if (!result) throw new RuntimeException();
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringLengthPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringLengthPerfTest.java
new file mode 100644
index 0000000..8dbf9f5
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringLengthPerfTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 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.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class StringLengthPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeLength() {
+        int length = 0;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            length = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".length();
+        }
+        if (length != 51) throw new RuntimeException();
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringPerfTest.java
new file mode 100644
index 0000000..02194b1
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringPerfTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2022 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.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class StringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    enum StringLengths {
+        EMPTY(""),
+        SHORT("short"),
+        EIGHTY(makeString(80)),
+        EIGHT_KI(makeString(8192));
+        final String mValue;
+
+        StringLengths(String value) {
+            this.mValue = value;
+        }
+    }
+
+    @Parameters(name = "mStringLengths={0}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(
+                new Object[][] {
+                    {StringLengths.EIGHT_KI},
+                    {StringLengths.EIGHTY},
+                    {StringLengths.SHORT},
+                    {StringLengths.EMPTY}
+                });
+    }
+
+    @Parameterized.Parameter(0)
+    public StringLengths mStringLengths;
+
+    private static String makeString(int length) {
+        StringBuilder result = new StringBuilder(length);
+        for (int i = 0; i < length; ++i) {
+            result.append((char) i);
+        }
+        return result.toString();
+    }
+
+    @Test
+    public void timeHashCode() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mStringLengths.mValue.hashCode();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringReplaceAllPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringReplaceAllPerfTest.java
new file mode 100644
index 0000000..b0d1ee4
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringReplaceAllPerfTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class StringReplaceAllPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    // NOTE: These estimates of MOVEABLE / NON_MOVEABLE are based on a knowledge of
+    // ART implementation details. They make a difference here because JNI calls related
+    // to strings took different paths depending on whether the String in question was
+    // moveable or not.
+    enum StringLengths {
+        EMPTY(""),
+        MOVEABLE_16(makeString(16)),
+        MOVEABLE_256(makeString(256)),
+        MOVEABLE_1024(makeString(1024)),
+        NON_MOVEABLE(makeString(64 * 1024)),
+        BOOT_IMAGE(java.util.jar.JarFile.MANIFEST_NAME);
+
+        private final String mValue;
+
+        StringLengths(String s) {
+            this.mValue = s;
+        }
+    }
+
+    private static String makeString(int length) {
+        final String sequence8 = "abcdefghijklmnop";
+        final int numAppends = (length / 16) - 1;
+        StringBuilder stringBuilder = new StringBuilder(length);
+
+        // (n-1) occurrences of "abcdefghijklmnop"
+        for (int i = 0; i < numAppends; ++i) {
+            stringBuilder.append(sequence8);
+        }
+
+        // and one final occurrence of qrstuvwx.
+        stringBuilder.append("qrstuvwx");
+
+        return stringBuilder.toString();
+    }
+
+    @Parameters(name = "mStringLengths={0}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(
+                new Object[][] {
+                    {StringLengths.BOOT_IMAGE},
+                    {StringLengths.EMPTY},
+                    {StringLengths.MOVEABLE_16},
+                    {StringLengths.MOVEABLE_256},
+                    {StringLengths.MOVEABLE_1024},
+                    {StringLengths.NON_MOVEABLE}
+                });
+    }
+
+    @Parameterized.Parameter(0)
+    public StringLengths mStringLengths;
+
+    @Test
+    public void timeReplaceAllTrivialPatternNonExistent() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mStringLengths.mValue.replaceAll("fish", "0");
+        }
+    }
+
+    @Test
+    public void timeReplaceTrivialPatternAllRepeated() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mStringLengths.mValue.replaceAll("jklm", "0");
+        }
+    }
+
+    @Test
+    public void timeReplaceAllTrivialPatternSingleOccurrence() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mStringLengths.mValue.replaceAll("qrst", "0");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringReplacePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringReplacePerfTest.java
new file mode 100644
index 0000000..d2e657a
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringReplacePerfTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2022 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.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class StringReplacePerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    enum StringLengths {
+        EMPTY(""),
+        L_16(makeString(16)),
+        L_64(makeString(64)),
+        L_256(makeString(256)),
+        L_512(makeString(512));
+
+        private final String mValue;
+
+        StringLengths(String s) {
+            this.mValue = s;
+        }
+    }
+
+    private static String makeString(int length) {
+        final String sequence8 = "abcdefghijklmnop";
+        final int numAppends = (length / 16) - 1;
+        StringBuilder stringBuilder = new StringBuilder(length);
+
+        // (n-1) occurrences of "abcdefghijklmnop"
+        for (int i = 0; i < numAppends; ++i) {
+            stringBuilder.append(sequence8);
+        }
+
+        // and one final occurrence of qrstuvwx.
+        stringBuilder.append("qrstuvwx");
+
+        return stringBuilder.toString();
+    }
+
+    @Parameters(name = "mStringLengths={0}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(
+                new Object[][] {
+                    {StringLengths.EMPTY},
+                    {StringLengths.L_16},
+                    {StringLengths.L_64},
+                    {StringLengths.L_256},
+                    {StringLengths.L_512}
+                });
+    }
+
+    @Parameterized.Parameter(0)
+    public StringLengths mStringLengths;
+
+    @Test
+    public void timeReplaceCharNonExistent() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mStringLengths.mValue.replace('z', '0');
+        }
+    }
+
+    @Test
+    public void timeReplaceCharRepeated() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mStringLengths.mValue.replace('a', '0');
+        }
+    }
+
+    @Test
+    public void timeReplaceSingleChar() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mStringLengths.mValue.replace('q', '0');
+        }
+    }
+
+    @Test
+    public void timeReplaceSequenceNonExistent() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mStringLengths.mValue.replace("fish", "0");
+        }
+    }
+
+    @Test
+    public void timeReplaceSequenceRepeated() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mStringLengths.mValue.replace("jklm", "0");
+        }
+    }
+
+    @Test
+    public void timeReplaceSingleSequence() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mStringLengths.mValue.replace("qrst", "0");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringSplitPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringSplitPerfTest.java
new file mode 100644
index 0000000..2bb25ac
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringSplitPerfTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2022 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.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.regex.Pattern;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class StringSplitPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeStringSplitComma() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            "this,is,a,simple,example".split(",");
+        }
+    }
+
+    @Test
+    public void timeStringSplitLiteralDot() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            "this.is.a.simple.example".split("\\.");
+        }
+    }
+
+    @Test
+    public void timeStringSplitNewline() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            "this\nis\na\nsimple\nexample\n".split("\n");
+        }
+    }
+
+    @Test
+    public void timePatternSplitComma() {
+        Pattern p = Pattern.compile(",");
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            p.split("this,is,a,simple,example");
+        }
+    }
+
+    @Test
+    public void timePatternSplitLiteralDot() {
+        Pattern p = Pattern.compile("\\.");
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            p.split("this.is.a.simple.example");
+        }
+    }
+
+    @Test
+    public void timeStringSplitHard() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            "this,is,a,harder,example".split("[,]");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringToBytesPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringToBytesPerfTest.java
new file mode 100644
index 0000000..1efc188
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringToBytesPerfTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2022 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.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class StringToBytesPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    enum StringLengths {
+        EMPTY(""),
+        L_16(makeString(16)),
+        L_64(makeString(64)),
+        L_256(makeString(256)),
+        L_512(makeString(512)),
+        A_16(makeAsciiString(16)),
+        A_64(makeAsciiString(64)),
+        A_256(makeAsciiString(256)),
+        A_512(makeAsciiString(512));
+
+        private final String mValue;
+
+        StringLengths(String s) {
+            this.mValue = s;
+        }
+    }
+
+    @Parameters(name = "mStringLengths={0}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(
+                new Object[][] {
+                    {StringLengths.EMPTY},
+                    {StringLengths.L_16},
+                    {StringLengths.L_64},
+                    {StringLengths.L_256},
+                    {StringLengths.L_512},
+                    {StringLengths.A_16},
+                    {StringLengths.A_64},
+                    {StringLengths.A_256},
+                    {StringLengths.A_512}
+                });
+    }
+
+    @Parameterized.Parameter(0)
+    public StringLengths mStringLengths;
+
+    private static String makeString(int length) {
+        char[] chars = new char[length];
+        for (int i = 0; i < length; ++i) {
+            chars[i] = (char) i;
+        }
+        return new String(chars);
+    }
+
+    private static String makeAsciiString(int length) {
+        char[] chars = new char[length];
+        for (int i = 0; i < length; ++i) {
+            chars[i] = ((i & 0x7f) != 0) ? (char) (i & 0x7f) : '?';
+        }
+        return new String(chars);
+    }
+
+    @Test
+    public void timeGetBytesUtf8() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mStringLengths.mValue.getBytes(StandardCharsets.UTF_8);
+        }
+    }
+
+    @Test
+    public void timeGetBytesIso88591() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mStringLengths.mValue.getBytes(StandardCharsets.ISO_8859_1);
+        }
+    }
+
+    @Test
+    public void timeGetBytesAscii() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mStringLengths.mValue.getBytes(StandardCharsets.US_ASCII);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringToRealPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringToRealPerfTest.java
new file mode 100644
index 0000000..b01948a
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringToRealPerfTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 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.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class StringToRealPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Parameters(name = "mString={0}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(
+                new Object[][] {
+                    {"NaN"},
+                    {"-1"},
+                    {"0"},
+                    {"1"},
+                    {"1.2"},
+                    {"-123.45"},
+                    {"-123.45e8"},
+                    {"-123.45e36"}
+                });
+    }
+
+    @Parameterized.Parameter(0)
+    public String mString;
+
+    @Test
+    public void timeFloat_parseFloat() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Float.parseFloat(mString);
+        }
+    }
+
+    @Test
+    public void timeDouble_parseDouble() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Double.parseDouble(mString);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ThreadLocalPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ThreadLocalPerfTest.java
new file mode 100644
index 0000000..f256555
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/ThreadLocalPerfTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 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.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ThreadLocalPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private static final ThreadLocal<char[]> BUFFER =
+            new ThreadLocal<char[]>() {
+                @Override
+                protected char[] initialValue() {
+                    return new char[20];
+                }
+            };
+
+    @Test
+    public void timeThreadLocal_get() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            BUFFER.get();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/TimeZonePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/TimeZonePerfTest.java
new file mode 100644
index 0000000..8274512
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/TimeZonePerfTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2022 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.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.TimeZone;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class TimeZonePerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeTimeZone_getDefault() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            TimeZone.getDefault();
+        }
+    }
+
+    @Test
+    public void timeTimeZone_getTimeZoneUTC() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            TimeZone.getTimeZone("UTC");
+        }
+    }
+
+    @Test
+    public void timeTimeZone_getTimeZone_default() throws Exception {
+        String defaultId = TimeZone.getDefault().getID();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            TimeZone.getTimeZone(defaultId);
+        }
+    }
+
+    // A time zone with relatively few transitions.
+    @Test
+    public void timeTimeZone_getTimeZone_America_Caracas() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            TimeZone.getTimeZone("America/Caracas");
+        }
+    }
+
+    // A time zone with a lot of transitions.
+    @Test
+    public void timeTimeZone_getTimeZone_America_Santiago() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            TimeZone.getTimeZone("America/Santiago");
+        }
+    }
+
+    @Test
+    public void timeTimeZone_getTimeZone_GMT_plus_10() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            TimeZone.getTimeZone("GMT+10");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/XMLEntitiesPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/XMLEntitiesPerfTest.java
new file mode 100644
index 0000000..2ea834d
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/XMLEntitiesPerfTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2022 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.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.xml.sax.InputSource;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import java.io.StringReader;
+import java.util.Arrays;
+import java.util.Collection;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+// http://code.google.com/p/android/issues/detail?id=18102
+@RunWith(Parameterized.class)
+@LargeTest
+public final class XMLEntitiesPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Parameters(name = "mLength={0}, mEntityFraction={1}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(
+                new Object[][] {
+                    {10, 0},
+                    {10, 0.5f},
+                    {10, 1.0f},
+                    {100, 0},
+                    {100, 0.5f},
+                    {100, 1.0f},
+                    {1000, 0},
+                    {1000, 0.5f},
+                    {1000, 1.0f}
+                });
+    }
+
+    @Parameterized.Parameter(0)
+    public int mLength;
+
+    @Parameterized.Parameter(1)
+    public float mEntityFraction;
+
+    private XmlPullParserFactory mXmlPullParserFactory;
+    private DocumentBuilderFactory mDocumentBuilderFactory;
+
+    /** a string like {@code <doc>&amp;&amp;++</doc>}. */
+    private String mXml;
+
+    @Before
+    public void setUp() throws Exception {
+        mXmlPullParserFactory = XmlPullParserFactory.newInstance();
+        mDocumentBuilderFactory = DocumentBuilderFactory.newInstance();
+
+        StringBuilder xmlBuilder = new StringBuilder();
+        xmlBuilder.append("<doc>");
+        for (int i = 0; i < (mLength * mEntityFraction); i++) {
+            xmlBuilder.append("&amp;");
+        }
+        while (xmlBuilder.length() < mLength) {
+            xmlBuilder.append("+");
+        }
+        xmlBuilder.append("</doc>");
+        mXml = xmlBuilder.toString();
+    }
+
+    @Test
+    public void timeXmlParser() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            XmlPullParser parser = mXmlPullParserFactory.newPullParser();
+            parser.setInput(new StringReader(mXml));
+            while (parser.next() != XmlPullParser.END_DOCUMENT) {
+                // Keep running
+            }
+        }
+    }
+
+    @Test
+    public void timeDocumentBuilder() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            DocumentBuilder documentBuilder = mDocumentBuilderFactory.newDocumentBuilder();
+            documentBuilder.parse(new InputSource(new StringReader(mXml)));
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/view/HandwritingImeService.java b/apct-tests/perftests/core/src/android/view/HandwritingImeService.java
new file mode 100644
index 0000000..27cb16e
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/view/HandwritingImeService.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 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.view;
+
+import android.content.ComponentName;
+import android.inputmethodservice.InputMethodService;
+
+public class HandwritingImeService extends InputMethodService {
+    private static final String PACKAGE_NAME = "com.android.perftests.core";
+
+    private static ComponentName getComponentName() {
+        return new ComponentName(PACKAGE_NAME, HandwritingImeService.class.getName());
+    }
+
+    static String getImeId() {
+        return getComponentName().flattenToShortString();
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java b/apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java
index 123b2ee..cf76334 100644
--- a/apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java
+++ b/apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java
@@ -22,7 +22,6 @@
 import static android.view.MotionEvent.TOOL_TYPE_FINGER;
 import static android.view.MotionEvent.TOOL_TYPE_STYLUS;
 
-
 import android.app.Instrumentation;
 import android.content.Context;
 import android.perftests.utils.BenchmarkState;
@@ -34,11 +33,15 @@
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.compatibility.common.util.PollingCheck;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.concurrent.TimeUnit;
+
 /**
  * Benchmark tests for {@link HandwritingInitiator}
  *
@@ -56,11 +59,21 @@
     public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
 
     @Before
-    public void setup() {
-        final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
-        mContext = mInstrumentation.getTargetContext();
+    public void setup() throws Exception {
+        final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+        mContext = instrumentation.getTargetContext();
+
+        String imeId = HandwritingImeService.getImeId();
+        instrumentation.getUiAutomation().executeShellCommand("ime enable " + imeId);
+        instrumentation.getUiAutomation().executeShellCommand("ime set " + imeId);
+        PollingCheck.check("Check that stylus handwriting is available",
+                TimeUnit.SECONDS.toMillis(10),
+                () -> mContext.getSystemService(InputMethodManager.class)
+                        .isStylusHandwritingAvailable());
+
         final ViewConfiguration viewConfiguration = ViewConfiguration.get(mContext);
         mTouchSlop = viewConfiguration.getScaledTouchSlop();
+
         final InputMethodManager inputMethodManager =
                 mContext.getSystemService(InputMethodManager.class);
         mHandwritingInitiator = new HandwritingInitiator(viewConfiguration, inputMethodManager);
diff --git a/apct-tests/perftests/core/src/com/android/internal/util/FastDataPerfTest.java b/apct-tests/perftests/core/src/com/android/internal/util/FastDataPerfTest.java
index e3691a7..76656bd 100644
--- a/apct-tests/perftests/core/src/com/android/internal/util/FastDataPerfTest.java
+++ b/apct-tests/perftests/core/src/com/android/internal/util/FastDataPerfTest.java
@@ -52,19 +52,39 @@
         while (state.keepRunning()) {
             os.reset();
             final BufferedOutputStream bos = new BufferedOutputStream(os, BUFFER_SIZE);
-            final DataOutput out = new DataOutputStream(bos);
-            doWrite(out);
-            bos.flush();
+            final DataOutputStream out = new DataOutputStream(bos);
+            try {
+                doWrite(out);
+                out.flush();
+            } finally {
+                out.close();
+            }
         }
     }
 
     @Test
-    public void timeWrite_Local() throws IOException {
+    public void timeWrite_LocalUsing4ByteSequences() throws IOException {
         final ByteArrayOutputStream os = new ByteArrayOutputStream(OUTPUT_SIZE);
         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
         while (state.keepRunning()) {
             os.reset();
-            final FastDataOutput out = FastDataOutput.obtain(os);
+            final FastDataOutput out = FastDataOutput.obtainUsing4ByteSequences(os);
+            try {
+                doWrite(out);
+                out.flush();
+            } finally {
+                out.release();
+            }
+        }
+    }
+
+    @Test
+    public void timeWrite_LocalUsing3ByteSequences() throws IOException {
+        final ByteArrayOutputStream os = new ByteArrayOutputStream(OUTPUT_SIZE);
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            os.reset();
+            final FastDataOutput out = FastDataOutput.obtainUsing3ByteSequences(os);
             try {
                 doWrite(out);
                 out.flush();
@@ -81,19 +101,42 @@
         while (state.keepRunning()) {
             is.reset();
             final BufferedInputStream bis = new BufferedInputStream(is, BUFFER_SIZE);
-            final DataInput in = new DataInputStream(bis);
-            doRead(in);
+            final DataInputStream in = new DataInputStream(bis);
+            try {
+                doRead(in);
+            } finally {
+                in.close();
+            }
         }
     }
 
     @Test
-    public void timeRead_Local() throws Exception {
+    public void timeRead_LocalUsing4ByteSequences() throws Exception {
         final ByteArrayInputStream is = new ByteArrayInputStream(doWrite());
         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
         while (state.keepRunning()) {
             is.reset();
-            final DataInput in = new FastDataInput(is, BUFFER_SIZE);
-            doRead(in);
+            final FastDataInput in = FastDataInput.obtainUsing4ByteSequences(is);
+            try {
+                doRead(in);
+            } finally {
+                in.release();
+            }
+        }
+    }
+
+    @Test
+    public void timeRead_LocalUsing3ByteSequences() throws Exception {
+        final ByteArrayInputStream is = new ByteArrayInputStream(doWrite());
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            is.reset();
+            final FastDataInput in = FastDataInput.obtainUsing3ByteSequences(is);
+            try {
+                doRead(in);
+            } finally {
+                in.release();
+            }
         }
     }
 
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/BroadcastWaiter.java b/apct-tests/perftests/multiuser/src/android/multiuser/BroadcastWaiter.java
index 7ed97fb..dcabca4 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/BroadcastWaiter.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/BroadcastWaiter.java
@@ -23,9 +23,12 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.os.SystemClock;
 import android.text.TextUtils;
 import android.util.Log;
 
+import com.android.internal.util.FunctionalUtils;
+
 import java.io.Closeable;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -72,7 +75,8 @@
             @Override
             public void onReceive(Context context, Intent intent) {
                 if (action.equals(intent.getAction())) {
-                    final int userId = getSendingUserId();
+                    final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
+                            getSendingUserId());
                     final String data = intent.getDataString();
                     Log.d(mTag, "Received " + action + " for user " + userId
                             + (!TextUtils.isEmpty(data) ? " with " + data : ""));
@@ -95,7 +99,7 @@
         return mActionReceivedForUser.contains(action + userId);
     }
 
-    public boolean waitActionForUser(String action, int userId) {
+    private boolean waitActionForUser(String action, int userId) {
         Log.d(mTag, "#waitActionForUser(action: " + action + ", userId: " + userId + ")");
 
         if (!mActions.contains(action)) {
@@ -103,18 +107,40 @@
             return false;
         }
 
+        final long startTime = SystemClock.elapsedRealtime();
         try {
-            if (!getSemaphore(action, userId).tryAcquire(1, mTimeoutInSecond, SECONDS)) {
-                Log.e(mTag, action + " broadcast wasn't received for user " + userId);
+            final boolean doneBeforeTimeout = getSemaphore(action, userId)
+                    .tryAcquire(1, mTimeoutInSecond, SECONDS);
+            if (!doneBeforeTimeout) {
+                Log.e(mTag, action + " broadcast wasn't received for user " + userId
+                        + " in " + mTimeoutInSecond + " seconds");
                 return false;
             }
         } catch (InterruptedException e) {
             Log.e(mTag, "Interrupted while waiting " + action + " for user " + userId);
             return false;
         }
+        final long elapsedTime = SystemClock.elapsedRealtime() - startTime;
+        Log.d(mTag, action + " broadcast received for user " + userId
+                + " in " + elapsedTime + " ms");
         return true;
     }
 
+    public String runThenWaitForBroadcasts(int userId, FunctionalUtils.ThrowingRunnable runnable,
+            String... actions) {
+        for (String action : actions) {
+            mActionReceivedForUser.remove(action + userId);
+            getSemaphore(action, userId).drainPermits();
+        }
+        runnable.run();
+        for (String action : actions) {
+            if (!waitActionForUser(action, userId)) {
+                return action;
+            }
+        }
+        return null;
+    }
+
     public boolean waitActionForUserIfNotReceivedYet(String action, int userId) {
         return hasActionBeenReceivedForUser(action, userId)
                 || waitActionForUser(action, userId);
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
index a44d939..448ee61 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
@@ -15,6 +15,7 @@
  */
 package android.multiuser;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assume.assumeTrue;
 
 import android.annotation.NonNull;
@@ -23,14 +24,12 @@
 import android.app.AppGlobals;
 import android.app.IActivityManager;
 import android.app.IStopUserCallback;
-import android.app.UserSwitchObserver;
 import android.app.WaitResult;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.IIntentReceiver;
 import android.content.IIntentSender;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.IntentSender;
 import android.content.pm.IPackageInstaller;
 import android.content.pm.PackageManager;
@@ -44,6 +43,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.perftests.utils.ShellHelper;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.WindowManagerGlobal;
 
@@ -51,6 +51,8 @@
 import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.util.FunctionalUtils;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
@@ -115,13 +117,15 @@
     private ArrayList<Integer> mUsersToRemove;
     private boolean mHasManagedUserFeature;
     private BroadcastWaiter mBroadcastWaiter;
+    private UserSwitchWaiter mUserSwitchWaiter;
+    private String mUserSwitchTimeoutMs;
 
     private final BenchmarkRunner mRunner = new BenchmarkRunner();
     @Rule
     public BenchmarkResultsReporter mReporter = new BenchmarkResultsReporter(mRunner);
 
     @Before
-    public void setUp() {
+    public void setUp() throws Exception {
         final Context context = InstrumentationRegistry.getContext();
         mUm = UserManager.get(context);
         mAm = context.getSystemService(ActivityManager.class);
@@ -132,16 +136,24 @@
         mBroadcastWaiter = new BroadcastWaiter(context, TAG, TIMEOUT_IN_SECOND,
                 Intent.ACTION_USER_STARTED,
                 Intent.ACTION_MEDIA_MOUNTED,
-                Intent.ACTION_USER_UNLOCKED);
+                Intent.ACTION_USER_UNLOCKED,
+                Intent.ACTION_USER_STOPPED);
+        mUserSwitchWaiter = new UserSwitchWaiter(TAG, TIMEOUT_IN_SECOND);
         removeAnyPreviousTestUsers();
         if (mAm.getCurrentUser() != UserHandle.USER_SYSTEM) {
             Log.w(TAG, "WARNING: Tests are being run from user " + mAm.getCurrentUser()
                     + " rather than the system user");
         }
+        mUserSwitchTimeoutMs = setSystemProperty("debug.usercontroller.user_switch_timeout_ms",
+                "100000");
+        if (TextUtils.isEmpty(mUserSwitchTimeoutMs)) {
+            mUserSwitchTimeoutMs = "invalid";
+        }
     }
 
     @After
-    public void tearDown() {
+    public void tearDown() throws Exception {
+        setSystemProperty("debug.usercontroller.user_switch_timeout_ms", mUserSwitchTimeoutMs);
         mBroadcastWaiter.close();
         for (int userId : mUsersToRemove) {
             try {
@@ -175,8 +187,9 @@
 
             // Don't use this.startUserInBackgroundAndWaitForUnlock() since only waiting until
             // ACTION_USER_STARTED.
-            mIam.startUserInBackground(userId);
-            waitForBroadcast(Intent.ACTION_USER_STARTED, userId);
+            runThenWaitForBroadcasts(userId, () -> {
+                mIam.startUserInBackground(userId);
+            }, Intent.ACTION_USER_STARTED);
 
             mRunner.pauseTiming();
             Log.i(TAG, "Stopping timer");
@@ -197,8 +210,9 @@
             mRunner.resumeTiming();
             Log.i(TAG, "Starting timer");
 
-            mIam.startUserInBackground(userId);
-            waitForBroadcast(Intent.ACTION_USER_STARTED, userId);
+            runThenWaitForBroadcasts(userId, () -> {
+                mIam.startUserInBackground(userId);
+            }, Intent.ACTION_USER_STARTED);
 
             mRunner.pauseTiming();
             Log.i(TAG, "Stopping timer");
@@ -231,7 +245,7 @@
 
     /** Tests switching to an uninitialized user. */
     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
-    public void switchUser() throws RemoteException {
+    public void switchUser() throws Exception {
         while (mRunner.keepRunning()) {
             mRunner.pauseTiming();
             final int startUser = mAm.getCurrentUser();
@@ -259,8 +273,9 @@
             mRunner.resumeTiming();
             Log.i(TAG, "Starting timer");
 
-            mAm.switchUser(testUser);
-            waitForBroadcast(Intent.ACTION_USER_UNLOCKED, testUser);
+            runThenWaitForBroadcasts(testUser, () -> {
+                mAm.switchUser(testUser);
+            }, Intent.ACTION_USER_UNLOCKED);
 
             mRunner.pauseTiming();
             Log.i(TAG, "Stopping timer");
@@ -296,10 +311,10 @@
         while (mRunner.keepRunning()) {
             mRunner.pauseTiming();
             final int userId = createUserNoFlags();
-            mIam.startUserInBackground(userId);
 
-            waitForBroadcast(Intent.ACTION_USER_STARTED, userId);
-            waitForBroadcast(Intent.ACTION_MEDIA_MOUNTED, userId);
+            runThenWaitForBroadcasts(userId, ()-> {
+                mIam.startUserInBackground(userId);
+            }, Intent.ACTION_USER_STARTED, Intent.ACTION_MEDIA_MOUNTED);
 
             mRunner.resumeTiming();
             Log.i(TAG, "Starting timer");
@@ -320,13 +335,12 @@
             mRunner.pauseTiming();
             final int startUser = mAm.getCurrentUser();
             final int userId = createUserNoFlags();
-            final CountDownLatch latch = new CountDownLatch(1);
-            registerUserSwitchObserver(null, latch, userId);
-            mRunner.resumeTiming();
-            Log.i(TAG, "Starting timer");
 
-            mAm.switchUser(userId);
-            waitForLatch("Failed to achieve onLockedBootComplete for user " + userId, latch);
+            mUserSwitchWaiter.runThenWaitUntilBootCompleted(userId, () -> {
+                mRunner.resumeTiming();
+                Log.i(TAG, "Starting timer");
+                mAm.switchUser(userId);
+            }, () -> fail("Failed to achieve onLockedBootComplete for user " + userId));
 
             mRunner.pauseTiming();
             Log.i(TAG, "Stopping timer");
@@ -343,34 +357,22 @@
             mRunner.pauseTiming();
             final int startUser = mAm.getCurrentUser();
             final int userId = createUserWithFlags(UserInfo.FLAG_EPHEMERAL | UserInfo.FLAG_DEMO);
-            switchUser(userId);
-            waitForBroadcast(Intent.ACTION_MEDIA_MOUNTED, userId);
+            runThenWaitForBroadcasts(userId, () -> {
+                switchUser(userId);
+            }, Intent.ACTION_MEDIA_MOUNTED);
 
-            final CountDownLatch latch = new CountDownLatch(1);
-            InstrumentationRegistry.getContext().registerReceiver(new BroadcastReceiver() {
-                @Override
-                public void onReceive(Context context, Intent intent) {
-                    if (Intent.ACTION_USER_STOPPED.equals(intent.getAction()) && intent.getIntExtra(
-                            Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL) == userId) {
-                        latch.countDown();
-                    }
-                }
-            }, new IntentFilter(Intent.ACTION_USER_STOPPED));
-            final CountDownLatch switchLatch = new CountDownLatch(1);
-            registerUserSwitchObserver(switchLatch, null, startUser);
-            mRunner.resumeTiming();
-            Log.i(TAG, "Starting timer");
+            mUserSwitchWaiter.runThenWaitUntilSwitchCompleted(startUser, () -> {
+                mRunner.resumeTiming();
+                Log.i(TAG, "Starting timer");
 
-            mAm.switchUser(startUser);
-            waitForLatch("Failed to achieve ACTION_USER_STOPPED for user " + userId, latch);
+                runThenWaitForBroadcasts(userId, () -> {
+                    mAm.switchUser(startUser);
+                }, Intent.ACTION_USER_STOPPED);
 
-            mRunner.pauseTiming();
-            Log.i(TAG, "Stopping timer");
-            try {
-                switchLatch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
-            } catch (InterruptedException e) {
-                Log.e(TAG, "Thread interrupted unexpectedly while waiting for switch.", e);
-            }
+                mRunner.pauseTiming();
+                Log.i(TAG, "Stopping timer");
+            }, null);
+
             removeUser(userId);
             mRunner.resumeTimingForNextIteration();
         }
@@ -547,8 +549,9 @@
         while (mRunner.keepRunning()) {
             mRunner.pauseTiming();
             final int userId = createManagedProfile();
-            startUserInBackgroundAndWaitForUnlock(userId);
-            waitForBroadcast(Intent.ACTION_MEDIA_MOUNTED, userId);
+            runThenWaitForBroadcasts(userId, () -> {
+                startUserInBackgroundAndWaitForUnlock(userId);
+            }, Intent.ACTION_MEDIA_MOUNTED);
 
             mRunner.resumeTiming();
             Log.i(TAG, "Starting timer");
@@ -667,15 +670,11 @@
      * If lack of success should fail the test, use {@link #switchUser(int)} instead.
      */
     private boolean switchUserNoCheck(int userId) throws RemoteException {
-        final CountDownLatch latch = new CountDownLatch(1);
-        registerUserSwitchObserver(latch, null, userId);
-        mAm.switchUser(userId);
-        try {
-            return latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
-        } catch (InterruptedException e) {
-            Log.e(TAG, "Thread interrupted unexpectedly.", e);
-            return false;
-        }
+        final boolean[] success = {true};
+        mUserSwitchWaiter.runThenWaitUntilSwitchCompleted(userId, () -> {
+            mAm.switchUser(userId);
+        }, () -> success[0] = false);
+        return success[0];
     }
 
     private void stopUser(int userId, boolean force) throws RemoteException {
@@ -704,9 +703,9 @@
         final int origUser = mAm.getCurrentUser();
         // First, create and switch to testUser, waiting for its ACTION_USER_UNLOCKED
         final int testUser = createUserNoFlags();
-        mAm.switchUser(testUser);
-        waitForBroadcast(Intent.ACTION_USER_UNLOCKED, testUser);
-        waitForBroadcast(Intent.ACTION_MEDIA_MOUNTED, testUser);
+        runThenWaitForBroadcasts(testUser, () -> {
+            mAm.switchUser(testUser);
+        }, Intent.ACTION_USER_UNLOCKED, Intent.ACTION_MEDIA_MOUNTED);
 
         // Second, switch back to origUser, waiting merely for switchUser() to finish
         switchUser(origUser);
@@ -756,26 +755,6 @@
                 result.result == ActivityManager.START_SUCCESS);
     }
 
-    private void registerUserSwitchObserver(final CountDownLatch switchLatch,
-            final CountDownLatch bootCompleteLatch, final int userId) throws RemoteException {
-        ActivityManager.getService().registerUserSwitchObserver(
-                new UserSwitchObserver() {
-                    @Override
-                    public void onUserSwitchComplete(int newUserId) throws RemoteException {
-                        if (switchLatch != null && userId == newUserId) {
-                            switchLatch.countDown();
-                        }
-                    }
-
-                    @Override
-                    public void onLockedBootComplete(int newUserId) {
-                        if (bootCompleteLatch != null && userId == newUserId) {
-                            bootCompleteLatch.countDown();
-                        }
-                    }
-                }, TAG);
-    }
-
     private class ProgressWaiter extends IProgressListener.Stub {
         private final CountDownLatch mFinishedLatch = new CountDownLatch(1);
 
@@ -803,12 +782,21 @@
     /**
      * Waits TIMEOUT_IN_SECOND for the broadcast to be received, otherwise declares the given error.
      * It only works for the broadcasts provided in {@link #mBroadcastWaiter}'s instantiation above.
-     * @param action action of the broadcast, i.e. {@link Intent#ACTION_USER_STARTED}
-     * @param userId sendingUserId of the broadcast. See {@link BroadcastReceiver#getSendingUserId}
+     * @param userId userId associated with the broadcast. It is {@link Intent#EXTRA_USER_HANDLE}
+     *               or in case that is null, then it is {@link BroadcastReceiver#getSendingUserId}.
+     * @param runnable function to be run after clearing any possible previously received broadcasts
+     *                 and before waiting for the new broadcasts. This function should typically do
+     *                 something to trigger broadcasts to be sent. Like starting or stopping a user.
+     * @param actions actions of the broadcasts, i.e. {@link Intent#ACTION_USER_STARTED}.
+     *                If multiple actions are provided, they will be waited in given order.
      */
-    private void waitForBroadcast(String action, int userId) {
-        attestTrue("Failed to achieve " + action + " for user " + userId,
-                mBroadcastWaiter.waitActionForUser(action, userId));
+    private void runThenWaitForBroadcasts(int userId, FunctionalUtils.ThrowingRunnable runnable,
+            String... actions) {
+        final String unreceivedAction =
+                mBroadcastWaiter.runThenWaitForBroadcasts(userId, runnable, actions);
+
+        attestTrue("Failed to achieve " + unreceivedAction + " for user " + userId,
+                unreceivedAction == null);
     }
 
     /** Waits TIMEOUT_IN_SECOND for the latch to complete, otherwise declares the given error. */
@@ -874,14 +862,24 @@
         }
     }
 
+    private void fail(@NonNull String message) {
+        Log.e(TAG, "Test failed on iteration #" + mRunner.getIteration() + ": " + message);
+        mRunner.markAsFailed(new AssertionError(message));
+    }
+
     private void attestTrue(@NonNull String message, boolean assertion) {
         if (!assertion) {
-            Log.e(TAG, "Test failed on iteration #" + mRunner.getIteration() + ": " + message);
-            mRunner.markAsFailed(new AssertionError(message));
+            fail(message);
         }
     }
 
     private void attestFalse(@NonNull String message, boolean assertion) {
         attestTrue(message, !assertion);
     }
+
+    private String setSystemProperty(String name, String value) throws Exception {
+        final String oldValue = ShellHelper.runShellCommand("getprop " + name);
+        assertEquals("", ShellHelper.runShellCommand("setprop " + name + " " + value));
+        return oldValue;
+    }
 }
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserSwitchWaiter.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserSwitchWaiter.java
new file mode 100644
index 0000000..228d14c
--- /dev/null
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserSwitchWaiter.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2022 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.multiuser;
+
+import android.app.ActivityManager;
+import android.app.UserSwitchObserver;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.util.FunctionalUtils;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class UserSwitchWaiter {
+
+    private final String mTag;
+    private final int mTimeoutInSecond;
+
+    public UserSwitchWaiter(String tag, int timeoutInSecond) {
+        mTag = tag;
+        mTimeoutInSecond = timeoutInSecond;
+    }
+
+    public void runThenWaitUntilSwitchCompleted(int userId,
+            FunctionalUtils.ThrowingRunnable runnable, Runnable onFail) throws RemoteException {
+        final CountDownLatch latch = new CountDownLatch(1);
+        ActivityManager.getService().registerUserSwitchObserver(
+                new UserSwitchObserver() {
+                    @Override
+                    public void onUserSwitchComplete(int newUserId) throws RemoteException {
+                        if (userId == newUserId) {
+                            latch.countDown();
+                        }
+                    }
+                }, mTag);
+        runnable.run();
+        waitForLatch(latch, onFail);
+    }
+
+    public void runThenWaitUntilBootCompleted(int userId,
+            FunctionalUtils.ThrowingRunnable runnable, Runnable onFail) throws RemoteException {
+        final CountDownLatch latch = new CountDownLatch(1);
+        ActivityManager.getService().registerUserSwitchObserver(
+                new UserSwitchObserver() {
+                    @Override
+                    public void onLockedBootComplete(int newUserId) {
+                        if (userId == newUserId) {
+                            latch.countDown();
+                        }
+                    }
+                }, mTag);
+        runnable.run();
+        waitForLatch(latch, onFail);
+    }
+
+    private void waitForLatch(CountDownLatch latch, Runnable onFail) {
+        boolean success = false;
+        try {
+            success = latch.await(mTimeoutInSecond, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            Log.e(mTag, "Thread interrupted unexpectedly.", e);
+        }
+        if (!success && onFail != null) {
+            onFail.run();
+        }
+    }
+}
diff --git a/apct-tests/perftests/rubidium/assets/turtledove_parametrized_generateBid.js b/apct-tests/perftests/rubidium/assets/turtledove_parametrized_generateBid.js
new file mode 100644
index 0000000..d8e0f8e
--- /dev/null
+++ b/apct-tests/perftests/rubidium/assets/turtledove_parametrized_generateBid.js
@@ -0,0 +1,113 @@
+/*
+
+ Copyright The Closure Library Authors.
+ SPDX-License-Identifier: Apache-2.0
+*/
+var n,aa=function(a){var b=0;return function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}}},ba="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(a==Array.prototype||a==Object.prototype)return a;a[b]=c.value;return a},ca=function(a){a=["object"==typeof globalThis&&globalThis,a,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var b=0;b<a.length;++b){var c=a[b];if(c&&c.Math==Math)return c}throw Error("Cannot find global object");
+},ea=ca(this),q=function(a,b){if(b)a:{var c=ea;a=a.split(".");for(var d=0;d<a.length-1;d++){var e=a[d];if(!(e in c))break a;c=c[e]}a=a[a.length-1];d=c[a];b=b(d);b!=d&&null!=b&&ba(c,a,{configurable:!0,writable:!0,value:b})}};
+q("Symbol",function(a){if(a)return a;var b=function(g,f){this.ra=g;ba(this,"description",{configurable:!0,writable:!0,value:f})};b.prototype.toString=function(){return this.ra};var c="jscomp_symbol_"+(1E9*Math.random()>>>0)+"_",d=0,e=function(g){if(this instanceof e)throw new TypeError("Symbol is not a constructor");return new b(c+(g||"")+"_"+d++,g)};return e});
+q("Symbol.iterator",function(a){if(a)return a;a=Symbol("Symbol.iterator");for(var b="Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array".split(" "),c=0;c<b.length;c++){var d=ea[b[c]];"function"===typeof d&&"function"!=typeof d.prototype[a]&&ba(d.prototype,a,{configurable:!0,writable:!0,value:function(){return fa(aa(this))}})}return a});
+var fa=function(a){a={next:a};a[Symbol.iterator]=function(){return this};return a},r=function(a){var b="undefined"!=typeof Symbol&&Symbol.iterator&&a[Symbol.iterator];return b?b.call(a):{next:aa(a)}},ha="function"==typeof Object.create?Object.create:function(a){var b=function(){};b.prototype=a;return new b},ia;
+if("function"==typeof Object.setPrototypeOf)ia=Object.setPrototypeOf;else{var ja;a:{var ka={a:!0},la={};try{la.__proto__=ka;ja=la.a;break a}catch(a){}ja=!1}ia=ja?function(a,b){a.__proto__=b;if(a.__proto__!==b)throw new TypeError(a+" is not extensible");return a}:null}
+var ma=ia,t=function(a,b){a.prototype=ha(b.prototype);a.prototype.constructor=a;if(ma)ma(a,b);else for(var c in b)if("prototype"!=c)if(Object.defineProperties){var d=Object.getOwnPropertyDescriptor(b,c);d&&Object.defineProperty(a,c,d)}else a[c]=b[c];a.za=b.prototype},u=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)};
+q("WeakMap",function(a){function b(){}function c(k){var l=typeof k;return"object"===l&&null!==k||"function"===l}function d(k){if(!u(k,g)){var l=new b;ba(k,g,{value:l})}}function e(k){var l=Object[k];l&&(Object[k]=function(m){if(m instanceof b)return m;Object.isExtensible(m)&&d(m);return l(m)})}if(function(){if(!a||!Object.seal)return!1;try{var k=Object.seal({}),l=Object.seal({}),m=new a([[k,2],[l,3]]);if(2!=m.get(k)||3!=m.get(l))return!1;m.delete(k);m.set(l,4);return!m.has(k)&&4==m.get(l)}catch(p){return!1}}())return a;
+var g="$jscomp_hidden_"+Math.random();e("freeze");e("preventExtensions");e("seal");var f=0,h=function(k){this.M=(f+=Math.random()+1).toString();if(k){k=r(k);for(var l;!(l=k.next()).done;)l=l.value,this.set(l[0],l[1])}};h.prototype.set=function(k,l){if(!c(k))throw Error("Invalid WeakMap key");d(k);if(!u(k,g))throw Error("WeakMap key fail: "+k);k[g][this.M]=l;return this};h.prototype.get=function(k){return c(k)&&u(k,g)?k[g][this.M]:void 0};h.prototype.has=function(k){return c(k)&&u(k,g)&&u(k[g],this.M)};
+h.prototype.delete=function(k){return c(k)&&u(k,g)&&u(k[g],this.M)?delete k[g][this.M]:!1};return h});
+q("Map",function(a){if(function(){if(!a||"function"!=typeof a||!a.prototype.entries||"function"!=typeof Object.seal)return!1;try{var h=Object.seal({x:4}),k=new a(r([[h,"s"]]));if("s"!=k.get(h)||1!=k.size||k.get({x:4})||k.set({x:4},"t")!=k||2!=k.size)return!1;var l=k.entries(),m=l.next();if(m.done||m.value[0]!=h||"s"!=m.value[1])return!1;m=l.next();return m.done||4!=m.value[0].x||"t"!=m.value[1]||!l.next().done?!1:!0}catch(p){return!1}}())return a;var b=new WeakMap,c=function(h){this.L={};this.A=g();
+this.size=0;if(h){h=r(h);for(var k;!(k=h.next()).done;)k=k.value,this.set(k[0],k[1])}};c.prototype.set=function(h,k){h=0===h?0:h;var l=d(this,h);l.list||(l.list=this.L[l.id]=[]);l.j?l.j.value=k:(l.j={next:this.A,B:this.A.B,head:this.A,key:h,value:k},l.list.push(l.j),this.A.B.next=l.j,this.A.B=l.j,this.size++);return this};c.prototype.delete=function(h){h=d(this,h);return h.j&&h.list?(h.list.splice(h.index,1),h.list.length||delete this.L[h.id],h.j.B.next=h.j.next,h.j.next.B=h.j.B,h.j.head=null,this.size--,
+!0):!1};c.prototype.clear=function(){this.L={};this.A=this.A.B=g();this.size=0};c.prototype.has=function(h){return!!d(this,h).j};c.prototype.get=function(h){return(h=d(this,h).j)&&h.value};c.prototype.entries=function(){return e(this,function(h){return[h.key,h.value]})};c.prototype.keys=function(){return e(this,function(h){return h.key})};c.prototype.values=function(){return e(this,function(h){return h.value})};c.prototype.forEach=function(h,k){for(var l=this.entries(),m;!(m=l.next()).done;)m=m.value,
+h.call(k,m[1],m[0],this)};c.prototype[Symbol.iterator]=c.prototype.entries;var d=function(h,k){var l=k&&typeof k;"object"==l||"function"==l?b.has(k)?l=b.get(k):(l=""+ ++f,b.set(k,l)):l="p_"+k;var m=h.L[l];if(m&&u(h.L,l))for(h=0;h<m.length;h++){var p=m[h];if(k!==k&&p.key!==p.key||k===p.key)return{id:l,list:m,index:h,j:p}}return{id:l,list:m,index:-1,j:void 0}},e=function(h,k){var l=h.A;return fa(function(){if(l){for(;l.head!=h.A;)l=l.B;for(;l.next!=l.head;)return l=l.next,{done:!1,value:k(l)};l=null}return{done:!0,
+value:void 0}})},g=function(){var h={};return h.B=h.next=h.head=h},f=0;return c});q("Number.isFinite",function(a){return a?a:function(b){return"number"!==typeof b?!1:!isNaN(b)&&Infinity!==b&&-Infinity!==b}});var oa=function(a,b){a instanceof String&&(a+="");var c=0,d=!1,e={next:function(){if(!d&&c<a.length){var g=c++;return{value:b(g,a[g]),done:!1}}d=!0;return{done:!0,value:void 0}}};e[Symbol.iterator]=function(){return e};return e};
+q("Array.prototype.entries",function(a){return a?a:function(){return oa(this,function(b,c){return[b,c]})}});q("Number.isNaN",function(a){return a?a:function(b){return"number"===typeof b&&isNaN(b)}});
+q("Set",function(a){if(function(){if(!a||"function"!=typeof a||!a.prototype.entries||"function"!=typeof Object.seal)return!1;try{var c=Object.seal({x:4}),d=new a(r([c]));if(!d.has(c)||1!=d.size||d.add(c)!=d||1!=d.size||d.add({x:4})!=d||2!=d.size)return!1;var e=d.entries(),g=e.next();if(g.done||g.value[0]!=c||g.value[1]!=c)return!1;g=e.next();return g.done||g.value[0]==c||4!=g.value[0].x||g.value[1]!=g.value[0]?!1:e.next().done}catch(f){return!1}}())return a;var b=function(c){this.m=new Map;if(c){c=
+r(c);for(var d;!(d=c.next()).done;)this.add(d.value)}this.size=this.m.size};b.prototype.add=function(c){c=0===c?0:c;this.m.set(c,c);this.size=this.m.size;return this};b.prototype.delete=function(c){c=this.m.delete(c);this.size=this.m.size;return c};b.prototype.clear=function(){this.m.clear();this.size=0};b.prototype.has=function(c){return this.m.has(c)};b.prototype.entries=function(){return this.m.entries()};b.prototype.values=function(){return this.m.values()};b.prototype.keys=b.prototype.values;
+b.prototype[Symbol.iterator]=b.prototype.values;b.prototype.forEach=function(c,d){var e=this;this.m.forEach(function(g){return c.call(d,g,g,e)})};return b});q("Array.from",function(a){return a?a:function(b,c,d){c=null!=c?c:function(h){return h};var e=[],g="undefined"!=typeof Symbol&&Symbol.iterator&&b[Symbol.iterator];if("function"==typeof g){b=g.call(b);for(var f=0;!(g=b.next()).done;)e.push(c.call(d,g.value,f++))}else for(g=b.length,f=0;f<g;f++)e.push(c.call(d,b[f],f));return e}});
+q("Object.entries",function(a){return a?a:function(b){var c=[],d;for(d in b)u(b,d)&&c.push([d,b[d]]);return c}});q("Object.is",function(a){return a?a:function(b,c){return b===c?0!==b||1/b===1/c:b!==b&&c!==c}});q("Array.prototype.includes",function(a){return a?a:function(b,c){var d=this;d instanceof String&&(d=String(d));var e=d.length;c=c||0;for(0>c&&(c=Math.max(c+e,0));c<e;c++){var g=d[c];if(g===b||Object.is(g,b))return!0}return!1}});
+q("String.prototype.includes",function(a){return a?a:function(b,c){if(null==this)throw new TypeError("The 'this' value for String.prototype.includes must not be null or undefined");if(b instanceof RegExp)throw new TypeError("First argument to String.prototype.includes must not be a regular expression");return-1!==(this+"").indexOf(b,c||0)}});q("Array.prototype.values",function(a){return a?a:function(){return oa(this,function(b,c){return c})}});
+var pa=function(a){var b=typeof a;return"object"!=b?b:a?Array.isArray(a)?"array":b:"null"},qa=function(a,b){function c(){}c.prototype=b.prototype;a.za=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.Ca=function(d,e,g){for(var f=Array(arguments.length-2),h=2;h<arguments.length;h++)f[h-2]=arguments[h];return b.prototype[e].apply(d,f)}};function ra(a,b){if(Error.captureStackTrace)Error.captureStackTrace(this,ra);else{var c=Error().stack;c&&(this.stack=c)}a&&(this.message=String(a));void 0!==b&&(this.cause=b)}qa(ra,Error);ra.prototype.name="CustomError";function sa(a,b){a=a.split("%s");for(var c="",d=a.length-1,e=0;e<d;e++)c+=a[e]+(e<b.length?b[e]:"%s");ra.call(this,c+a[d])}qa(sa,ra);sa.prototype.name="AssertionError";function ta(a,b,c,d){var e="Assertion failed";if(c){e+=": "+c;var g=d}else a&&(e+=": "+a,g=b);throw new sa(""+e,g||[]);}
+var v=function(a,b,c){a||ta("",null,b,Array.prototype.slice.call(arguments,2));return a},ua=function(a,b,c){null==a&&ta("Expected to exist: %s.",[a],b,Array.prototype.slice.call(arguments,2));return a},va=function(a,b){throw new sa("Failure"+(a?": "+a:""),Array.prototype.slice.call(arguments,1));},w=function(a,b,c){Array.isArray(a)||ta("Expected array but got %s: %s.",[pa(a),a],b,Array.prototype.slice.call(arguments,2))},x=function(a,b,c,d){a instanceof b||ta("Expected instanceof %s but got %s.",
+[wa(b),wa(a)],c,Array.prototype.slice.call(arguments,3));return a};function wa(a){return a instanceof Function?a.displayName||a.name||"unknown type name":a instanceof Object?a.constructor.displayName||a.constructor.name||Object.prototype.toString.call(a):null===a?"null":typeof a};var xa={},ya=null,za=function(a){var b,c=pa(a);v("array"==c||"object"==c&&"number"==typeof a.length,"encodeByteArray takes an array as a parameter");void 0===b&&(b=0);if(!ya){ya={};c="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".split("");for(var d=["+/=","+/","-_=","-_.","-_"],e=0;5>e;e++){var g=c.concat(d[e].split(""));xa[e]=g;for(var f=0;f<g.length;f++){var h=g[f],k=ya[h];void 0===k?ya[h]=f:v(k===f)}}}b=xa[b];c=Array(Math.floor(a.length/3));d=b[64]||"";for(e=g=0;g<a.length-2;g+=
+3){k=a[g];var l=a[g+1];h=a[g+2];f=b[k>>2];k=b[(k&3)<<4|l>>4];l=b[(l&15)<<2|h>>6];h=b[h&63];c[e++]=""+f+k+l+h}f=0;h=d;switch(a.length-g){case 2:f=a[g+1],h=b[(f&15)<<2]||d;case 1:a=a[g],c[e]=""+b[a>>2]+b[(a&3)<<4|f>>4]+h+d}return c.join("")};var Aa="undefined"!==typeof Uint8Array,Ba={};var Ca,Da=function(a){if(Ba!==Ba)throw Error("illegal external caller");this.qa=a;if(null!=a&&0===a.length)throw Error("ByteString should be constructed with non-empty values");};v(!0);var Ea={};var z="function"===typeof Symbol&&"symbol"===typeof Symbol()?Symbol("INTERNAL_ARRAY_STATE"):void 0;function Fa(a,b){Object.isFrozen(a)||(z?a[z]|=b:void 0!==a.F?a.F|=b:Object.defineProperties(a,{F:{value:b,configurable:!0,writable:!0,enumerable:!1}}))}var Ga=Object.getOwnPropertyDescriptor(Array.prototype,"wa");
+Object.defineProperties(Array.prototype,{wa:{get:function(){var a=A(this),b=[];1&a&&b.push("IS_REPEATED_FIELD");2&a&&b.push("IS_IMMUTABLE_ARRAY");4&a&&b.push("IS_API_FORMATTED");8&a&&b.push("ONLY_MUTABLE_VALUES");a=b.join(",");return Ga?Ga.get.call(this)+"|"+a:a},configurable:!0,enumerable:!1}});function A(a){w(a,"state is only maintained on arrays.");a=z?a[z]:a.F;return null==a?0:a}function B(a){w(a,"state is only maintained on arrays.");Fa(a,1);return a}
+function C(a){return Array.isArray(a)?!!(A(a)&2):!1}function Ha(a){if(!Array.isArray(a))throw Error("cannot mark non-array as immutable");Fa(a,2)}function Ia(a,b){if(!Array.isArray(a))throw Error("cannot mark non-array as mutable");b?Fa(a,8):Object.isFrozen(a)||(z?a[z]&=-9:void 0!==a.F&&(a.F&=-9))};function Ja(a){return null!==a&&"object"===typeof a&&!Array.isArray(a)&&a.constructor===Object}var Ka=Symbol("exempted jspb subclass"),La=Symbol("generated by jspb"),Ma=Object.freeze(B([])),Na=function(a){if(C(a.g))throw Error("Cannot mutate an immutable Message");},Oa="undefined"!=typeof Symbol&&"undefined"!=typeof Symbol.hasInstance;function Pa(a){return{value:a,configurable:!1,writable:!1,enumerable:!1}};function Qa(a){return a.displayName||a.name||"unknown type name"}function Ra(a,b){if(!(a instanceof b))throw Error("Expected instanceof "+Qa(b)+" but got "+(a&&Qa(a.constructor)));return a}function Sa(a,b,c){c=void 0===c?!1:c;if(Array.isArray(a))return new b(a);if(c)return new b};var Ta=function(){throw Error("please construct maps as mutable then call toImmutable");};if(Oa){var Ua=function(){throw Error("Cannot perform instanceof checks on ImmutableMap");},Va={};Object.defineProperties(Ta,(Va[Symbol.hasInstance]=Pa(Ua),Va));v(Ta[Symbol.hasInstance]===Ua,"defineProperties did not work: was it monkey-patched?")};function Wa(a){switch(typeof a){case "number":return isFinite(a)?a:String(a);case "object":if(a&&!Array.isArray(a)){if(Aa&&null!=a&&a instanceof Uint8Array)return za(a);if(a instanceof Da){var b=a.qa;null!=b&&"string"!==typeof b&&(Aa&&b instanceof Uint8Array?b=za(b):(va("Cannot coerce to b64 string: "+pa(b)),b=null));return null==b?"":a.qa=b}}}return a};function Xa(a,b){b=void 0===b?Ya:b;w(a);return Za(a,b)}function $a(a,b){if(null!=a){if(Array.isArray(a))a=Za(a,b);else if(Ja(a)){var c={},d;for(d in a)c[d]=$a(a[d],b);a=c}else a=b(a);return a}}function Za(a,b){w(a);for(var c=a.slice(),d=0;d<c.length;d++)c[d]=$a(c[d],b);Array.isArray(a)&&A(a)&1&&B(c);return c}function ab(a){if(a&&"object"==typeof a&&a.toJSON)return a.toJSON();a=Wa(a);return Array.isArray(a)?Xa(a,ab):a}function Ya(a){return Aa&&null!=a&&a instanceof Uint8Array?new Uint8Array(a):a};var bb=function(a){return a.C||(a.C=a.g[a.G+a.D]={})},D=function(a,b,c){return-1===b?null:b>=a.G?a.C?a.C[b]:void 0:(void 0===c?0:c)&&a.C&&(c=a.C[b],null!=c)?c:a.g[b+a.D]},E=function(a,b,c,d,e){d=void 0===d?!1:d;(void 0===e?0:e)||Na(a);b<a.G&&!d?a.g[b+a.D]=c:bb(a)[b]=c},F=function(a,b,c,d){c=void 0===c?!0:c;var e=D(a,b,d);Array.isArray(e)||(e=Ma);if(C(a.g))c&&(Ha(e),Object.freeze(e));else if(e===Ma||C(e))e=B(e.slice()),E(a,b,e,d);return e},G=function(a,b){var c=Number,d=F(a,b,!1),e;if(e=d.length)e=
+d,w(e,"state is only maintained on arrays."),e=!(A(e)&4);if(e){Object.isFrozen(d)&&(d=B(d.slice()),E(a,b,d,void 0,!0));for(b=0;b<d.length;b++)d[b]=c(d[b]);c=d;w(c,"state is only maintained on arrays.");Fa(c,5)}C(a.g)&&Object.freeze(d);return d},I=function(a,b,c){a=D(a,b);return null==a?c:a},J=function(a,b){a=D(a,b);a=null==a?a:!!a;return null==a?!1:a},L=function(a,b){a=D(a,b);a=null==a?a:+a;return null==a?0:a};function M(a,b,c){Na(a);0!==c?E(a,b,c):E(a,b,void 0,!1);return a}
+var N=function(a,b,c,d,e){e=void 0===e?!1:e;var g=e;if(-1===c)d=null;else{a.h||(a.h={});var f=a.h[c];if(f)d=f;else{var h=D(a,c,g);b=Sa(h,b,d);void 0==b?d=f:(d&&b.g!==h&&E(a,c,b.g,g,!0),a.h[c]=b,C(a.g)&&Ha(b.g),d=b)}}if(null==d)return d;C(d.g)&&!C(a.g)&&(d=d.fa(Ea),E(a,c,d.g,e),a.h[c]=d);return d},O=function(a,b,c,d){d=void 0===d?!1:d;var e=C(a.g),g=d,f=e;f=void 0===f?!0:f;a.h||(a.h={});var h=C(a.g);var k=a.h[c];g=F(a,c,!0,g);var l=h||C(g);if(!k){k=[];h=h||l;for(var m=0;m<g.length;m++){var p=g[m];
+h=h||C(p);p=Sa(p,b);void 0!==p&&(k.push(p),l&&Ha(p.g))}a.h[c]=k;Ia(g,!h)}b=l||f;f=C(k);b&&!f&&(Object.isFrozen(k)&&(a.h[c]=k=k.slice()),Ha(k),Object.freeze(k));!b&&f&&(a.h[c]=k=k.slice());a=F(a,c,d);if(!(c=e)&&(c=a)){if(!Array.isArray(a))throw Error("cannot check mutability state of non-array");c=!(A(a)&8)}if(c){for(c=0;c<k.length;c++)(d=k[c])&&C(d.g)&&!e&&(k[c]=k[c].fa(Ea),a[c]=k[c].g);Ia(a,!0)}return k},cb=function(a,b,c,d){Na(a);a.h||(a.h={});b=null!=d?Ra(d,ua(b)).g:d;a.h[c]=d;E(a,c,b)},P=function(a,
+b){return I(a,b,"0")};var Q=function(a,b,c){x(this,Q,"The message constructor should only be used by subclasses");v(this.constructor!==Q,"Message is an abstract class and cannot be directly constructed");if(!0!==this[Ka]){v(!0===this[La],"Message can only be subclassed by proto gencode.");var d=Object.getPrototypeOf(v(Object.getPrototypeOf(this)));v(d.hasOwnProperty(La),"Generated jspb classes should not be extended")}a||(a=db);db=null;d=this.constructor.Ia;a||(a=d?[d]:[]);this.D=(d?0:-1)-(this.constructor.Ga||0);this.h=
+void 0;this.g=a;a:{d=this.g.length;a=d-1;if(d&&(d=this.g[a],Ja(d))){this.G=a-this.D;this.C=d;break a}void 0!==b&&-1<b?(this.G=Math.max(b,a+1-this.D),this.C=void 0):this.G=Number.MAX_VALUE}if(c)for(b=0;b<c.length;b++)if(a=c[b],a<this.G)a+=this.D,(d=this.g[a])?Array.isArray(d)&&B(d):this.g[a]=Ma;else{d=bb(this);var e=d[a];e?Array.isArray(e)&&B(e):d[a]=Ma}};n=Q.prototype;n.toJSON=function(){return Xa(this.g,ab)};n.getExtension=function(a){x(this,a.va);return a.Ea(x(this,Q))};
+n.hasExtension=function(a){x(this,a.va);v(!a.Ha,"repeated extensions don't support hasExtension");var b=x(this,Q);return null!=D(b,a.Da)};n.clone=function(){var a=x(this,Q),b=Xa(a.g);x(a,Q);w(b);db=b;b=new a.constructor(b);x(b,Q);db=null;eb(b,a);return b};n.toString=function(){return this.g.toString()};
+function eb(a,b){v(a,"expected `to` to be non-null");v(b,"expected `from` to be non-null");b.N&&(a.N=b.N.slice());var c=b.h;if(c){b=b.C;for(var d in c){var e=c[d];if(e){var g=!(!b||!b[d]),f=+d;if(Array.isArray(e)){if(e.length)for(g=O(a,e[0].constructor,f,g),f=0;f<Math.min(g.length,e.length);f++)eb(g[f],x(e[f],Q))}else x(e,Q),(g=N(a,e.constructor,f,void 0,g))&&eb(g,e)}}}}var db;var fb=function(){Q.call(this,void 0);throw Error("ImmutableMessage is not instantiable");};t(fb,Q);fb.prototype.clone=function(){return Q.prototype.clone.call(this)};if(Oa){var gb=function(){throw Error("Cannot perform instanceof checks for MutableMessage");},hb={};Object.defineProperties(fb,(hb[Symbol.hasInstance]=Pa(gb),hb));v(fb[Symbol.hasInstance]===gb,"broken defineProperties implementation")};var R=function(){Q.apply(this,arguments)};t(R,Q);R.prototype.fa=function(){return this};if(Oa){var ib=function(){throw Error("Cannot perform instanceof checks for MutableMessage");},jb={};Object.defineProperties(R,(jb[Symbol.hasInstance]=Pa(ib),jb));v(R[Symbol.hasInstance]===ib,"defineProperties did not work: was it monkey-patched?")};function kb(a,b,c,d,e,g){if(a=a.h&&a.h[c])if(Array.isArray(a)){e=g.ba?B(a.slice()):a;g=0<e.length?e[0].constructor:void 0;Na(b);if(null!=e){w(e);d=B([]);a=!1;for(var f=0;f<e.length;f++)d[f]=Ra(e[f],ua(g)).g,a=a||C(d[f]);b.h||(b.h={});b.h[c]=e;Ia(d,!a)}else b.h&&(b.h[c]=void 0),d=Ma;E(b,c,d)}else cb(b,a.constructor,c,x(a,Q));else Aa&&d instanceof Uint8Array?(e=d,x(e,Uint8Array),e=e.length?new Da(new Uint8Array(e)):Ca||(Ca=new Da(null))):(Array.isArray(d)&&(e?Ha(d):Array.isArray(d)&&A(d)&1&&g.ba&&(d=
+d.slice())),e=d),E(b,c,e)};var S=function(){R.apply(this,arguments)};t(S,R);
+S.prototype.fa=function(a){if(a!==Ea)throw Error("requires a valid immutable API token");if(C(this.g)){x(this,Q);a={ba:!0};var b=C(this.g);if(b&&!a.ba)throw Error("copyRepeatedFields must be true for frozen messages");var c=new this.constructor;this.N&&(c.N=this.N.slice());for(var d=this.g,e=0;e<d.length;e++){var g=d[e];if(e===d.length-1&&Ja(g))for(h in g){var f=+h;Number.isNaN(f)?bb(c)[h]=g[h]:kb(this,c,f,g[h],b,a)}else kb(this,c,e-this.D,g,b,a)}var h=c}else h=this;return h};S.prototype[La]=!0;
+if(Oa){var lb={};Object.defineProperties(S,(lb[Symbol.hasInstance]=Pa(Object[Symbol.hasInstance]),lb));v(S[Symbol.hasInstance]===Object[Symbol.hasInstance],"broken defineProperties implementation")};var mb=void 0;function nb(a){var b=mb;mb=void 0;var c=[],d=ob(a,c);if(!d&&c){var e="Expected Array<unknown>, got "+pb(a);c.push(e)}if(!d)throw a="",b&&(a=b()+"\n"),Error(a+"Guard Array<unknown> failed:\n"+c.reverse().join("\n"));return a}
+function pb(a,b){b=void 0===b?new Set:b;if(b.has(a))return"(Recursive reference)";switch(typeof a){case "object":if(a){var c=Object.getPrototypeOf(a);switch(c){case Map.prototype:case Set.prototype:case Array.prototype:b.add(a);var d="["+Array.from(a,function(e){return pb(e,b)}).join(", ")+"]";b.delete(a);c!==Array.prototype&&(d=qb(c.constructor)+"("+d+")");return d;case Object.prototype:return b.add(a),c="{"+Object.entries(a).map(function(e){var g=r(e);e=g.next().value;g=g.next().value;return e+
+": "+pb(g,b)}).join(", ")+"}",b.delete(a),c;default:return d="Object",c&&c.constructor&&(d=qb(c.constructor)),"function"===typeof a.toString&&a.toString!==Object.prototype.toString?d+"("+String(a)+")":"(object "+d+")"}}break;case "function":return"function "+qb(a);case "number":if(!Number.isFinite(a))return String(a);break;case "bigint":return a.toString(10)+"n"}return JSON.stringify(a)}function qb(a){var b=a.name;b||(b=(a=/function\s+([^\(]+)/m.exec(String(a)))?a[1]:"(Anonymous)");return b};var ob=function(a){a.Fa=function(){return"Array<unknown>"};return a}(function(a){return Array.isArray(a)});var rb=[[[["1646440773",[-.21289063,-.014526367,-.0046081543,-.013671875,-.012451172,.056152344,-.05029297,-.15234375,-.044677734,-.29101563,-.099121094,.0014190674,.08496094,.078125,-.009765625,-.09765625,-.045166016,.09765625,-.022583008,.23242188,-.04321289,.0126953125,.032226563,.064941406,.36132813,-.09716797,.28515625,.0074768066,-.11279297,-.0625,.012329102,-.076171875]]],[["1646451678",[-.18652344,.15917969,-.005340576,.055664063,.041015625,-.010253906,.06591797,-.071777344,.024536133,1.828125,
+-.19140625,-.35351563,.13671875,.45117188,.12792969,-.03466797,.18261719,.19628906,.14160156,.17480469,-.04638672,-.06689453,-.30273438,.35351563,-.33789063,-.7578125,-.17675781,.05810547,-.002029419,.005279541,-.025756836,.15234375]]]],null,[1],"CMb9tKfcrvYCFawfBgAdboELOQ",null,[null,null,null,1,[]],[null,null,null,null,[]]];var sb={"1j115753478":[[["52836427830","310927197294","4",[[["1643849995",[3.09375,.8203125,1.4765625,-.55078125,1.9140625,-.78125,-1.1640625,-3.15625,1.25,3.421875,1.6484375,1.0625,4.96875,-.66796875,-1.4375,.87109375,1.6171875,-4.125,-2.375,3.421875,-2.359375,1.6015625,.625,-4.65625,-5.03125,.416015625,-4.03125,-.24609375,3.296875,-.052001953125,-3.75,3.765625]],["1643804092",[3.09375,.796875,1.46875,-.56640625,1.890625,-.76953125,-1.1484375,-3.140625,1.2109375,3.421875,1.625,1.046875,4.9375,-.65234375,
+-1.421875,.84765625,1.6015625,-4.125,-2.359375,3.453125,-2.34375,1.5859375,.63671875,-4.65625,-5,.396484375,-4.03125,-.26171875,3.296875,-.068359375,-3.734375,3.75]]],null,[["1643822293",[-.039794921875,.035400390625,.357421875,.041748046875,.0054931640625,-.060791015625,.138671875,-.318359375,.2255859375,.10546875,.2099609375,-.240234375,-.07373046875,-.279296875,-.44140625,.015380859375,-.298828125,.119140625,-.09716796875,.1796875,.04248046875,.09033203125,.38671875,.412109375,-.357421875,.259765625,
+-.24609375,-.3828125,.33984375,.07861328125,-.1259765625,.3046875]],["1643799063",[.0079345703125,.0546875,.353515625,.00958251953125,-.01318359375,-.10888671875,.13671875,-.373046875,.208984375,.09228515625,.1962890625,-.248046875,-.031494140625,-.2734375,-.42578125,.0035400390625,-.345703125,.1083984375,-.068359375,.173828125,.0810546875,.1162109375,.361328125,.451171875,-.3671875,.162109375,-.212890625,-.46484375,.337890625,.1083984375,-.177734375,.318359375]]],null,null,null,null,[[null,[318.3513488769531,
+1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["52836427830","310927197297","4",[[["1643849995",[3.125,.953125,1.484375,-.46875,2.109375,-.89453125,-1.265625,-3.15625,1.265625,3.421875,1.7578125,1.1796875,4.9375,-.6796875,-1.5234375,.953125,1.7734375,-4.125,-2.453125,3.4375,-2.375,1.6328125,.3984375,-4.375,-4.96875,.59375,-4.03125,-.08935546875,3.34375,.1806640625,-3.8125,3.796875]],["1643804092",[3.125,.90625,1.4609375,-.5,2.046875,-.8671875,
+-1.234375,-3.140625,1.2265625,3.421875,1.71875,1.1328125,4.90625,-.65625,-1.4921875,.921875,1.734375,-4.125,-2.421875,3.46875,-2.34375,1.6015625,.4296875,-4.375,-4.9375,.55078125,-4.03125,-.123046875,3.328125,.1416015625,-3.78125,3.765625]]],null,[["1643822293",[-.060546875,.0185546875,.353515625,.02587890625,.00311279296875,-.07421875,.1533203125,-.3203125,.2470703125,.06689453125,.193359375,-.234375,.029296875,-.255859375,-.44921875,.0146484375,-.306640625,.11962890625,-.10498046875,.1865234375,
+.049072265625,.1162109375,.365234375,.42578125,-.359375,.26953125,-.2490234375,-.392578125,.306640625,.1103515625,-.1376953125,.310546875]],["1643799063",[-.015869140625,.02978515625,.337890625,-.00628662109375,-.0169677734375,-.12353515625,.1494140625,-.373046875,.232421875,.056640625,.1806640625,-.2353515625,.0966796875,-.2451171875,-.43359375,.004180908203125,-.353515625,.107421875,-.087890625,.1865234375,.087890625,.138671875,.345703125,.455078125,-.36328125,.181640625,-.224609375,-.486328125,
+.294921875,.13671875,-.19921875,.3203125]]],null,null,null,null,[[null,[318.3513488769531,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["52836427830","310927197300","4",[[["1643849995",[3.109375,.99609375,1.59375,-.4609375,2.171875,-.91015625,-1.296875,-3.3125,1.3984375,3.4375,1.8046875,1.2578125,5.09375,-.7421875,-1.59375,1.0078125,1.8125,-4.1875,-2.578125,3.390625,-2.53125,1.765625,.54296875,-4.71875,-5.09375,.55859375,-4.09375,-.1318359375,
+3.328125,.0654296875,-3.890625,3.859375]],["1643804092",[3.109375,.953125,1.5703125,-.48828125,2.109375,-.88671875,-1.2734375,-3.296875,1.359375,3.4375,1.7734375,1.21875,5.0625,-.71875,-1.5625,.9765625,1.7734375,-4.1875,-2.53125,3.4375,-2.5,1.734375,.5703125,-4.71875,-5.0625,.5234375,-4.0625,-.1591796875,3.328125,.03515625,-3.84375,3.828125]]],null,[["1643822293",[-.048095703125,.0179443359375,.36328125,.033203125,.030029296875,-.07568359375,.15625,-.326171875,.224609375,.07568359375,.1787109375,
+-.234375,-.0277099609375,-.265625,-.412109375,.00909423828125,-.3046875,.11865234375,-.103515625,.1767578125,.048095703125,.12158203125,.36328125,.421875,-.359375,.255859375,-.25,-.396484375,.29296875,.10205078125,-.1279296875,.318359375]],["1643799063",[-.0045166015625,.03173828125,.353515625,.003631591796875,.00927734375,-.126953125,.154296875,-.37890625,.208984375,.06689453125,.1708984375,-.234375,.03173828125,-.255859375,-.396484375,-.00384521484375,-.353515625,.10693359375,-.0830078125,.1708984375,
+.08935546875,.1474609375,.341796875,.44921875,-.3671875,.1669921875,-.224609375,-.482421875,.28125,.130859375,-.1796875,.326171875]]],null,null,null,null,[[null,[318.3513488769531,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]]]],"1j380357233":[[["52836427830","310927197294","4",[[["1643849995",[4.53125,1.8671875,.13671875,3.3125,-7.5625,.546875,2.953125,-7.90625,4.71875,7.375,.0047607421875,-3.25,.74609375,.298828125,-1.34375,-2.4375,-6.34375,
+-9.1875,-1.3359375,9.875,1.1796875,-3.15625,3.796875,-6.90625,-3.203125,-.09375,-7.65625,-.71875,4.65625,-.75390625,-6.28125,3.6875]],["1643804092",[4.53125,1.9453125,.19140625,3.40625,-7.53125,.52734375,2.9375,-7.9375,4.625,7.375,.01416015625,-3.25,.74609375,.28125,-1.34375,-2.484375,-6.34375,-9.25,-1.328125,9.9375,1.2421875,-3.171875,3.71875,-6.71875,-3.21875,-.0311279296875,-7.71875,-.69140625,4.65625,-.70703125,-6.40625,3.71875]]],null,[["1643822293",[-.09033203125,.037109375,.423828125,.0439453125,
+.0390625,-.04345703125,.162109375,-.3125,.2197265625,.06884765625,.25,-.240234375,-.07763671875,-.267578125,-.416015625,.0150146484375,-.2890625,.126953125,-.08740234375,.158203125,.035888671875,.130859375,.3515625,.412109375,-.38671875,.27734375,-.234375,-.408203125,.337890625,.0458984375,-.1328125,.36328125]],["1643799063",[-.044921875,.056640625,.3984375,.0162353515625,.01373291015625,-.08544921875,.1611328125,-.359375,.1982421875,.06298828125,.2421875,-.2421875,-.05078125,-.263671875,-.39453125,
+.001953125,-.33203125,.11767578125,-.060546875,.1513671875,.07080078125,.14453125,.3359375,.4453125,-.388671875,.1865234375,-.1904296875,-.48046875,.3359375,.0693359375,-.177734375,.37109375]]],null,null,null,null,[[null,[318.3513488769531,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["52836427830","310927197297","4",[[["1643849995",[4.4375,1.90625,.20703125,3.125,-7.03125,.44140625,2.703125,-7.46875,4.5,7.1875,.080078125,-3.03125,.94140625,
+.25390625,-1.3203125,-2.25,-5.875,-8.875,-1.375,9.4375,1.0234375,-2.984375,3.453125,-6.46875,-3.171875,.007781982421875,-7.4375,-.62890625,4.5625,-.58984375,-6.125,3.609375]],["1643804092",[4.46875,1.9765625,.26171875,3.1875,-6.9375,.41015625,2.671875,-7.53125,4.375,7.21875,.09716796875,-3.015625,1.0078125,.232421875,-1.3203125,-2.28125,-5.84375,-8.875,-1.3828125,9.5625,1.0859375,-2.96875,3.359375,-6.3125,-3.234375,.06494140625,-7.5,-.6171875,4.5625,-.53125,-6.28125,3.703125]]],null,[["1643822293",
+[-.107421875,.017822265625,.427734375,.0274658203125,.0289306640625,-.05908203125,.17578125,-.31640625,.2373046875,.033447265625,.2470703125,-.23046875,.00579833984375,-.25,-.421875,.01385498046875,-.298828125,.1240234375,-.09912109375,.16796875,.036865234375,.1435546875,.33984375,.4296875,-.380859375,.28515625,-.232421875,-.427734375,.3125,.0654296875,-.1513671875,.373046875]],["1643799063",[-.07177734375,.024658203125,.396484375,-.0016937255859375,.01434326171875,-.11328125,.1748046875,-.3671875,
+.2255859375,.026611328125,.224609375,-.2197265625,.07470703125,-.232421875,-.396484375,.01507568359375,-.341796875,.11376953125,-.087890625,.16015625,.072265625,.173828125,.3203125,.44921875,-.3828125,.19921875,-.2080078125,-.5078125,.28125,.1044921875,-.21484375,.380859375]]],null,null,null,null,[[null,[318.3513488769531,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["52836427830","310927197300","4",[[["1643849995",[4.5,1.96875,.2099609375,
+3.328125,-7.28125,.458984375,2.8125,-7.84375,4.84375,7.3125,.09814453125,-3.078125,.859375,.224609375,-1.4296875,-2.3125,-6.09375,-9.125,-1.4453125,9.75,1.0078125,-3,3.71875,-6.90625,-3.203125,-.04931640625,-7.5625,-.6328125,4.625,-.69140625,-6.25,3.671875]],["1643804092",[4.5,2.09375,.298828125,3.453125,-7.1875,.416015625,2.765625,-7.90625,4.75,7.3125,.1318359375,-3.046875,.9140625,.17578125,-1.4453125,-2.328125,-6.0625,-9.125,-1.46875,9.75,1.046875,-2.984375,3.59375,-6.6875,-3.25,.041015625,-7.625,
+-.5859375,4.625,-.6171875,-6.40625,3.75]]],null,[["1643822293",[-.09765625,.0216064453125,.421875,.03955078125,.056396484375,-.0546875,.1767578125,-.31640625,.208984375,.04248046875,.2265625,-.2314453125,-.0419921875,-.2578125,-.3828125,.0084228515625,-.29296875,.123046875,-.09423828125,.1533203125,.0380859375,.1474609375,.333984375,.4140625,-.384765625,.275390625,-.232421875,-.4140625,.291015625,.06591796875,-.1337890625,.376953125]],["1643799063",[-.0673828125,.03271484375,.41796875,.01336669921875,
+.041748046875,-.10595703125,.1767578125,-.37109375,.1982421875,.0294189453125,.212890625,-.2275390625,.02880859375,-.248046875,-.361328125,.00909423828125,-.337890625,.115234375,-.0732421875,.14453125,.07080078125,.1875,.310546875,.4453125,-.39453125,.1875,-.203125,-.5078125,.26953125,.095703125,-.1962890625,.40625]]],null,null,null,null,[[null,[318.3513488769531,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["31279674038","113383149038",
+null,[[["1643849995",[7.875,2.375,-3.078125,9.8125,-20.875,2.46875,9.1875,-18.25,10,13.0625,-1.1171875,-8.875,-6.9375,2.078125,-2.1875,-7.34375,-17.375,-19.375,.640625,21.375,7.0625,-9.875,7.875,-9.5625,-2.09375,.034423828125,-13.4375,-.3359375,8.5625,-.75390625,-11.375,6.15625]],["1643804092",[7.875,2.4375,-3.015625,10,-20.75,2.453125,9.1875,-18.25,9.6875,13,-1.1484375,-8.9375,-6.875,2.078125,-2.125,-7.4375,-17.5,-19.25,.71875,21.25,7.3125,-9.9375,7.65625,-9.125,-2.171875,.1513671875,-13.5625,-.34765625,
+8.5625,-.69921875,-11.6875,6.28125]]],null,[["1643822293",[-.337890625,-.1884765625,.1923828125,-.0213623046875,-.1953125,.5234375,.326171875,.0908203125,-.09033203125,.019775390625,.40234375,.462890625,-.19921875,-.08642578125,-.29296875,-.1943359375,.248046875,-.2470703125,-.2099609375,.2353515625,.0400390625,.1767578125,.828125,-.059326171875,-.0218505859375,.5703125,-.431640625,-.30859375,.19921875,.1455078125,-.486328125,-.2578125]],["1643799063",[-.37109375,-.1455078125,.361328125,-.0595703125,
+-.1611328125,.5234375,.3203125,.07568359375,-.0791015625,.03173828125,.423828125,.4609375,-.2412109375,-.09130859375,-.310546875,-.193359375,.232421875,-.2353515625,-.19140625,.2177734375,.0205078125,.232421875,.8359375,-.04150390625,-.045166015625,.55078125,-.451171875,-.412109375,.298828125,.1220703125,-.56640625,-.11767578125]]],null,null,null,null,[[null,[176.8618621826172,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["31279674038",
+"113383149158",null,[[["1643849995",[8.1875,2.0625,-3.328125,9.5,-21.125,2.609375,9.3125,-17.875,9.5,13.375,-1.2578125,-9.1875,-7,2.265625,-1.9140625,-7.5,-17.625,-19.5,.953125,21.375,7.46875,-10.3125,7.65625,-9.125,-2.265625,.02490234375,-13.75,-.4375,8.8125,-.59765625,-11.4375,6.40625]],["1643804092",[8.125,2.140625,-3.25,9.6875,-21.125,2.59375,9.3125,-17.875,9.25,13.25,-1.25,-9.1875,-6.90625,2.234375,-1.8671875,-7.5625,-17.625,-19.5,1.0078125,21.25,7.625,-10.375,7.5,-8.8125,-2.359375,.1494140625,
+-13.75,-.458984375,8.75,-.5625,-11.6875,6.5]]],null,[["1643822293",[-.349609375,-.19140625,.1767578125,-.0213623046875,-.197265625,.5234375,.330078125,.0927734375,-.0908203125,.027587890625,.3984375,.462890625,-.2001953125,-.0810546875,-.296875,-.19140625,.2490234375,-.244140625,-.2119140625,.2392578125,.0400390625,.181640625,.828125,-.05859375,-.0181884765625,.5703125,-.4296875,-.302734375,.1982421875,.1494140625,-.490234375,-.263671875]],["1643799063",[-.369140625,-.1435546875,.353515625,-.05908203125,
+-.1552734375,.515625,.322265625,.0703125,-.07177734375,.04345703125,.421875,.45703125,-.248046875,-.08935546875,-.30859375,-.1953125,.2255859375,-.2333984375,-.1943359375,.220703125,.021484375,.2431640625,.83984375,-.0419921875,-.04052734375,.54296875,-.443359375,-.41015625,.30078125,.11767578125,-.5703125,-.12158203125]]],null,null,null,null,[[null,[176.8618621826172,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["31279674038","113383149518",
+null,[[["1643849995",[7.71875,2.21875,-2.984375,9.3125,-20.25,2.40625,8.875,-17.375,9.5,12.75,-1.1015625,-8.6875,-6.53125,2.03125,-2.03125,-7.09375,-16.875,-18.625,.61328125,20.625,6.84375,-9.625,7.625,-9.3125,-2.140625,-.0341796875,-13.125,-.435546875,8.375,-.8046875,-11.0625,6]],["1643804092",[7.65625,2.328125,-2.875,9.5,-20.125,2.375,8.8125,-17.375,9.3125,12.625,-1.09375,-8.625,-6.46875,1.9921875,-2.015625,-7.125,-16.875,-18.625,.671875,20.5,7,-9.625,7.4375,-8.9375,-2.15625,.1357421875,-13.125,
+-.4140625,8.25,-.73046875,-11.25,6.0625]]],null,[["1643822293",[-.34765625,-.193359375,.208984375,-.025390625,-.201171875,.5234375,.330078125,.09326171875,-.09423828125,.0084228515625,.41015625,.46484375,-.1767578125,-.08251953125,-.310546875,-.19140625,.25,-.24609375,-.212890625,.2392578125,.0380859375,.17578125,.828125,-.0576171875,-.01904296875,.578125,-.43359375,-.31640625,.2060546875,.14453125,-.4921875,-.255859375]],["1643799063",[-.369140625,-.150390625,.37890625,-.0546875,-.1630859375,.53125,
+.3203125,.08251953125,-.08447265625,.01318359375,.43359375,.462890625,-.2392578125,-.09619140625,-.310546875,-.189453125,.2421875,-.2333984375,-.1953125,.2119140625,.0142822265625,.23046875,.83203125,-.0284423828125,-.047119140625,.55078125,-.447265625,-.427734375,.306640625,.115234375,-.57421875,-.107421875]]],null,null,null,null,[[null,[176.8618621826172,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]]]],"1j395640136":[[["31279674038","113383149038",
+null,[[["1643849995",[3.34375,.197265625,.66015625,-.796875,1.1015625,-.5546875,-.78515625,-2.21875,.84765625,3.390625,1.28125,.482421875,3.9375,-.1865234375,-1.09375,.609375,1.1484375,-4.0625,-1.7890625,4.5625,-1.859375,.83203125,.64453125,-4,-4.09375,.02587890625,-3.734375,-.31640625,3.65625,-.025146484375,-2.5625,3.03125]],["1643804092",[3.34375,.177734375,.6484375,-.8125,1.078125,-.54296875,-.76953125,-2.203125,.81640625,3.40625,1.265625,.462890625,3.9375,-.171875,-1.078125,.59375,1.125,-4.09375,
+-1.7734375,4.59375,-1.8359375,.8203125,.65625,-3.984375,-4.09375,.0101318359375,-3.75,-.33203125,3.671875,-.039794921875,-2.546875,3.015625]]],null,[["1643822293",[-.345703125,-.1962890625,.2109375,-.034912109375,-.2158203125,.5234375,.3359375,.09619140625,-.09326171875,.01385498046875,.427734375,.474609375,-.1806640625,-.0771484375,-.3203125,-.2060546875,.2451171875,-.2578125,-.2177734375,.2490234375,.035888671875,.1513671875,.84375,-.04638671875,-.01220703125,.5703125,-.439453125,-.32421875,.2138671875,
+.1513671875,-.50390625,-.263671875]],["1643799063",[-.3828125,-.1494140625,.384765625,-.058837890625,-.1826171875,.53125,.322265625,.0859375,-.08837890625,.0159912109375,.458984375,.462890625,-.2275390625,-.08984375,-.328125,-.1962890625,.23828125,-.23828125,-.189453125,.22265625,.01556396484375,.2109375,.83203125,-.0238037109375,-.044677734375,.55859375,-.453125,-.43359375,.31640625,.12158203125,-.57421875,-.11328125]]],null,null,null,null,[[null,[176.8618621826172,1],[1,2],[1,1],null,3]]],[null,
+[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["31279674038","113383149158",null,[[["1643849995",[3.34375,.130859375,.62109375,-.84765625,.98046875,-.453125,-.68359375,-2.03125,.51953125,3.453125,1.140625,.291015625,3.96875,-.15625,-.8828125,.435546875,1.0078125,-4,-1.515625,4.15625,-1.5234375,.62890625,.37890625,-3.421875,-4.21875,.1220703125,-3.84375,-.345703125,3.5625,.10791015625,-2.828125,3.25]],["1643804092",[3.34375,.130859375,.62109375,-.8515625,.98046875,-.451171875,
+-.68359375,-2.03125,.50390625,3.453125,1.1328125,.287109375,3.96875,-.1533203125,-.875,.427734375,1.0078125,-4,-1.5078125,4.15625,-1.515625,.625,.369140625,-3.390625,-4.21875,.1259765625,-3.84375,-.34765625,3.5625,.11181640625,-2.828125,3.25]]],null,[["1643822293",[-.3515625,-.1982421875,.185546875,-.027099609375,-.21875,.5234375,.333984375,.099609375,-.09423828125,.0244140625,.42578125,.47265625,-.1845703125,-.0751953125,-.314453125,-.2001953125,.2470703125,-.25390625,-.216796875,.248046875,.036865234375,
+.1533203125,.83984375,-.044189453125,-.00933837890625,.5703125,-.43359375,-.31640625,.212890625,.15625,-.5,-.275390625]],["1643799063",[-.38671875,-.138671875,.375,-.061767578125,-.177734375,.5234375,.3203125,.07666015625,-.080078125,.033447265625,.4453125,.447265625,-.2333984375,-.09130859375,-.333984375,-.19921875,.2265625,-.2275390625,-.18359375,.2255859375,.02197265625,.2197265625,.828125,-.0189208984375,-.047119140625,.55078125,-.44140625,-.4296875,.328125,.11962890625,-.5703125,-.11572265625]]],
+null,null,null,null,[[null,[176.8618621826172,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["31279674038","113383149518",null,[[["1643849995",[3.21875,.1484375,.6796875,-.8203125,1,-.486328125,-.73046875,-2.21875,.77734375,3.3125,1.1875,.419921875,3.875,-.1904296875,-1.015625,.52734375,1.046875,-3.984375,-1.7265625,4.46875,-1.8046875,.828125,.7421875,-4.03125,-4.0625,-.07080078125,-3.671875,-.3984375,3.53125,-.1494140625,-2.515625,2.953125]],
+["1643804092",[3.21875,.1416015625,.671875,-.828125,1,-.486328125,-.73046875,-2.21875,.75390625,3.3125,1.1796875,.416015625,3.890625,-.1796875,-1.015625,.51953125,1.046875,-3.984375,-1.71875,4.5,-1.7890625,.8203125,.73046875,-4,-4.0625,-.06640625,-3.6875,-.3984375,3.53125,-.142578125,-2.53125,2.96875]]],null,[["1643822293",[-.349609375,-.19921875,.2109375,-.03173828125,-.2158203125,.53515625,.333984375,.10400390625,-.11181640625,.00836181640625,.431640625,.4765625,-.16796875,-.07568359375,-.32421875,
+-.201171875,.25390625,-.26171875,-.21875,.251953125,.032958984375,.142578125,.83984375,-.05126953125,-.00836181640625,.58203125,-.439453125,-.31640625,.21875,.1513671875,-.498046875,-.267578125]],["1643799063",[-.376953125,-.1513671875,.38671875,-.061279296875,-.1875,.53125,.322265625,.08642578125,-.08935546875,.01324462890625,.45703125,.462890625,-.224609375,-.08984375,-.333984375,-.19921875,.23828125,-.240234375,-.1962890625,.2197265625,.01519775390625,.2041015625,.8359375,-.0179443359375,-.041748046875,
+.5546875,-.451171875,-.43359375,.3203125,.123046875,-.578125,-.11962890625]]],null,null,null,null,[[null,[176.8618621826172,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]]]],"1j396781473":[[["31279674038","113383149038",null,[[["1643849995",[3.28125,.37890625,.828125,-.734375,1.3359375,-.625,-.89453125,-2.390625,.7578125,3.40625,1.3515625,.58984375,4.125,-.2734375,-1.125,.6171875,1.2734375,-4.0625,-1.859375,4.3125,-1.84375,.953125,.427734375,
+-3.71875,-4.28125,.2119140625,-3.828125,-.244140625,3.5625,.134765625,-2.9375,3.25]],["1643804092",[3.28125,.345703125,.80859375,-.75390625,1.2890625,-.6015625,-.87109375,-2.375,.72265625,3.40625,1.3203125,.5546875,4.09375,-.255859375,-1.09375,.5859375,1.234375,-4.0625,-1.828125,4.34375,-1.8125,.92578125,.4453125,-3.71875,-4.28125,.185546875,-3.84375,-.267578125,3.5625,.111328125,-2.921875,3.234375]]],null,[["1643822293",[-.32421875,-.203125,.212890625,-.006622314453125,-.224609375,.5234375,.330078125,
+.099609375,-.08203125,-.01239013671875,.41015625,.484375,-.140625,-.0751953125,-.3046875,-.17578125,.251953125,-.25,-.2119140625,.2119140625,.030029296875,.1689453125,.8359375,-.041748046875,-.022216796875,.5546875,-.412109375,-.34375,.1748046875,.1806640625,-.5,-.2470703125]],["1643799063",[-.3359375,-.1572265625,.376953125,-.039306640625,-.1982421875,.515625,.314453125,.076171875,-.0595703125,-.0079345703125,.43359375,.4765625,-.208984375,-.091796875,-.3125,-.1708984375,.23046875,-.23828125,-.1962890625,
+.1787109375,.01556396484375,.220703125,.84375,-.0184326171875,-.052001953125,.51953125,-.4296875,-.458984375,.263671875,.1494140625,-.58203125,-.10498046875]]],null,null,null,null,[[null,[176.8618621826172,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["31279674038","113383149158",null,[[["1643849995",[3.328125,.369140625,.8125,-.7578125,1.3125,-.56640625,-.84375,-2.25,.478515625,3.484375,1.2734375,.462890625,4.21875,-.265625,-.96875,.4921875,
+1.2109375,-4.03125,-1.640625,3.875,-1.5546875,.7890625,.10302734375,-3.125,-4.4375,.375,-3.96875,-.2236328125,3.5,.3359375,-3.265625,3.515625]],["1643804092",[3.3125,.349609375,.80078125,-.76953125,1.28125,-.5546875,-.828125,-2.234375,.4453125,3.46875,1.25,.44140625,4.1875,-.251953125,-.94921875,.47265625,1.1875,-4.03125,-1.6171875,3.890625,-1.53125,.76953125,.10888671875,-3.109375,-4.4375,.359375,-3.953125,-.236328125,3.5,.32421875,-3.234375,3.5]]],null,[["1643822293",[-.326171875,-.201171875,.1884765625,
+-.0014190673828125,-.2216796875,.53125,.330078125,.10107421875,-.0849609375,-.00994873046875,.404296875,.4765625,-.1513671875,-.07470703125,-.298828125,-.17578125,.25390625,-.2421875,-.2099609375,.2109375,.0322265625,.1728515625,.83203125,-.0380859375,-.0242919921875,.55859375,-.408203125,-.33984375,.177734375,.18359375,-.494140625,-.25390625]],["1643799063",[-.33984375,-.1474609375,.3515625,-.03466796875,-.1923828125,.5078125,.3125,.0712890625,-.057861328125,.01446533203125,.431640625,.46484375,
+-.2109375,-.0927734375,-.310546875,-.17578125,.220703125,-.2294921875,-.1923828125,.1796875,.023681640625,.2314453125,.83984375,-.0205078125,-.049072265625,.51953125,-.41796875,-.4453125,.2734375,.1513671875,-.57421875,-.115234375]]],null,null,null,null,[[null,[176.8618621826172,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["31279674038","113383149518",null,[[["1643849995",[3.15625,.34765625,.8515625,-.74609375,1.2578125,-.56640625,-.85546875,
+-2.40625,.6953125,3.328125,1.265625,.546875,4.09375,-.283203125,-1.0625,.54296875,1.1953125,-3.984375,-1.8046875,4.1875,-1.796875,.95703125,.5,-3.75,-4.25,.1376953125,-3.78125,-.310546875,3.4375,.03173828125,-2.921875,3.1875]],["1643804092",[3.171875,.322265625,.8359375,-.765625,1.2265625,-.546875,-.8359375,-2.390625,.65625,3.328125,1.2421875,.515625,4.0625,-.265625,-1.0390625,.51953125,1.171875,-3.984375,-1.7734375,4.21875,-1.765625,.93359375,.5,-3.71875,-4.25,.12353515625,-3.78125,-.32421875,3.4375,
+.0242919921875,-2.921875,3.1875]]],null,[["1643822293",[-.32421875,-.21484375,.212890625,-.00543212890625,-.2333984375,.52734375,.333984375,.10498046875,-.08740234375,-.0296630859375,.416015625,.49609375,-.1357421875,-.072265625,-.302734375,-.1728515625,.2578125,-.259765625,-.2177734375,.208984375,.028564453125,.1640625,.83984375,-.042724609375,-.0184326171875,.55859375,-.41796875,-.345703125,.162109375,.185546875,-.5078125,-.25390625]],["1643799063",[-.345703125,-.1650390625,.375,-.041748046875,
+-.1962890625,.51953125,.318359375,.08056640625,-.06396484375,-.004486083984375,.447265625,.486328125,-.197265625,-.0888671875,-.3203125,-.166015625,.234375,-.2431640625,-.2041015625,.1826171875,.01495361328125,.2216796875,.84765625,-.029052734375,-.044921875,.53125,-.431640625,-.4609375,.2578125,.1494140625,-.5859375,-.115234375]]],null,null,null,null,[[null,[176.8618621826172,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]]]],"1j475122041":[[["60795725037",
+"306664789872",null,[[["1643849995",[3.421875,1.78125,1.6796875,.048095703125,2.796875,-1.3984375,-1.703125,-3.5625,1.328125,3.796875,2.265625,1.5,5.125,-.80078125,-1.8515625,1.1796875,2.203125,-4.53125,-2.78125,3.5625,-2.265625,1.6796875,-.76171875,-2.8125,-5.09375,1.5078125,-4.5,.59375,3.609375,1.359375,-4.78125,4.375]],["1643804092",[3.40625,1.75,1.6640625,.0306396484375,2.75,-1.3828125,-1.6875,-3.53125,1.3125,3.78125,2.25,1.4765625,5.09375,-.79296875,-1.828125,1.171875,2.171875,-4.53125,-2.765625,
+3.5625,-2.25,1.6640625,-.73046875,-2.84375,-5.0625,1.4765625,-4.5,.56640625,3.609375,1.3203125,-4.75,4.34375]]],null,[["1643822293",[1.2734375,1.0859375,.298828125,.09619140625,.10107421875,-.09375,-.52734375,-.953125,-.1259765625,-.5078125,-.1611328125,-.498046875,-1.3515625,-.412109375,.94140625,-.33984375,-.578125,.2578125,.47265625,-.478515625,.255859375,-.1005859375,-.06396484375,.166015625,-.9765625,.029541015625,.314453125,.0106201171875,.74609375,-.38671875,.83984375,.75390625]],["1643799063",
+[1.3046875,1.0625,.3828125,.06201171875,.1142578125,-.046875,-.52734375,-.94921875,-.134765625,-.56640625,-.08740234375,-.439453125,-1.3671875,-.4296875,1.046875,-.33203125,-.5625,.2734375,.50390625,-.54296875,.1728515625,-.123046875,-.0233154296875,.1962890625,-1.0546875,.05859375,.318359375,-.0537109375,.8125,-.423828125,.79296875,.953125]]],null,null,null,null,[[null,[61170.82421875,1],[1,2],[1,1],null,3]]],[null,[[3,0,null,["AdvControlbrand-unsafe"]]]],"1614272341"]]]};function tb(a,b){return!b||0>=b?a:Math.min(a,b)}function T(a,b,c){return b?b:c?c:a?1:0}function ub(a){a=null==a?void 0:I(a,9,0);return void 0===a?!1:[61,51,52].includes(a)};var U=function(a){S.call(this,a,-1,vb)};t(U,S);var vb=[2];var wb=function(a){S.call(this,a)};t(wb,S);var yb=function(a){S.call(this,a,-1,xb)};t(yb,S);yb.prototype.ca=function(){return O(this,wb,3)};var xb=[2,3];var Ab=function(a){S.call(this,a,-1,zb)};t(Ab,S);var Cb=function(a){S.call(this,a,-1,Bb)};t(Cb,S);var Eb=function(a){S.call(this,a,-1,Db)};t(Eb,S);Eb.prototype.ca=function(){return O(this,wb,5)};var zb=[1,2],Bb=[3,4],Db=[3,4,5];var Gb=function(a){S.call(this,a,-1,Fb)};t(Gb,S);var W=function(a){return N(a,Hb,3)},Jb=function(a){S.call(this,a,-1,Ib)};t(Jb,S);Jb.prototype.Y=function(){return O(this,U,2)};Jb.prototype.ma=function(){return O(this,U,3)};var Kb=function(a){S.call(this,a)};t(Kb,S);Kb.prototype.u=function(){return P(this,1)};Kb.prototype.v=function(){return P(this,2)};Kb.prototype.da=function(){return L(this,3)};var Hb=function(a){S.call(this,a)};t(Hb,S);var X=function(a){S.call(this,a)};t(X,S);
+var Y=function(a){S.call(this,a)};t(Y,S);var Nb=function(a){var b=new Y;return M(b,1,a)},Z=function(a){S.call(this,a)};t(Z,S);Z.prototype.u=function(){return P(this,2)};Z.prototype.v=function(){return P(this,3)};Z.prototype.W=function(){return P(this,4)};Z.prototype.da=function(){return L(this,5)};var Fb=[2],Ib=[1,2,3];function Ob(a,b,c){if(!b||0>=b)return{l:0,P:1};var d=T(!0,null==a?void 0:L(a,1),null==c?void 0:L(c,1)),e=T(!1,null==a?void 0:L(a,2),null==c?void 0:L(c,2)),g=T(!1,null==a?void 0:L(a,3),null==c?void 0:L(c,3)),f,h;a=T(!1,null==a?void 0:null==(f=N(a,Y,5))?void 0:L(f,1),null==c?void 0:null==(h=N(c,Y,5))?void 0:L(h,1));c=new X;f=M(c,1,d);f=M(f,2,e);f=M(f,3,g);h=Nb(a);cb(f,Y,5,h);return{l:b*d*(1-1/(1+Math.exp(-e*(Math.log(b/1E6)-a-g)))),P:4,sa:c}};function Pb(a,b){var c=null==a?void 0:N(a,X,6),d,e=null==a?void 0:null==(d=W(a))?void 0:N(d,X,3);if(!b||0>=b)return{l:0,P:1};var g;if(!(null==a?0:null==(g=W(a))?0:J(g,2)))return{l:.85*b,P:2};d=T(!0,null==c?void 0:L(c,4),null==e?void 0:L(e,4));g=T(!0,null==c?void 0:L(c,1),null==e?void 0:L(e,1));var f=T(!1,null==c?void 0:L(c,2),null==e?void 0:L(e,2)),h=T(!1,null==c?void 0:L(c,3),null==e?void 0:L(e,3)),k,l;c=T(!1,null==c?void 0:null==(k=N(c,Y,5))?void 0:L(k,1),null==e?void 0:null==(l=N(e,Y,5))?void 0:
+L(l,1));k=new X;l=M(k,1,g);l=M(l,2,f);l=M(l,3,h);l=M(l,4,d);var m=Nb(c);cb(l,Y,5,m);d=d*b*g*(1-1/(1+Math.exp(-f*(Math.log(d*b/1E6)-c-h))));g=1E6*(null==a?NaN:L(a,8));var p;if((null==a?0:null==(p=W(a))?0:J(p,6))&&d<g&&g<b){var y;d=g+1E6*(null!=(y=null==e?void 0:L(e,7))?y:0)*Math.log(b/g)}return{l:d,P:3,sa:k}};function Qb(a,b){if(!(0<G(a,2).length&&G(a,2).length===F(a,3).length&&G(a,2).length===G(a,4).length))return 0;for(var c=0,d=0,e=1,g=r(F(a,3)),f=g.next();!f.done;f=g.next()){var h=0;switch(f.value){case 1:h=G(a,2)[d]*(b.ea?Math.pow(b.ea,G(a,4)[d]):0);break;case 2:c=h=G(a,2)[d]*(b.oa?Math.pow(b.oa,G(a,4)[d]):0);break;case 3:h=G(a,2)[d]}if(0===h)return 0;e*=h;d+=1}0<L(a,7)&&(e=Math.min(e,L(a,7)*c*1E3));return 1E6*e}
+function Rb(a,b){var c=0;b&&(0<O(b,Sb,7).length?c=Qb(O(b,Sb,7)[0],a):0<O(b,Sb,8).length&&(c=Qb(O(b,Sb,8)[0],a)));return c};function Tb(a,b,c){if(I(a,2,0)!==I(b,2,0))return c;var d=!1;switch(I(a,2,0)){case 1:a:{var e,g=new Set(null!=(e=F(a,3))?e:[]);b=r(F(b,3));for(e=b.next();!e.done;e=b.next())if(g.has(e.value)){d=!0;break a}d=!1}break;case 0:a:{e=new Set(null!=(g=F(a,4))?g:[]);b=r(F(b,4));for(g=b.next();!g.done;g=b.next())if(e.has(g.value)){d=!0;break a}d=!1}break;case 2:b=new Ub(b),d=(e=N(a,yb,5))?Vb(b,e):!1}return J(a,6)?d?null:c:d?c:null}
+function Vb(a,b){var c=I(b,1,0),d=b.ca(),e=O(b,yb,2);switch(c){case 2:c=d.every(function(g){return Wb(a,g)})&&e.every(function(g){return Vb(a,g)});break;case 1:c=d.some(function(g){return Wb(a,g)})||e.some(function(g){return Vb(a,g)});break;default:throw Error("unexpected value "+c+"!");}return J(b,4)?!c:c}
+var Ub=function(a){this.ga=new Map;a=r(a.ca());for(var b=a.next();!b.done;b=a.next()){var c=b.value;b=I(c,1,0);c=I(c,2,0);var d=this.ga.get(b);d||(d=new Set,this.ga.set(b,d));d.add(c)}},Wb=function(a,b){var c=I(b,2,0);return(a=a.ga.get(I(b,1,0)))?a.has(c):!1};function Xb(a,b){a=r((null==b?void 0:b.get(a))||[]);for(b=a.next();!b.done;b=a.next())if(b=b.value,b.count+1>b.xa)return!1;return!0};function Yb(a,b){return null==a.na?!0:!a.na.some(function(c){var d;return null==(d=b.Ba)?void 0:d.includes(c,0)})};var Zb=function(a){S.call(this,a)};t(Zb,S);n=Zb.prototype;n.u=function(){return P(this,1)};n.v=function(){return P(this,2)};n.W=function(){return P(this,3)};n.V=function(){return P(this,4)};n.U=function(){return P(this,5)};n.X=function(){return P(this,6)};var ac=function(a){S.call(this,a,-1,$b)};t(ac,S);var $b=[1];function bc(a,b){var c=!0;c=void 0===c?!1:c;return cc(0,(null==a?void 0:O(a,U,1))||[],(null==b?void 0:O(b,U,1))||[],c)}function dc(a,b){var c=!0;c=void 0===c?!1:c;return cc(1,(null==a?void 0:a.Y())||[],(null==b?void 0:b.Y())||[],c)}function ec(a,b){var c=!0;c=void 0===c?!1:c;return cc(1,(null==a?void 0:a.ma())||[],(null==b?void 0:b.Y())||[],c)}
+function cc(a,b,c,d){var e=0,g=new Map;b=r(b);for(var f=b.next();!f.done;f=b.next())e=f.value,g.set(I(e,1,""),e),e=L(e,3);b=null;c=r(c);for(f=c.next();!f.done;f=c.next()){var h=f.value;e=L(h,3);if(f=d?g.values().next().value:g.get(I(h,1,""))){a:{b=a;f=G(f,2);h=G(h,2);if(f.length===h.length){for(var k=0,l=0;l<f.length;l++)k+=f[l]*h[l];f=k}else f=void 0;if(void 0!==f)switch(b){case 0:b=1/(1+Math.exp(-1*f));break a;case 1:b=Math.exp(f);break a}b=void 0}if(void 0!==b)return b;b=e}}var m;return null!=
+(m=b)?m:e};var fc=function(a){S.call(this,a)};t(fc,S);function gc(a,b,c){"0"===a||c.has(a)||c.set(a,b.filter(function(d){return 0<I(d,3,0)}).map(function(d){var e=I(d,3,0);switch(I(d,1,0)){case 6:d=60*I(d,2,0);break;case 1:d=3600*I(d,2,0);break;case 2:d=86400*I(d,2,0);break;case 3:d=604800*I(d,2,0);break;case 4:d=2592E3*I(d,2,0);break;case 5:d=null;break;default:e=d=0}return{pa:d,xa:e,count:0}}))}function hc(a,b,c){if(b=c.get(b))for(b=r(b),c=b.next();!c.done;c=b.next())c=c.value,(null===c.pa||a.Aa<=c.pa)&&c.count++};var Sb=function(a){S.call(this,a,-1,ic)};t(Sb,S);var ic=[2,3,4];var kc=function(a){S.call(this,a,-1,jc)};t(kc,S);kc.prototype.Y=function(){return O(this,U,3)};kc.prototype.ma=function(){return O(this,U,10)};var jc=[1,3,10,7,8];var mc=function(a){S.call(this,a,-1,lc)};t(mc,S);n=mc.prototype;n.u=function(){return P(this,1)};n.v=function(){return P(this,2)};n.W=function(){return P(this,3)};n.V=function(){return P(this,6)};n.U=function(){return P(this,7)};n.X=function(){return P(this,8)};var lc=[9,10,11,12,13,14];var oc=function(a){S.call(this,a,-1,nc)};t(oc,S);var nc=[1];var qc=function(a){S.call(this,a,-1,pc)};t(qc,S);var pc=[1];var rc={ad:{},bid:0,render:""};function sc(){new qc;return function(a,b,c,d,e){return tc(a,c,d,e)}}
+function tc(a,b,c,d){b=b?new Gb(nb(b)):void 0;var e,g;if(!b||!(O(b,Kb,2).length||(null==(e=W(b))?0:J(e,1))||(null==(g=W(b))?0:J(g,5))))return rc;e=new ac(nb(a.userBiddingSignals));g=a.ads.map(function(f){return{renderUrl:f.renderUrl,metadata:new Zb(nb(f.metadata))}});c=c[a.name]?new oc(nb(c[a.name])):void 0;d=d.prevWins.map(function(f){return{Aa:f[0],I:new Zb(nb(f[1].metadata))}});return uc(a.name,e,g,d,c,b)}
+function uc(a,b,c,d,e,g){var f,h={Ja:null!=(f=null==g?void 0:W(g))?f:void 0,T:new Map,O:new Map,R:new Map,S:new Map,Z:new Map,interestGroupName:null!=a?a:void 0};a=new Map;if(e){e=r(O(e,mc,1));for(f=e.next();!f.done;f=e.next())f=f.value,a.set(f.u().concat("+",f.v(),"+",f.W()),f),gc(f.v(),O(f,fc,9),h.T),gc(f.u(),O(f,fc,10),h.O),gc(f.V(),O(f,fc,11),h.R),gc(f.U(),O(f,fc,12),h.S),gc(f.X(),O(f,fc,13),h.Z);d=r(d);for(e=d.next();!e.done;e=d.next())e=e.value,h.T&&hc(e,e.I.v(),h.T),h.O&&hc(e,e.I.u(),h.O),
+h.R&&hc(e,e.I.V(),h.R),h.S&&hc(e,e.I.U(),h.S),h.Z&&hc(e,e.I.X(),h.Z)}e=new Map;if(g)for(d=r(O(g,Kb,2)),f=d.next();!f.done;f=d.next())f=f.value,e.set(f.u().concat("+",f.v(),"+",""),f.da());d=[];c=r(c);for(f=c.next();!f.done;f=c.next()){f=f.value;f={renderUrl:f.renderUrl,H:f.metadata.u(),K:f.metadata.v(),ka:f.metadata.W(),ja:f.metadata.V(),ia:f.metadata.U(),la:f.metadata.X(),i:0,J:0};var k=f.H.concat("+",f.K,"+",f.ka);f.aa=e.get(f.H.concat("+",f.K,"+",""));if(!f.aa){var l=void 0,m=void 0,p=void 0,y=
+void 0;if(!(null==(l=g)?0:null==(m=W(l))?0:J(m,1))&&!(null==(p=g)?0:null==(y=W(p))?0:J(y,5)))continue;else if(!a.get(k))continue;m=l=void 0;f.o=null!=(m=null==(l=a.get(k))?void 0:N(l,kc,4))?m:void 0}m=l=void 0;f.ha=null!=(m=null==(l=a.get(k))?void 0:N(l,Ab,5))?m:void 0;m=l=void 0;f.na=null!=(m=null==(l=a.get(k))?void 0:F(l,14))?m:void 0;d.push(f)}if(c=null==g?void 0:N(g,Ab,5)){a=new Map;e=new Map;f=r(O(c,Cb,1));for(k=f.next();!k.done;k=f.next())k=k.value,a.set(I(k,1,0),k);c=r(O(c,Eb,2));for(f=c.next();!f.done;f=
+c.next())f=f.value,e.set(I(f,1,0),f);h.ta=a;h.ua=e}var H;h.Ba=null!=(H=F(b,1))?H:void 0;b=[];H=new Map;a=r(d);for(d=a.next();!d.done;d=a.next())if(d=d.value,e=h,!(!Xb(d.K,e.T)||!Xb(d.H,e.O)||d.ja&&!Xb(d.ja,e.R)||d.ia&&!Xb(d.ia,e.S)||d.la&&!Xb(d.la,e.Z))){if(d.ha){c=h;e=c.ta;c=c.ua;f=d.ha;if(e&&c&&f)a:{k=r(O(f,Cb,1));for(l=k.next();!l.done;l=k.next()){p=l.value;y=I(p,1,0);var da=c.get(y);if(da){if(J(p,7)){l=H.get(y);m=I(p,8,0);if(void 0===l)l=new Map,H.set(y,l);else{var na=l.get(m);if(void 0!==na){e=
+na;break a}}p=Tb(p,da,y);l.set(m,p)}else p=Tb(p,da,y);if(p){e=p;break a}}}c=r(O(f,Eb,2));for(f=c.next();!f.done;f=c.next())if(f=f.value,k=I(f,1,0),l=e.get(k))if(f=Tb(l,f,k)){e=f;break a}e=null}else e=null;if(e)continue}Yb(d,h)&&b.push(d)}return vc({ads:b,ya:h},g).bidResponse}
+function vc(a,b){for(var c=[],d=[],e=r(a.ads),g=e.next();!g.done;g=e.next()){g=g.value;var f=void 0,h=void 0;if(null==(f=b)?0:null==(h=W(f))?0:J(h,7)){var k=h=f=void 0,l=void 0,m=void 0,p=void 0;g.H===(null==(f=b)?void 0:null==(h=N(f,Z,16))?void 0:h.u())&&g.K===(null==(k=b)?void 0:null==(l=N(k,Z,16))?void 0:l.v())&&a.ya.interestGroupName===(null==(m=b)?void 0:null==(p=N(m,Z,16))?void 0:I(p,1,""))?(k=h=f=void 0,l=null!=(k=null==(f=b)?void 0:null==(h=N(f,Z,16))?void 0:h.da())?k:0,g.i=0===l?1E9:l):g.i=
+0}else if(null!=g.aa){g.i=g.aa;c.push(g);continue}else if(h=f=void 0,null==(f=b)?0:null==(h=W(f))?0:J(h,1))ub(g.o)?(f=void 0,g.ea=ec(null==(f=b)?void 0:N(f,Jb,1),g.o)):(f=void 0,g.oa=bc(null==(f=b)?void 0:N(f,Jb,1),g.o),f=void 0,g.ea=dc(null==(f=b)?void 0:N(f,Jb,1),g.o)),g.i=Rb(g,g.o),g.i||(h=f=void 0,g.i=null!=(h=null==(f=g.o)?void 0:L(f,6))?h:0);else if(h=f=void 0,null==(f=b)?0:null==(h=W(f))?0:J(h,5))h=f=void 0,g.i=null!=(h=null==(f=g.o)?void 0:L(f,6))?h:0;d.push(g)}c={renderUrl:"",H:"",K:"",ka:"",
+i:0,J:0};var y;if(null==b?0:null==(y=W(b))?0:J(y,7))b=a.ads.reduce(function(V,K){return V.i<K.i?K:V},c),b.J=b.i;else{y=a.ads.reduce(function(V,K){return!ub(K.o)&&V.i<K.i?K:V},c);c=a.ads.reduce(function(V,K){return ub(K.o)&&V.i<K.i?K:V},c);a=Pb(b,null==y?void 0:y.i);var H,da;a.l=tb(a.l,null==b?void 0:null==(H=W(b))?void 0:null==(da=N(H,X,3))?void 0:L(da,6));var na;H=Ob(null==b?void 0:N(b,X,7),null==c?void 0:c.i,null==b?void 0:null==(na=W(b))?void 0:N(na,X,4));var Lb,Mb;H.l=tb(H.l,null==b?void 0:null==
+(Lb=W(b))?void 0:null==(Mb=N(Lb,X,4))?void 0:L(Mb,6));a.l>H.l?(b=y,b.J=a.l):(b=c,b.J=H.l)}return{bidResponse:{ad:{},bid:b.J,render:b.renderUrl},debugInfo:void 0}};var wc=function(a){var b={maxFloorCpmUsdMicros:"6250"},c={topWindowHostname:"www.cnn.com",seller:"https://pubads.g.doubleclick.net",joinCount:7,bidCount:0,prevWins:[]},d=sc();return function(){return d(a,b,rb,sb,c)}};
+
+function generateBid(interestGroups){for(var a=[],b=Date.now(),c=r(interestGroups),d=c.next();!d.done;d=c.next()){var e={generateBidTime:0,success:!1},g=wc(d.value);d=Date.now();g=g();e.generateBidTime=Date.now()-d;e.success=JSON.stringify(g)===JSON.stringify({ad:{},bid:2937687.988333709,render:"https://googleads.g.doubleclick.net/ads/simple-ad.html?adg_id=52836427830&cr_id=310927197294&cv_id=4"});e.bidResponse=g;a.push(e)}a.push({generateBidTime:Date.now()-b,success:!0});return a;}
diff --git a/apct-tests/perftests/rubidium/src/android/rubidium/js/JSScriptEnginePerfTests.java b/apct-tests/perftests/rubidium/src/android/rubidium/js/JSScriptEnginePerfTests.java
index ac36ac2..bf9ff3a 100644
--- a/apct-tests/perftests/rubidium/src/android/rubidium/js/JSScriptEnginePerfTests.java
+++ b/apct-tests/perftests/rubidium/src/android/rubidium/js/JSScriptEnginePerfTests.java
@@ -16,49 +16,77 @@
 
 package android.rubidium.js;
 
+import static com.android.adservices.service.js.JSScriptArgument.arrayArg;
 import static com.android.adservices.service.js.JSScriptArgument.numericArg;
 import static com.android.adservices.service.js.JSScriptArgument.recordArg;
 import static com.android.adservices.service.js.JSScriptArgument.stringArg;
+import static com.android.adservices.service.js.JSScriptArgument.stringArrayArg;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import android.content.Context;
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
+import android.util.Log;
 
 import androidx.annotation.NonNull;
 import androidx.test.core.app.ApplicationProvider;
-import androidx.test.filters.LargeTest;
+import androidx.test.filters.MediumTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.adservices.service.js.JSScriptArgument;
+import com.android.adservices.service.js.JSScriptArrayArgument;
 import com.android.adservices.service.js.JSScriptEngine;
+import com.android.adservices.service.js.JSScriptRecordArgument;
+import com.android.adservices.service.profiling.JSScriptEngineLogConstants;
+import com.android.adservices.service.profiling.Profiler;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.ListenableFuture;
 
+import org.json.JSONArray;
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
+import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
-@LargeTest
+/** To run the unit tests for this class, run "atest RubidiumPerfTests:JSScriptEnginePerfTests" */
+@MediumTest
 @RunWith(AndroidJUnit4.class)
 public class JSScriptEnginePerfTests {
     private static final String TAG = JSScriptEnginePerfTests.class.getSimpleName();
-    protected static final Context sContext = ApplicationProvider.getApplicationContext();
-    private final ExecutorService mExecutorService = Executors.newFixedThreadPool(10);
-    private final JSScriptEngine mJSScriptEngine = new JSScriptEngine(sContext);
+    private static final Context sContext = ApplicationProvider.getApplicationContext();
+    private static final ExecutorService sExecutorService = Executors.newFixedThreadPool(10);
+
+    private static JSScriptEngine sJSScriptEngine;
 
     @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
 
+    @Before
+    public void before() throws Exception {
+        Profiler profiler = Profiler.createInstance(JSScriptEngine.TAG);
+        sJSScriptEngine = JSScriptEngine.getInstanceForTesting(sContext, profiler);
+
+        // Warm up the sandbox env.
+        callJSEngine(
+                "function test() { return \"hello world\";" + " }", ImmutableList.of(), "test");
+    }
+
+    @After
+    public void after() {
+        sJSScriptEngine.shutdown();
+    }
+
     @Test
     public void evaluate_helloWorld() throws Exception {
         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
@@ -88,8 +116,7 @@
 
         state.resumeTiming();
         while (state.keepRunning()) {
-            callJSEngine(
-                    jsTestFile, ImmutableList.of(adDataArgument), "generateBid");
+            callJSEngine(jsTestFile, ImmutableList.of(adDataArgument), "generateBid");
         }
     }
 
@@ -99,8 +126,7 @@
         state.pauseTiming();
 
         InputStream testJsInputStream = sContext.getAssets().open("turtledove_generate_bid.js");
-        String jsTestFile =
-                new String(testJsInputStream.readAllBytes(), StandardCharsets.UTF_8);
+        String jsTestFile = new String(testJsInputStream.readAllBytes(), StandardCharsets.UTF_8);
         // Initialize the environment with one call.
         callJSEngine(jsTestFile, ImmutableList.of(), "generateBid");
 
@@ -110,15 +136,99 @@
         }
     }
 
-    private String callJSEngine(
+    @Test
+    public void evaluate_turtledoveSampleGenerateBid_parametrized_10Ads() throws Exception {
+        runParametrizedTurtledoveScript(10);
+    }
+
+    @Test
+    public void evaluate_turtledoveSampleGenerateBid_parametrized_25Ads() throws Exception {
+        runParametrizedTurtledoveScript(25);
+    }
+
+    @Test
+    public void evaluate_turtledoveSampleGenerateBid_parametrized_50Ads() throws Exception {
+        runParametrizedTurtledoveScript(50);
+    }
+
+    @Test
+    public void evaluate_turtledoveSampleGenerateBid_parametrized_75Ads() throws Exception {
+        runParametrizedTurtledoveScript(75);
+    }
+
+    private void runParametrizedTurtledoveScript(int numAds) throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        state.pauseTiming();
+        InputStream testJsInputStream =
+                sContext.getAssets().open("turtledove_parametrized_generateBid.js");
+        String jsTestFile = new String(testJsInputStream.readAllBytes(), StandardCharsets.UTF_8);
+
+        state.resumeTiming();
+        while (state.keepRunning()) {
+            int numInterestGroups = 1;
+            String res =
+                    callJSEngine(
+                            sJSScriptEngine,
+                            jsTestFile,
+                            ImmutableList.of(
+                                    buildSampleInterestGroupArg(numInterestGroups, numAds)),
+                            "generateBid");
+
+            // I modified the Turtledove script to have the total execution time
+            // (across all IGs) as the last element in the response array.
+            JSONArray obj = new JSONArray(res);
+            long webviewExecTime = obj.getJSONObject(obj.length() - 1).getLong("generateBidTime");
+            String webviewExecTimeLog =
+                    String.format(
+                            "(%s: %d)",
+                            JSScriptEngineLogConstants.WEBVIEW_EXECUTION_TIME, webviewExecTime);
+            // The listener picks up logs from JSScriptEngine, so simulate logging from there.
+            Log.d("JSScriptEngine", webviewExecTimeLog);
+        }
+    }
+
+    private JSScriptArrayArgument<JSScriptRecordArgument> buildSampleInterestGroupArg(
+            int numCustomAudiences, int numAds) {
+        JSScriptRecordArgument ad =
+                recordArg(
+                        "foo",
+                        ImmutableList.of(
+                                stringArg(
+                                        "renderUrl",
+                                        "https://googleads.g.doubleclick.net/ads/simple-ad.html?adg_id=52836427830&cr_id=310927197297&cv_id=4"),
+                                stringArrayArg(
+                                        "metadata",
+                                        ImmutableList.of(
+                                                "52836427830", "310927197297", "4", "608936333"))));
+
+        JSScriptRecordArgument interestGroupArg =
+                recordArg(
+                        "foo",
+                        stringArg("owner", "https://googleads.g.doubleclick.net/"),
+                        stringArg("name", "1j115753478"),
+                        stringArg("biddingLogicUrl", "https://googleads.g.doubleclick.net/td/bjs"),
+                        stringArg(
+                                "dailyUpdateUrl", "https://googleads.g.doubleclick.net/td/update"),
+                        stringArg(
+                                "trustedBiddingSignalsUrl",
+                                "https://googleads.g.doubleclick.net/td/sjs"),
+                        stringArrayArg(
+                                "trustedBiddingSignalsKeys", ImmutableList.of("1j115753478")),
+                        stringArrayArg("userBiddingSignals", ImmutableList.of()),
+                        new JSScriptArrayArgument("ads", Collections.nCopies(numAds, ad)));
+
+        return arrayArg("foo", Collections.nCopies(numCustomAudiences, interestGroupArg));
+    }
+
+    private static String callJSEngine(
             @NonNull String jsScript,
             @NonNull List<JSScriptArgument> args,
             @NonNull String functionName)
             throws Exception {
-        return callJSEngine(mJSScriptEngine, jsScript, args, functionName);
+        return callJSEngine(sJSScriptEngine, jsScript, args, functionName);
     }
 
-    private String callJSEngine(
+    private static String callJSEngine(
             @NonNull JSScriptEngine jsScriptEngine,
             @NonNull String jsScript,
             @NonNull List<JSScriptArgument> args,
@@ -131,15 +241,15 @@
         return futureResult.get();
     }
 
-    private ListenableFuture<String> callJSEngineAsync(
+    private static ListenableFuture<String> callJSEngineAsync(
             @NonNull String jsScript,
             @NonNull List<JSScriptArgument> args,
             @NonNull String functionName,
             @NonNull CountDownLatch resultLatch) {
-        return callJSEngineAsync(mJSScriptEngine, jsScript, args, functionName, resultLatch);
+        return callJSEngineAsync(sJSScriptEngine, jsScript, args, functionName, resultLatch);
     }
 
-    private ListenableFuture<String> callJSEngineAsync(
+    private static ListenableFuture<String> callJSEngineAsync(
             @NonNull JSScriptEngine engine,
             @NonNull String jsScript,
             @NonNull List<JSScriptArgument> args,
@@ -148,7 +258,7 @@
         Objects.requireNonNull(engine);
         Objects.requireNonNull(resultLatch);
         ListenableFuture<String> result = engine.evaluate(jsScript, args, functionName);
-        result.addListener(resultLatch::countDown, mExecutorService);
+        result.addListener(resultLatch::countDown, sExecutorService);
         return result;
     }
 }
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 367c8f5..92068e5 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -332,12 +332,18 @@
             "REORDER_ALARMS_FOR_TARE",
     });
 
-    BroadcastOptions mOptsWithFgs = BroadcastOptions.makeBasic();
-    BroadcastOptions mOptsWithFgsForAlarmClock = BroadcastOptions.makeBasic();
-    BroadcastOptions mOptsWithoutFgs = BroadcastOptions.makeBasic();
-    BroadcastOptions mOptsTimeBroadcast = BroadcastOptions.makeBasic();
+    BroadcastOptions mOptsWithFgs = makeBasicAlarmBroadcastOptions();
+    BroadcastOptions mOptsWithFgsForAlarmClock = makeBasicAlarmBroadcastOptions();
+    BroadcastOptions mOptsWithoutFgs = makeBasicAlarmBroadcastOptions();
+    BroadcastOptions mOptsTimeBroadcast = makeBasicAlarmBroadcastOptions();
     ActivityOptions mActivityOptsRestrictBal = ActivityOptions.makeBasic();
-    BroadcastOptions mBroadcastOptsRestrictBal = BroadcastOptions.makeBasic();
+    BroadcastOptions mBroadcastOptsRestrictBal = makeBasicAlarmBroadcastOptions();
+
+    private static BroadcastOptions makeBasicAlarmBroadcastOptions() {
+        final BroadcastOptions b = BroadcastOptions.makeBasic();
+        b.setAlarmBroadcast(true);
+        return b;
+    }
 
     // TODO(b/172085676): Move inside alarm store.
     private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser =
@@ -667,9 +673,6 @@
         private static final String KEY_APP_STANDBY_RESTRICTED_WINDOW =
                 "app_standby_restricted_window";
 
-        @VisibleForTesting
-        static final String KEY_LAZY_BATCHING = "lazy_batching";
-
         private static final String KEY_TIME_TICK_ALLOWED_WHILE_IDLE =
                 "time_tick_allowed_while_idle";
 
@@ -685,8 +688,6 @@
         static final String KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW = "allow_while_idle_compat_window";
 
         @VisibleForTesting
-        static final String KEY_CRASH_NON_CLOCK_APPS = "crash_non_clock_apps";
-        @VisibleForTesting
         static final String KEY_PRIORITY_ALARM_DELAY = "priority_alarm_delay";
         @VisibleForTesting
         static final String KEY_EXACT_ALARM_DENY_LIST = "exact_alarm_deny_list";
@@ -721,7 +722,6 @@
         private static final int DEFAULT_APP_STANDBY_RESTRICTED_QUOTA = 1;
         private static final long DEFAULT_APP_STANDBY_RESTRICTED_WINDOW = INTERVAL_DAY;
 
-        private static final boolean DEFAULT_LAZY_BATCHING = true;
         private static final boolean DEFAULT_TIME_TICK_ALLOWED_WHILE_IDLE = true;
 
         /**
@@ -734,8 +734,6 @@
         private static final long DEFAULT_ALLOW_WHILE_IDLE_WINDOW = 60 * 60 * 1000; // 1 hour.
         private static final long DEFAULT_ALLOW_WHILE_IDLE_COMPAT_WINDOW = 9 * 60 * 1000; // 9 mins.
 
-        private static final boolean DEFAULT_CRASH_NON_CLOCK_APPS = true;
-
         private static final long DEFAULT_PRIORITY_ALARM_DELAY = 9 * 60_000;
 
         private static final long DEFAULT_MIN_DEVICE_IDLE_FUZZ = 2 * 60_000;
@@ -770,7 +768,6 @@
         public int APP_STANDBY_RESTRICTED_QUOTA = DEFAULT_APP_STANDBY_RESTRICTED_QUOTA;
         public long APP_STANDBY_RESTRICTED_WINDOW = DEFAULT_APP_STANDBY_RESTRICTED_WINDOW;
 
-        public boolean LAZY_BATCHING = DEFAULT_LAZY_BATCHING;
         public boolean TIME_TICK_ALLOWED_WHILE_IDLE = DEFAULT_TIME_TICK_ALLOWED_WHILE_IDLE;
 
         public int ALLOW_WHILE_IDLE_QUOTA = DEFAULT_ALLOW_WHILE_IDLE_QUOTA;
@@ -794,13 +791,6 @@
         public long ALLOW_WHILE_IDLE_WINDOW = DEFAULT_ALLOW_WHILE_IDLE_WINDOW;
 
         /**
-         * Whether or not to crash callers that use setExactAndAllowWhileIdle or setAlarmClock
-         * but don't hold the required permission. This is useful to catch broken
-         * apps and reverting to a softer failure in case of broken apps.
-         */
-        public boolean CRASH_NON_CLOCK_APPS = DEFAULT_CRASH_NON_CLOCK_APPS;
-
-        /**
          * Minimum delay between two slots that an app can get for their prioritized alarms, while
          * the device is in doze.
          */
@@ -981,23 +971,11 @@
                         case KEY_APP_STANDBY_RESTRICTED_WINDOW:
                             updateStandbyWindowsLocked();
                             break;
-                        case KEY_LAZY_BATCHING:
-                            final boolean oldLazyBatching = LAZY_BATCHING;
-                            LAZY_BATCHING = properties.getBoolean(
-                                    KEY_LAZY_BATCHING, DEFAULT_LAZY_BATCHING);
-                            if (oldLazyBatching != LAZY_BATCHING) {
-                                migrateAlarmsToNewStoreLocked();
-                            }
-                            break;
                         case KEY_TIME_TICK_ALLOWED_WHILE_IDLE:
                             TIME_TICK_ALLOWED_WHILE_IDLE = properties.getBoolean(
                                     KEY_TIME_TICK_ALLOWED_WHILE_IDLE,
                                     DEFAULT_TIME_TICK_ALLOWED_WHILE_IDLE);
                             break;
-                        case KEY_CRASH_NON_CLOCK_APPS:
-                            CRASH_NON_CLOCK_APPS = properties.getBoolean(KEY_CRASH_NON_CLOCK_APPS,
-                                    DEFAULT_CRASH_NON_CLOCK_APPS);
-                            break;
                         case KEY_PRIORITY_ALARM_DELAY:
                             PRIORITY_ALARM_DELAY = properties.getLong(KEY_PRIORITY_ALARM_DELAY,
                                     DEFAULT_PRIORITY_ALARM_DELAY);
@@ -1103,15 +1081,6 @@
             }
         }
 
-        private void migrateAlarmsToNewStoreLocked() {
-            final AlarmStore newStore = LAZY_BATCHING ? new LazyAlarmStore()
-                    : new BatchingAlarmStore();
-            final ArrayList<Alarm> allAlarms = mAlarmStore.remove((unused) -> true);
-            newStore.addAll(allAlarms);
-            mAlarmStore = newStore;
-            mAlarmStore.setAlarmClockRemovalListener(mAlarmClockUpdater);
-        }
-
         private void updateDeviceIdleFuzzBoundaries() {
             final DeviceConfig.Properties properties = DeviceConfig.getProperties(
                     DeviceConfig.NAMESPACE_ALARM_MANAGER,
@@ -1249,15 +1218,9 @@
             TimeUtils.formatDuration(APP_STANDBY_RESTRICTED_WINDOW, pw);
             pw.println();
 
-            pw.print(KEY_LAZY_BATCHING, LAZY_BATCHING);
-            pw.println();
-
             pw.print(KEY_TIME_TICK_ALLOWED_WHILE_IDLE, TIME_TICK_ALLOWED_WHILE_IDLE);
             pw.println();
 
-            pw.print(KEY_CRASH_NON_CLOCK_APPS, CRASH_NON_CLOCK_APPS);
-            pw.println();
-
             pw.print(KEY_PRIORITY_ALARM_DELAY);
             pw.print("=");
             TimeUtils.formatDuration(PRIORITY_ALARM_DELAY, pw);
@@ -1890,8 +1853,7 @@
             mHandler = new AlarmHandler();
             mConstants = new Constants(mHandler);
 
-            mAlarmStore = mConstants.LAZY_BATCHING ? new LazyAlarmStore()
-                    : new BatchingAlarmStore();
+            mAlarmStore = new LazyAlarmStore();
             mAlarmStore.setAlarmClockRemovalListener(mAlarmClockUpdater);
 
             mAppWakeupHistory = new AppWakeupHistory(Constants.DEFAULT_APP_STANDBY_WINDOW);
@@ -2905,11 +2867,7 @@
                                             + Manifest.permission.SCHEDULE_EXACT_ALARM + " or "
                                             + Manifest.permission.USE_EXACT_ALARM + " to set "
                                             + "exact alarms.";
-                            if (mConstants.CRASH_NON_CLOCK_APPS) {
-                                throw new SecurityException(errorMessage);
-                            } else {
-                                Slog.wtf(TAG, errorMessage);
-                            }
+                            throw new SecurityException(errorMessage);
                         }
                         // If the app is on the full system power allow-list (not except-idle),
                         // or the user-elected allow-list, or we're in a soft failure mode, we still
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/BatchingAlarmStore.java b/apex/jobscheduler/service/java/com/android/server/alarm/BatchingAlarmStore.java
deleted file mode 100644
index 1a4efb8..0000000
--- a/apex/jobscheduler/service/java/com/android/server/alarm/BatchingAlarmStore.java
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.alarm;
-
-import static com.android.server.alarm.AlarmManagerService.DEBUG_BATCH;
-import static com.android.server.alarm.AlarmManagerService.clampPositive;
-import static com.android.server.alarm.AlarmManagerService.dumpAlarmList;
-import static com.android.server.alarm.AlarmManagerService.isTimeTickAlarm;
-
-import android.app.AlarmManager;
-import android.util.IndentingPrintWriter;
-import android.util.Slog;
-import android.util.proto.ProtoOutputStream;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.StatLogger;
-
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.function.Predicate;
-
-/**
- * Batching implementation of an Alarm Store.
- * This keeps the alarms in batches, which are sorted on the start time of their delivery window.
- */
-public class BatchingAlarmStore implements AlarmStore {
-    @VisibleForTesting
-    static final String TAG = BatchingAlarmStore.class.getSimpleName();
-
-    private final ArrayList<Batch> mAlarmBatches = new ArrayList<>();
-    private int mSize;
-    private Runnable mOnAlarmClockRemoved;
-
-    interface Stats {
-        int REBATCH_ALL_ALARMS = 0;
-        int GET_COUNT = 1;
-    }
-
-    final StatLogger mStatLogger = new StatLogger(TAG + " stats", new String[]{
-            "REBATCH_ALL_ALARMS",
-            "GET_COUNT",
-    });
-
-    private static final Comparator<Batch> sBatchOrder = Comparator.comparingLong(b -> b.mStart);
-
-    private static final Comparator<Alarm> sIncreasingTimeOrder = Comparator.comparingLong(
-            Alarm::getWhenElapsed);
-
-    @Override
-    public void add(Alarm a) {
-        insertAndBatchAlarm(a);
-        mSize++;
-    }
-
-    @Override
-    public void addAll(ArrayList<Alarm> alarms) {
-        if (alarms == null) {
-            return;
-        }
-        for (final Alarm a : alarms) {
-            add(a);
-        }
-    }
-
-    @Override
-    public ArrayList<Alarm> remove(Predicate<Alarm> whichAlarms) {
-        final ArrayList<Alarm> removed = new ArrayList<>();
-        for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
-            final Batch b = mAlarmBatches.get(i);
-            removed.addAll(b.remove(whichAlarms));
-            if (b.size() == 0) {
-                mAlarmBatches.remove(i);
-            }
-        }
-        if (!removed.isEmpty()) {
-            mSize -= removed.size();
-            // Not needed if only whole batches were removed, but keeping existing behavior.
-            rebatchAllAlarms();
-        }
-        return removed;
-    }
-
-    @Override
-    public void setAlarmClockRemovalListener(Runnable listener) {
-        mOnAlarmClockRemoved = listener;
-    }
-
-    @Override
-    public Alarm getNextWakeFromIdleAlarm() {
-        for (final Batch batch : mAlarmBatches) {
-            if ((batch.mFlags & AlarmManager.FLAG_WAKE_FROM_IDLE) == 0) {
-                continue;
-            }
-            for (int i = 0; i < batch.size(); i++) {
-                final Alarm a = batch.get(i);
-                if ((a.flags & AlarmManager.FLAG_WAKE_FROM_IDLE) != 0) {
-                    return a;
-                }
-            }
-        }
-        return null;
-    }
-
-    private void rebatchAllAlarms() {
-        final long start = mStatLogger.getTime();
-        final ArrayList<Batch> oldBatches = (ArrayList<Batch>) mAlarmBatches.clone();
-        mAlarmBatches.clear();
-        for (final Batch batch : oldBatches) {
-            for (int i = 0; i < batch.size(); i++) {
-                insertAndBatchAlarm(batch.get(i));
-            }
-        }
-        mStatLogger.logDurationStat(Stats.REBATCH_ALL_ALARMS, start);
-    }
-
-    @Override
-    public int size() {
-        return mSize;
-    }
-
-    @Override
-    public long getNextWakeupDeliveryTime() {
-        for (Batch b : mAlarmBatches) {
-            if (b.hasWakeups()) {
-                return b.mStart;
-            }
-        }
-        return 0;
-    }
-
-    @Override
-    public long getNextDeliveryTime() {
-        if (mAlarmBatches.size() > 0) {
-            return mAlarmBatches.get(0).mStart;
-        }
-        return 0;
-    }
-
-    @Override
-    public ArrayList<Alarm> removePendingAlarms(long nowElapsed) {
-        final ArrayList<Alarm> removedAlarms = new ArrayList<>();
-        while (mAlarmBatches.size() > 0) {
-            final Batch batch = mAlarmBatches.get(0);
-            if (batch.mStart > nowElapsed) {
-                break;
-            }
-            mAlarmBatches.remove(0);
-            for (int i = 0; i < batch.size(); i++) {
-                removedAlarms.add(batch.get(i));
-            }
-        }
-        mSize -= removedAlarms.size();
-        return removedAlarms;
-    }
-
-    @Override
-    public boolean updateAlarmDeliveries(AlarmDeliveryCalculator deliveryCalculator) {
-        boolean changed = false;
-        for (final Batch b : mAlarmBatches) {
-            for (int i = 0; i < b.size(); i++) {
-                changed |= deliveryCalculator.updateAlarmDelivery(b.get(i));
-            }
-        }
-        if (changed) {
-            rebatchAllAlarms();
-        }
-        return changed;
-    }
-
-    @Override
-    public ArrayList<Alarm> asList() {
-        final ArrayList<Alarm> allAlarms = new ArrayList<>();
-        for (final Batch batch : mAlarmBatches) {
-            for (int i = 0; i < batch.size(); i++) {
-                allAlarms.add(batch.get(i));
-            }
-        }
-        return allAlarms;
-    }
-
-    @Override
-    public void dump(IndentingPrintWriter ipw, long nowElapsed, SimpleDateFormat sdf) {
-        ipw.print("Pending alarm batches: ");
-        ipw.println(mAlarmBatches.size());
-        for (Batch b : mAlarmBatches) {
-            ipw.print(b);
-            ipw.println(':');
-            ipw.increaseIndent();
-            dumpAlarmList(ipw, b.mAlarms, nowElapsed, sdf);
-            ipw.decreaseIndent();
-        }
-        mStatLogger.dump(ipw);
-    }
-
-    @Override
-    public void dumpProto(ProtoOutputStream pos, long nowElapsed) {
-        for (Batch b : mAlarmBatches) {
-            b.dumpDebug(pos, AlarmManagerServiceDumpProto.PENDING_ALARM_BATCHES, nowElapsed);
-        }
-    }
-
-    @Override
-    public String getName() {
-        return TAG;
-    }
-
-    @Override
-    public int getCount(Predicate<Alarm> condition) {
-        long start = mStatLogger.getTime();
-
-        int count = 0;
-        for (Batch b : mAlarmBatches) {
-            for (int i = 0; i < b.size(); i++) {
-                if (condition.test(b.get(i))) {
-                    count++;
-                }
-            }
-        }
-        mStatLogger.logDurationStat(Stats.GET_COUNT, start);
-        return count;
-    }
-
-    private void insertAndBatchAlarm(Alarm alarm) {
-        final int whichBatch = ((alarm.flags & AlarmManager.FLAG_STANDALONE) != 0) ? -1
-                : attemptCoalesce(alarm.getWhenElapsed(), alarm.getMaxWhenElapsed());
-
-        if (whichBatch < 0) {
-            addBatch(mAlarmBatches, new Batch(alarm));
-        } else {
-            final Batch batch = mAlarmBatches.get(whichBatch);
-            if (batch.add(alarm)) {
-                // The start time of this batch advanced, so batch ordering may
-                // have just been broken.  Move it to where it now belongs.
-                mAlarmBatches.remove(whichBatch);
-                addBatch(mAlarmBatches, batch);
-            }
-        }
-    }
-
-    static void addBatch(ArrayList<Batch> list, Batch newBatch) {
-        int index = Collections.binarySearch(list, newBatch, sBatchOrder);
-        if (index < 0) {
-            index = 0 - index - 1;
-        }
-        list.add(index, newBatch);
-    }
-
-    // Return the index of the matching batch, or -1 if none found.
-    private int attemptCoalesce(long whenElapsed, long maxWhen) {
-        final int n = mAlarmBatches.size();
-        for (int i = 0; i < n; i++) {
-            Batch b = mAlarmBatches.get(i);
-            if ((b.mFlags & AlarmManager.FLAG_STANDALONE) == 0 && b.canHold(whenElapsed, maxWhen)) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    final class Batch {
-        long mStart;     // These endpoints are always in ELAPSED
-        long mEnd;
-        int mFlags;      // Flags for alarms, such as FLAG_STANDALONE.
-
-        final ArrayList<Alarm> mAlarms = new ArrayList<>();
-
-        Batch(Alarm seed) {
-            mStart = seed.getWhenElapsed();
-            mEnd = clampPositive(seed.getMaxWhenElapsed());
-            mFlags = seed.flags;
-            mAlarms.add(seed);
-        }
-
-        int size() {
-            return mAlarms.size();
-        }
-
-        Alarm get(int index) {
-            return mAlarms.get(index);
-        }
-
-        boolean canHold(long whenElapsed, long maxWhen) {
-            return (mEnd >= whenElapsed) && (mStart <= maxWhen);
-        }
-
-        boolean add(Alarm alarm) {
-            boolean newStart = false;
-            // narrows the batch if necessary; presumes that canHold(alarm) is true
-            int index = Collections.binarySearch(mAlarms, alarm, sIncreasingTimeOrder);
-            if (index < 0) {
-                index = 0 - index - 1;
-            }
-            mAlarms.add(index, alarm);
-            if (DEBUG_BATCH) {
-                Slog.v(TAG, "Adding " + alarm + " to " + this);
-            }
-            if (alarm.getWhenElapsed() > mStart) {
-                mStart = alarm.getWhenElapsed();
-                newStart = true;
-            }
-            if (alarm.getMaxWhenElapsed() < mEnd) {
-                mEnd = alarm.getMaxWhenElapsed();
-            }
-            mFlags |= alarm.flags;
-
-            if (DEBUG_BATCH) {
-                Slog.v(TAG, "    => now " + this);
-            }
-            return newStart;
-        }
-
-        ArrayList<Alarm> remove(Predicate<Alarm> predicate) {
-            final ArrayList<Alarm> removed = new ArrayList<>();
-            long newStart = 0;  // recalculate endpoints as we go
-            long newEnd = Long.MAX_VALUE;
-            int newFlags = 0;
-            for (int i = 0; i < mAlarms.size(); ) {
-                Alarm alarm = mAlarms.get(i);
-                if (predicate.test(alarm)) {
-                    removed.add(mAlarms.remove(i));
-                    if (alarm.alarmClock != null && mOnAlarmClockRemoved != null) {
-                        mOnAlarmClockRemoved.run();
-                    }
-                    if (isTimeTickAlarm(alarm)) {
-                        // This code path is not invoked when delivering alarms, only when removing
-                        // alarms due to the caller cancelling it or getting uninstalled, etc.
-                        Slog.wtf(TAG, "Removed TIME_TICK alarm");
-                    }
-                } else {
-                    if (alarm.getWhenElapsed() > newStart) {
-                        newStart = alarm.getWhenElapsed();
-                    }
-                    if (alarm.getMaxWhenElapsed() < newEnd) {
-                        newEnd = alarm.getMaxWhenElapsed();
-                    }
-                    newFlags |= alarm.flags;
-                    i++;
-                }
-            }
-            if (!removed.isEmpty()) {
-                // commit the new batch bounds
-                mStart = newStart;
-                mEnd = newEnd;
-                mFlags = newFlags;
-            }
-            return removed;
-        }
-
-        boolean hasWakeups() {
-            final int n = mAlarms.size();
-            for (int i = 0; i < n; i++) {
-                Alarm a = mAlarms.get(i);
-                if (a.wakeup) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder b = new StringBuilder(40);
-            b.append("Batch{");
-            b.append(Integer.toHexString(this.hashCode()));
-            b.append(" num=");
-            b.append(size());
-            b.append(" start=");
-            b.append(mStart);
-            b.append(" end=");
-            b.append(mEnd);
-            if (mFlags != 0) {
-                b.append(" flgs=0x");
-                b.append(Integer.toHexString(mFlags));
-            }
-            b.append('}');
-            return b.toString();
-        }
-
-        public void dumpDebug(ProtoOutputStream proto, long fieldId, long nowElapsed) {
-            final long token = proto.start(fieldId);
-
-            proto.write(BatchProto.START_REALTIME, mStart);
-            proto.write(BatchProto.END_REALTIME, mEnd);
-            proto.write(BatchProto.FLAGS, mFlags);
-            for (Alarm a : mAlarms) {
-                a.dumpDebug(proto, BatchProto.ALARMS, nowElapsed);
-            }
-
-            proto.end(token);
-        }
-    }
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
index 68801bc..dd80acb 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
@@ -303,7 +303,9 @@
                     getStartActionId(job), String.valueOf(job.getJobId()));
             mVerb = VERB_BINDING;
             scheduleOpTimeOutLocked();
-            final Intent intent = new Intent().setComponent(job.getServiceComponent());
+            // Use FLAG_FROM_BACKGROUND to avoid resetting the bad-app tracking.
+            final Intent intent = new Intent().setComponent(job.getServiceComponent())
+                    .setFlags(Intent.FLAG_FROM_BACKGROUND);
             boolean binding = false;
             try {
                 final int bindFlags;
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java
new file mode 100644
index 0000000..687693c
--- /dev/null
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.job.controllers;
+
+import static android.text.format.DateUtils.HOUR_IN_MILLIS;
+import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
+
+import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
+
+import android.annotation.ElapsedRealtimeLong;
+import android.annotation.NonNull;
+import android.app.job.JobInfo;
+import android.content.Context;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.util.ArraySet;
+import android.util.IndentingPrintWriter;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.JobSchedulerBackgroundThread;
+import com.android.server.job.JobSchedulerService;
+import com.android.server.utils.AlarmQueue;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Predicate;
+
+/**
+ * Controller that tracks the number of flexible constraints being actively satisfied.
+ * Drops constraint for TOP apps and lowers number of required constraints with time.
+ *
+ * TODO: Plug in to other controllers (b/239047584), handle prefetch (b/238887951)
+ */
+public final class FlexibilityController extends StateController {
+    /**
+     * List of all potential flexible constraints
+     */
+    @VisibleForTesting
+    static final int FLEXIBLE_CONSTRAINTS = JobStatus.CONSTRAINT_BATTERY_NOT_LOW
+            | JobStatus.CONSTRAINT_CHARGING
+            | JobStatus.CONSTRAINT_CONNECTIVITY
+            | JobStatus.CONSTRAINT_IDLE;
+
+    /** Hard cutoff to remove flexible constraints */
+    private static final long DEADLINE_PROXIMITY_LIMIT_MS = 15 * MINUTE_IN_MILLIS;
+
+    /**
+     * Keeps track of what flexible constraints are satisfied at the moment.
+     * Is updated by the other controllers.
+     */
+    private int mSatisfiedFlexibleConstraints;
+
+    @VisibleForTesting
+    @GuardedBy("mLock")
+    final FlexibilityTracker mFlexibilityTracker;
+
+    private final FlexibilityAlarmQueue mFlexibilityAlarmQueue;
+    private final long mMinTimeBetweenAlarmsMs = MINUTE_IN_MILLIS;
+
+    /**
+     * The percent of a Jobs lifecycle to drop number of required constraints.
+     * mPercentToDropConstraints[i] denotes that at x% of a Jobs lifecycle,
+     * the controller should have i+1 constraints dropped.
+     */
+    private final int[] mPercentToDropConstraints = {50, 60, 70, 80};
+
+    /** The default deadline that all flexible constraints should be dropped by. */
+    private final long mDefaultFlexibleDeadline = 72 * HOUR_IN_MILLIS;
+
+    public FlexibilityController(JobSchedulerService service) {
+        super(service);
+        mFlexibilityTracker = new FlexibilityTracker(FLEXIBLE_CONSTRAINTS);
+        mFlexibilityAlarmQueue = new FlexibilityAlarmQueue(
+                mContext, JobSchedulerBackgroundThread.get().getLooper());
+    }
+
+    /**
+     * StateController interface
+     */
+    @Override
+    public void maybeStartTrackingJobLocked(JobStatus js, JobStatus lastJob) {
+        if (js.hasFlexibilityConstraint()) {
+            mFlexibilityTracker.add(js);
+            js.setTrackingController(JobStatus.TRACKING_FLEXIBILITY);
+            final long nowElapsed = sElapsedRealtimeClock.millis();
+            js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js));
+            mFlexibilityAlarmQueue.addAlarm(js, getNextConstraintDropTimeElapsed(js));
+        }
+    }
+
+    @Override
+    public void maybeStopTrackingJobLocked(JobStatus js, JobStatus incomingJob, boolean forUpdate) {
+        if (js.clearTrackingController(JobStatus.TRACKING_FLEXIBILITY)) {
+            mFlexibilityAlarmQueue.removeAlarmForKey(js);
+            mFlexibilityTracker.remove(js);
+        }
+    }
+
+    /** Checks if the flexibility constraint is actively satisfied for a given job. */
+    @VisibleForTesting
+    boolean isFlexibilitySatisfiedLocked(JobStatus js) {
+        synchronized (mLock) {
+            return mService.getUidBias(js.getUid()) == JobInfo.BIAS_TOP_APP
+                    || mService.isCurrentlyRunningLocked(js)
+                    || getNumSatisfiedRequiredConstraintsLocked(js)
+                    >= js.getNumRequiredFlexibleConstraints();
+        }
+    }
+
+    @VisibleForTesting
+    @GuardedBy("mLock")
+    int getNumSatisfiedRequiredConstraintsLocked(JobStatus js) {
+        return Integer.bitCount(js.getFlexibleConstraints() & mSatisfiedFlexibleConstraints);
+    }
+
+    /**
+     * Sets the controller's constraint to a given state.
+     * Changes flexibility constraint satisfaction for affected jobs.
+     */
+    @VisibleForTesting
+    void setConstraintSatisfied(int constraint, boolean state) {
+        synchronized (mLock) {
+            final boolean old = (mSatisfiedFlexibleConstraints & constraint) != 0;
+            if (old == state) {
+                return;
+            }
+
+            final int prevSatisfied = Integer.bitCount(mSatisfiedFlexibleConstraints);
+            mSatisfiedFlexibleConstraints =
+                    (mSatisfiedFlexibleConstraints & ~constraint) | (state ? constraint : 0);
+            final int curSatisfied = Integer.bitCount(mSatisfiedFlexibleConstraints);
+
+            // Only the max of the number of required flexible constraints will need to be updated
+            // The rest did not have a change in state and are still satisfied or unsatisfied.
+            final int numConstraintsToUpdate = Math.max(curSatisfied, prevSatisfied);
+
+            final ArraySet<JobStatus> jobs = mFlexibilityTracker.getJobsByNumRequiredConstraints(
+                    numConstraintsToUpdate);
+            final long nowElapsed = sElapsedRealtimeClock.millis();
+
+            for (int i = 0; i < jobs.size(); i++) {
+                JobStatus js = jobs.valueAt(i);
+                js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js));
+            }
+        }
+    }
+
+    /** Checks if the given constraint is satisfied in the flexibility controller. */
+    @VisibleForTesting
+    boolean isConstraintSatisfied(int constraint) {
+        return (mSatisfiedFlexibleConstraints & constraint) != 0;
+    }
+
+    /** The elapsed time that marks when the next constraint should be dropped. */
+    @VisibleForTesting
+    @ElapsedRealtimeLong
+    long getNextConstraintDropTimeElapsed(JobStatus js) {
+        final long earliest = js.getEarliestRunTime() == JobStatus.NO_EARLIEST_RUNTIME
+                ? js.enqueueTime : js.getEarliestRunTime();
+        final long latest = js.getLatestRunTimeElapsed() == JobStatus.NO_LATEST_RUNTIME
+                ? earliest + mDefaultFlexibleDeadline
+                : js.getLatestRunTimeElapsed();
+        final int percent = mPercentToDropConstraints[js.getNumDroppedFlexibleConstraints()];
+        final long percentInTime = ((latest - earliest) * percent) / 100;
+        return earliest + percentInTime;
+    }
+
+    @Override
+    @GuardedBy("mLock")
+    public void onUidBiasChangedLocked(int uid, int prevBias, int newBias) {
+        if (prevBias != JobInfo.BIAS_TOP_APP && newBias != JobInfo.BIAS_TOP_APP) {
+            return;
+        }
+        final long nowElapsed = sElapsedRealtimeClock.millis();
+        List<JobStatus> jobsByUid = mService.getJobStore().getJobsByUid(uid);
+        for (int i = 0; i < jobsByUid.size(); i++) {
+            JobStatus js = jobsByUid.get(i);
+            if (js.hasFlexibilityConstraint()) {
+                js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js));
+            }
+        }
+    }
+
+    @VisibleForTesting
+    class FlexibilityTracker {
+        final ArrayList<ArraySet<JobStatus>> mTrackedJobs;
+
+        FlexibilityTracker(int flexibleConstraints) {
+            mTrackedJobs = new ArrayList<>();
+            int numFlexibleConstraints = Integer.bitCount(flexibleConstraints);
+            for (int i = 0; i <= numFlexibleConstraints; i++) {
+                mTrackedJobs.add(new ArraySet<JobStatus>());
+            }
+        }
+
+        /** Gets every tracked job with a given number of required constraints. */
+        public ArraySet<JobStatus> getJobsByNumRequiredConstraints(int numRequired) {
+            return mTrackedJobs.get(numRequired - 1);
+        }
+
+        /** adds a JobStatus object based on number of required flexible constraints. */
+        public void add(JobStatus js) {
+            if (js.getNumRequiredFlexibleConstraints() <= 0) {
+                return;
+            }
+            mTrackedJobs.get(js.getNumRequiredFlexibleConstraints() - 1).add(js);
+        }
+
+        /** Removes a JobStatus object. */
+        public void remove(JobStatus js) {
+            if (js.getNumRequiredFlexibleConstraints() == 0) {
+                return;
+            }
+            mTrackedJobs.get(js.getNumRequiredFlexibleConstraints() - 1).remove(js);
+        }
+
+        /** Returns all tracked jobs. */
+        public ArrayList<ArraySet<JobStatus>> getArrayList() {
+            return mTrackedJobs;
+        }
+
+        /**
+         * Adjusts number of required flexible constraints and sorts it into the tracker.
+         * Returns false if the job status's number of flexible constraints is now 0.
+         * Jobs with 0 required flexible constraints are removed from the tracker.
+         */
+        public boolean adjustJobsRequiredConstraints(JobStatus js, int n) {
+            remove(js);
+            js.adjustNumRequiredFlexibleConstraints(n);
+            final long nowElapsed = sElapsedRealtimeClock.millis();
+            js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js));
+            if (js.getNumRequiredFlexibleConstraints() <= 0) {
+                maybeStopTrackingJobLocked(js, null, false);
+                return false;
+            }
+            add(js);
+            return true;
+        }
+
+        public void dump(IndentingPrintWriter pw, Predicate<JobStatus> predicate) {
+            for (int i = 0; i < mTrackedJobs.size(); i++) {
+                ArraySet<JobStatus> jobs = mTrackedJobs.get(i);
+                for (int j = 0; j < mTrackedJobs.size(); j++) {
+                    final JobStatus js = jobs.valueAt(j);
+                    if (!predicate.test(js)) {
+                        continue;
+                    }
+                    pw.print("#");
+                    js.printUniqueId(pw);
+                    pw.print(" from ");
+                    UserHandle.formatUid(pw, js.getSourceUid());
+                    pw.println();
+                }
+            }
+        }
+    }
+
+    private class FlexibilityAlarmQueue extends AlarmQueue<JobStatus> {
+        private FlexibilityAlarmQueue(Context context, Looper looper) {
+            super(context, looper, "*job.flexibility_check*",
+                    "Flexible Constraint Check", false, mMinTimeBetweenAlarmsMs);
+        }
+
+        @Override
+        protected boolean isForUser(@NonNull JobStatus js, int userId) {
+            return js.getSourceUserId() == userId;
+        }
+
+        @Override
+        protected void processExpiredAlarms(@NonNull ArraySet<JobStatus> expired) {
+            synchronized (mLock) {
+                JobStatus js;
+                for (int i = 0; i < expired.size(); i++) {
+                    js = expired.valueAt(i);
+                    long time = getNextConstraintDropTimeElapsed(js);
+                    if (js.getLatestRunTimeElapsed() - time < DEADLINE_PROXIMITY_LIMIT_MS) {
+                        mFlexibilityTracker.adjustJobsRequiredConstraints(js,
+                                -js.getNumRequiredFlexibleConstraints());
+                        continue;
+                    }
+                    if (mFlexibilityTracker.adjustJobsRequiredConstraints(js, -1)) {
+                        mFlexibilityAlarmQueue.addAlarm(js, time);
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    @GuardedBy("mLock")
+    public void dumpControllerStateLocked(IndentingPrintWriter pw, Predicate<JobStatus> predicate) {
+        pw.println("# Constraints Satisfied: " + Integer.bitCount(mSatisfiedFlexibleConstraints));
+        pw.println();
+
+        mFlexibilityTracker.dump(pw, predicate);
+    }
+}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index e0f58e3..41cf4212 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -16,6 +16,9 @@
 
 package com.android.server.job.controllers;
 
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
+import static android.text.format.DateUtils.HOUR_IN_MILLIS;
+
 import static com.android.server.job.JobSchedulerService.ACTIVE_INDEX;
 import static com.android.server.job.JobSchedulerService.EXEMPTED_INDEX;
 import static com.android.server.job.JobSchedulerService.NEVER_INDEX;
@@ -99,6 +102,7 @@
     static final int CONSTRAINT_WITHIN_QUOTA = 1 << 24;      // Implicit constraint
     static final int CONSTRAINT_PREFETCH = 1 << 23;
     static final int CONSTRAINT_BACKGROUND_NOT_RESTRICTED = 1 << 22; // Implicit constraint
+    static final int CONSTRAINT_FLEXIBLE = 1 << 21; // Implicit constraint
 
     // The following set of dynamic constraints are for specific use cases (as explained in their
     // relative naming and comments). Right now, they apply different constraints, which is fine,
@@ -118,6 +122,22 @@
                     | CONSTRAINT_IDLE;
 
     /**
+     * The set of constraints that are required to satisfy flexible constraints.
+     * Constraints explicitly requested by the job will not be added to the set.
+     */
+    private int mFlexibleConstraints;
+
+    /**
+     * Keeps track of how many flexible constraints must be satisfied for the job to execute.
+     */
+    private int mNumRequiredFlexibleConstraints;
+
+    /**
+     * Number of required flexible constraints that have been dropped.
+     */
+    private int mNumDroppedFlexibleConstraints;
+
+    /**
      * The additional set of dynamic constraints that must be met if this is an expedited job that
      * had a long enough run while the device was Dozing or in battery saver.
      */
@@ -305,6 +325,12 @@
     public static final int TRACKING_QUOTA = 1 << 6;
 
     /**
+     * Flag for {@link #trackingControllers}: the flexibility controller is currently tracking this
+     * job.
+     */
+    public static final int TRACKING_FLEXIBILITY = 1 << 7;
+
+    /**
      * Bit mask of controllers that are currently tracking the job.
      */
     private int trackingControllers;
@@ -318,6 +344,8 @@
      */
     public static final int INTERNAL_FLAG_HAS_FOREGROUND_EXEMPTION = 1 << 0;
 
+    /** Minimum difference between start and end time to have flexible constraint */
+    private static final long MIN_WINDOW_FOR_FLEXIBILITY_MS = HOUR_IN_MILLIS;
     /**
      * Versatile, persistable flags for a job that's updated within the system server,
      * as opposed to {@link JobInfo#flags} that's set by callers.
@@ -525,6 +553,33 @@
             }
         }
         mHasExemptedMediaUrisOnly = exemptedMediaUrisOnly;
+
+        if (isRequestedExpeditedJob()
+                || ((latestRunTimeElapsedMillis - earliestRunTimeElapsedMillis)
+                < MIN_WINDOW_FOR_FLEXIBILITY_MS)
+                || job.isPrefetch()) {
+            mFlexibleConstraints = 0;
+        } else {
+            if ((requiredConstraints & CONSTRAINT_CHARGING) == 0) {
+                mFlexibleConstraints |= CONSTRAINT_CHARGING;
+            }
+            if ((requiredConstraints & CONSTRAINT_BATTERY_NOT_LOW) == 0) {
+                mFlexibleConstraints |= CONSTRAINT_BATTERY_NOT_LOW;
+            }
+            if ((requiredConstraints & CONSTRAINT_IDLE) == 0) {
+                mFlexibleConstraints |= CONSTRAINT_IDLE;
+            }
+            if (job.getRequiredNetwork() != null
+                    && !job.getRequiredNetwork().hasCapability(NET_CAPABILITY_NOT_METERED)) {
+                mFlexibleConstraints |= CONSTRAINT_CONNECTIVITY;
+            }
+        }
+        if (mFlexibleConstraints != 0) {
+            // TODO(b/239047584): Uncomment once Flexibility Controller is plugged in.
+            // requiredConstraints |= CONSTRAINT_FLEXIBLE;
+            mNumRequiredFlexibleConstraints = Integer.bitCount(mFlexibleConstraints);
+        }
+
         this.requiredConstraints = requiredConstraints;
         mRequiredConstraintsOfInterest = requiredConstraints & CONSTRAINTS_OF_INTEREST;
         addDynamicConstraints(dynamicConstraints);
@@ -1082,12 +1137,35 @@
         return hasConstraint(CONSTRAINT_IDLE);
     }
 
+    /** Returns true if the job has a prefetch constraint */
+    public boolean hasPrefetchConstraint() {
+        return hasConstraint(CONSTRAINT_PREFETCH);
+    }
+
     public boolean hasContentTriggerConstraint() {
         // No need to check mDynamicConstraints since content trigger will only be in that list if
         // it's already in the requiredConstraints list.
         return (requiredConstraints&CONSTRAINT_CONTENT_TRIGGER) != 0;
     }
 
+    /** Returns true if the job has flexible job constraints enabled */
+    public boolean hasFlexibilityConstraint() {
+        return (requiredConstraints & CONSTRAINT_FLEXIBLE) != 0;
+    }
+
+    /** Returns the number of flexible job constraints required to be satisfied to execute */
+    public int getNumRequiredFlexibleConstraints() {
+        return mNumRequiredFlexibleConstraints;
+    }
+
+    /**
+     * Returns the number of required flexible job constraints that have been dropped with time.
+     * The lower this number is the easier it is for the flexibility constraint to be satisfied.
+     */
+    public int getNumDroppedFlexibleConstraints() {
+        return mNumDroppedFlexibleConstraints;
+    }
+
     /**
      * Checks both {@link #requiredConstraints} and {@link #mDynamicConstraints} to see if this job
      * requires the specified constraint.
@@ -1128,6 +1206,10 @@
         return mOriginalLatestRunTimeElapsedMillis;
     }
 
+    public int getFlexibleConstraints() {
+        return mFlexibleConstraints;
+    }
+
     public void setOriginalLatestRunTimeElapsed(long latestRunTimeElapsed) {
         mOriginalLatestRunTimeElapsedMillis = latestRunTimeElapsed;
     }
@@ -1301,6 +1383,11 @@
         return false;
     }
 
+    /** @return true if the constraint was changed, false otherwise. */
+    boolean setFlexibilityConstraintSatisfied(final long nowElapsed, boolean state) {
+        return setConstraintSatisfied(CONSTRAINT_FLEXIBLE, nowElapsed, state);
+    }
+
     /**
      * Sets whether or not this job is approved to be treated as an expedited job based on quota
      * policy.
@@ -1490,6 +1577,18 @@
         trackingControllers |= which;
     }
 
+    /** Adjusts the number of required flexible constraints by the given number */
+    public void adjustNumRequiredFlexibleConstraints(int adjustment) {
+        mNumRequiredFlexibleConstraints += adjustment;
+        if (mNumRequiredFlexibleConstraints < 0) {
+            mNumRequiredFlexibleConstraints = 0;
+        }
+        mNumDroppedFlexibleConstraints -= adjustment;
+        if (mNumDroppedFlexibleConstraints < 0) {
+            mNumDroppedFlexibleConstraints = 0;
+        }
+    }
+
     /**
      * Add additional constraints to prevent this job from running when doze or battery saver are
      * active.
@@ -1650,12 +1749,14 @@
     /** All constraints besides implicit and deadline. */
     static final int CONSTRAINTS_OF_INTEREST = CONSTRAINT_CHARGING | CONSTRAINT_BATTERY_NOT_LOW
             | CONSTRAINT_STORAGE_NOT_LOW | CONSTRAINT_TIMING_DELAY | CONSTRAINT_CONNECTIVITY
-            | CONSTRAINT_IDLE | CONSTRAINT_CONTENT_TRIGGER | CONSTRAINT_PREFETCH;
+            | CONSTRAINT_IDLE | CONSTRAINT_CONTENT_TRIGGER | CONSTRAINT_PREFETCH
+            | CONSTRAINT_FLEXIBLE;
 
     // Soft override covers all non-"functional" constraints
     static final int SOFT_OVERRIDE_CONSTRAINTS =
             CONSTRAINT_CHARGING | CONSTRAINT_BATTERY_NOT_LOW | CONSTRAINT_STORAGE_NOT_LOW
-                    | CONSTRAINT_TIMING_DELAY | CONSTRAINT_IDLE | CONSTRAINT_PREFETCH;
+                    | CONSTRAINT_TIMING_DELAY | CONSTRAINT_IDLE | CONSTRAINT_PREFETCH
+                    | CONSTRAINT_FLEXIBLE;
 
     /** Returns true whenever all dynamically set constraints are satisfied. */
     public boolean areDynamicConstraintsSatisfied() {
diff --git a/config/boot-image-profile-extra.txt b/config/boot-image-profile-extra.txt
new file mode 100644
index 0000000..e3b187e
--- /dev/null
+++ b/config/boot-image-profile-extra.txt
@@ -0,0 +1,21 @@
+#
+# Copyright (C) 2022 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.
+#
+
+# A list of methods that are found to be latency sensitive. We have this manual
+# due to current limitations of our boot image profiling, where knowing what
+# methods are latency sensitive is difficult. For example, this method is executed
+# in the system server, not on the UI thread of an app.
+HSPLandroid/graphics/Color;->luminance()F
diff --git a/core/api/current.txt b/core/api/current.txt
index bb32647..1e1a4a6 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -7051,6 +7051,7 @@
     method public void setRunAsMonkey(boolean);
     method public void setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo);
     method public android.graphics.Bitmap takeScreenshot();
+    method @Nullable public android.graphics.Bitmap takeScreenshot(@NonNull android.view.Window);
     method public void waitForIdle(long, long) throws java.util.concurrent.TimeoutException;
     field public static final int FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES = 1; // 0x1
     field public static final int FLAG_DONT_USE_ACCESSIBILITY = 2; // 0x2
@@ -14928,6 +14929,8 @@
     method public android.graphics.PathEffect getPathEffect();
     method public float getRunAdvance(char[], int, int, int, int, boolean, int);
     method public float getRunAdvance(CharSequence, int, int, int, int, boolean, int);
+    method public float getRunCharacterAdvance(@NonNull char[], int, int, int, int, boolean, int, @Nullable float[], int);
+    method public float getRunCharacterAdvance(@NonNull CharSequence, int, int, int, int, boolean, int, @Nullable float[], int);
     method public android.graphics.Shader getShader();
     method @ColorInt public int getShadowLayerColor();
     method @ColorLong public long getShadowLayerColorLong();
@@ -31159,7 +31162,7 @@
     method @Deprecated public static void changeDebugPort(int);
     method public static void dumpHprofData(String) throws java.io.IOException;
     method public static boolean dumpService(String, java.io.FileDescriptor, String[]);
-    method public static void enableEmulatorTraceOutput();
+    method @Deprecated public static void enableEmulatorTraceOutput();
     method public static int getBinderDeathObjectCount();
     method public static int getBinderLocalObjectCount();
     method public static int getBinderProxyObjectCount();
@@ -51083,6 +51086,7 @@
     method public void addOnTouchModeChangeListener(android.view.ViewTreeObserver.OnTouchModeChangeListener);
     method public void addOnWindowAttachListener(android.view.ViewTreeObserver.OnWindowAttachListener);
     method public void addOnWindowFocusChangeListener(android.view.ViewTreeObserver.OnWindowFocusChangeListener);
+    method public void addOnWindowVisibilityChangeListener(@NonNull android.view.ViewTreeObserver.OnWindowVisibilityChangeListener);
     method public void dispatchOnDraw();
     method public void dispatchOnGlobalLayout();
     method public boolean dispatchOnPreDraw();
@@ -51098,6 +51102,7 @@
     method public void removeOnTouchModeChangeListener(android.view.ViewTreeObserver.OnTouchModeChangeListener);
     method public void removeOnWindowAttachListener(android.view.ViewTreeObserver.OnWindowAttachListener);
     method public void removeOnWindowFocusChangeListener(android.view.ViewTreeObserver.OnWindowFocusChangeListener);
+    method public void removeOnWindowVisibilityChangeListener(@NonNull android.view.ViewTreeObserver.OnWindowVisibilityChangeListener);
     method public boolean unregisterFrameCommitCallback(@NonNull Runnable);
   }
 
@@ -51134,6 +51139,10 @@
     method public void onWindowFocusChanged(boolean);
   }
 
+  public static interface ViewTreeObserver.OnWindowVisibilityChangeListener {
+    method public void onWindowVisibilityChanged(int);
+  }
+
   public abstract class Window {
     ctor public Window(@UiContext android.content.Context);
     method public abstract void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
@@ -51530,6 +51539,7 @@
     method public default boolean isCrossWindowBlurEnabled();
     method public default void removeCrossWindowBlurEnabledListener(@NonNull java.util.function.Consumer<java.lang.Boolean>);
     method public void removeViewImmediate(android.view.View);
+    field public static final String PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE = "android.window.PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE";
   }
 
   public static class WindowManager.BadTokenException extends java.lang.RuntimeException {
@@ -53231,11 +53241,11 @@
   public final class InputMethodManager {
     method public void dispatchKeyEventFromInputMethod(@Nullable android.view.View, @NonNull android.view.KeyEvent);
     method public void displayCompletions(android.view.View, android.view.inputmethod.CompletionInfo[]);
-    method public android.view.inputmethod.InputMethodSubtype getCurrentInputMethodSubtype();
-    method public java.util.List<android.view.inputmethod.InputMethodInfo> getEnabledInputMethodList();
-    method public java.util.List<android.view.inputmethod.InputMethodSubtype> getEnabledInputMethodSubtypeList(android.view.inputmethod.InputMethodInfo, boolean);
-    method public java.util.List<android.view.inputmethod.InputMethodInfo> getInputMethodList();
-    method public android.view.inputmethod.InputMethodSubtype getLastInputMethodSubtype();
+    method @Nullable public android.view.inputmethod.InputMethodSubtype getCurrentInputMethodSubtype();
+    method @NonNull public java.util.List<android.view.inputmethod.InputMethodInfo> getEnabledInputMethodList();
+    method @NonNull public java.util.List<android.view.inputmethod.InputMethodSubtype> getEnabledInputMethodSubtypeList(@Nullable android.view.inputmethod.InputMethodInfo, boolean);
+    method @NonNull public java.util.List<android.view.inputmethod.InputMethodInfo> getInputMethodList();
+    method @Nullable public android.view.inputmethod.InputMethodSubtype getLastInputMethodSubtype();
     method public java.util.Map<android.view.inputmethod.InputMethodInfo,java.util.List<android.view.inputmethod.InputMethodSubtype>> getShortcutInputMethodsAndSubtypes();
     method @Deprecated public void hideSoftInputFromInputMethod(android.os.IBinder, int);
     method public boolean hideSoftInputFromWindow(android.os.IBinder, int);
@@ -53251,12 +53261,12 @@
     method @Deprecated public boolean isWatchingCursor(android.view.View);
     method public void restartInput(android.view.View);
     method public void sendAppPrivateCommand(android.view.View, String, android.os.Bundle);
-    method @Deprecated public void setAdditionalInputMethodSubtypes(String, android.view.inputmethod.InputMethodSubtype[]);
+    method @Deprecated public void setAdditionalInputMethodSubtypes(@NonNull String, @NonNull android.view.inputmethod.InputMethodSubtype[]);
     method @Deprecated @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean setCurrentInputMethodSubtype(android.view.inputmethod.InputMethodSubtype);
     method @Deprecated public void setInputMethod(android.os.IBinder, String);
     method @Deprecated public void setInputMethodAndSubtype(@NonNull android.os.IBinder, String, android.view.inputmethod.InputMethodSubtype);
     method @Deprecated public boolean shouldOfferSwitchingToNextInputMethod(android.os.IBinder);
-    method public void showInputMethodAndSubtypeEnabler(String);
+    method public void showInputMethodAndSubtypeEnabler(@Nullable String);
     method public void showInputMethodPicker();
     method public boolean showSoftInput(android.view.View, int);
     method public boolean showSoftInput(android.view.View, int, android.os.ResultReceiver);
@@ -57694,7 +57704,7 @@
     method public final void setSpannableFactory(android.text.Spannable.Factory);
     method public final void setText(CharSequence);
     method public void setText(CharSequence, android.widget.TextView.BufferType);
-    method public final void setText(char[], int, int);
+    method public final void setText(@NonNull char[], int, int);
     method public final void setText(@StringRes int);
     method public final void setText(@StringRes int, android.widget.TextView.BufferType);
     method public void setTextAppearance(@StyleRes int);
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 8a0acd5..572101c 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -5958,7 +5958,7 @@
     method public int getEphemerisSource();
     method @FloatRange public double getIonoDelayMeters();
     method @IntRange(from=0, to=1023) public int getIssueOfDataClock();
-    method @IntRange(from=0, to=255) public int getIssueOfDataEphemeris();
+    method @IntRange(from=0, to=1023) public int getIssueOfDataEphemeris();
     method @Nullable public android.location.SatellitePvt.PositionEcef getPositionEcef();
     method @IntRange(from=0) public long getTimeOfClockSeconds();
     method @IntRange(from=0) public long getTimeOfEphemerisSeconds();
@@ -5986,7 +5986,7 @@
     method @NonNull public android.location.SatellitePvt.Builder setEphemerisSource(int);
     method @NonNull public android.location.SatellitePvt.Builder setIonoDelayMeters(@FloatRange(from=0.0f, to=100.0f) double);
     method @NonNull public android.location.SatellitePvt.Builder setIssueOfDataClock(@IntRange(from=0, to=1023) int);
-    method @NonNull public android.location.SatellitePvt.Builder setIssueOfDataEphemeris(@IntRange(from=0, to=255) int);
+    method @NonNull public android.location.SatellitePvt.Builder setIssueOfDataEphemeris(@IntRange(from=0, to=1023) int);
     method @NonNull public android.location.SatellitePvt.Builder setPositionEcef(@NonNull android.location.SatellitePvt.PositionEcef);
     method @NonNull public android.location.SatellitePvt.Builder setTimeOfClockSeconds(@IntRange(from=0) long);
     method @NonNull public android.location.SatellitePvt.Builder setTimeOfEphemerisSeconds(@IntRange(from=0) long);
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 631f0fb..b13ebf3 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -419,6 +419,7 @@
   public class TaskInfo {
     method public boolean containsLaunchCookie(@NonNull android.os.IBinder);
     method @NonNull public android.content.res.Configuration getConfiguration();
+    method public int getDisplayId();
     method public int getParentTaskId();
     method @Nullable public android.app.PictureInPictureParams getPictureInPictureParams();
     method @NonNull public android.window.WindowContainerToken getToken();
@@ -439,7 +440,6 @@
     method @Deprecated public boolean revokeRuntimePermission(String, String, android.os.UserHandle);
     method public void syncInputTransactions();
     method public void syncInputTransactions(boolean);
-    method @Nullable public android.graphics.Bitmap takeScreenshot(@NonNull android.view.Window);
     field @NonNull public static final java.util.Set<java.lang.String> ALL_PERMISSIONS;
   }
 
@@ -823,7 +823,7 @@
   }
 
   public abstract class PackageManager {
-    method @Nullable public String getContentCaptureServicePackageName();
+    method @Deprecated @Nullable public final String getContentCaptureServicePackageName();
     method @Nullable public String getDefaultTextClassifierPackageName();
     method @RequiresPermission(android.Manifest.permission.INJECT_EVENTS) public android.os.IBinder getHoldLockToken();
     method public abstract int getInstallReason(@NonNull String, @NonNull android.os.UserHandle);
@@ -3109,6 +3109,7 @@
   }
 
   public final class InputMethodManager {
+    method public void addVirtualStylusIdForTestSession();
     method public int getDisplayId();
     method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public java.util.List<android.view.inputmethod.InputMethodInfo> getInputMethodListAsUser(int);
     method public boolean hasActiveInputConnection(@Nullable android.view.View);
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index c17fbf1..90b7828 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -2590,9 +2590,9 @@
                     return;
                 }
                 final HardwareBuffer hardwareBuffer =
-                        result.getParcelable(KEY_ACCESSIBILITY_SCREENSHOT_HARDWAREBUFFER);
+                        result.getParcelable(KEY_ACCESSIBILITY_SCREENSHOT_HARDWAREBUFFER, android.hardware.HardwareBuffer.class);
                 final ParcelableColorSpace colorSpace =
-                        result.getParcelable(KEY_ACCESSIBILITY_SCREENSHOT_COLORSPACE);
+                        result.getParcelable(KEY_ACCESSIBILITY_SCREENSHOT_COLORSPACE, android.graphics.ParcelableColorSpace.class);
                 final ScreenshotResult screenshot = new ScreenshotResult(hardwareBuffer,
                         colorSpace.getColorSpace(),
                         result.getLong(KEY_ACCESSIBILITY_SCREENSHOT_TIMESTAMP));
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index 530de0f..2e89ce8 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -79,7 +79,6 @@
  * @attr ref android.R.styleable#AccessibilityService_accessibilityEventTypes
  * @attr ref android.R.styleable#AccessibilityService_accessibilityFeedbackType
  * @attr ref android.R.styleable#AccessibilityService_accessibilityFlags
- * @attr ref android.R.styleable#AccessibilityService_canRequestEnhancedWebAccessibility
  * @attr ref android.R.styleable#AccessibilityService_canRequestFilterKeyEvents
  * @attr ref android.R.styleable#AccessibilityService_canRequestTouchExplorationMode
  * @attr ref android.R.styleable#AccessibilityService_canRetrieveWindowContent
@@ -1424,8 +1423,6 @@
                 return "CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT";
             case CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION:
                 return "CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION";
-            case CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY:
-                return "CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY";
             case CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS:
                 return "CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS";
             case CAPABILITY_CAN_CONTROL_MAGNIFICATION:
diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java
index 3807b50..f29998a 100644
--- a/core/java/android/accounts/AbstractAccountAuthenticator.java
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -290,10 +290,10 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
         @Override
         public void editProperties(IAccountAuthenticatorResponse response,
                 String accountType) throws RemoteException {
-            checkBinderPermission();
             try {
                 final Bundle result = AbstractAccountAuthenticator.this.editProperties(
                     new AccountAuthenticatorResponse(response), accountType);
@@ -305,10 +305,10 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
         @Override
         public void hasFeatures(IAccountAuthenticatorResponse response,
                 Account account, String[] features) throws RemoteException {
-            checkBinderPermission();
             try {
                 final Bundle result = AbstractAccountAuthenticator.this.hasFeatures(
                     new AccountAuthenticatorResponse(response), account, features);
@@ -320,10 +320,10 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
         @Override
         public void getAccountRemovalAllowed(IAccountAuthenticatorResponse response,
                 Account account) throws RemoteException {
-            checkBinderPermission();
             try {
                 final Bundle result = AbstractAccountAuthenticator.this.getAccountRemovalAllowed(
                     new AccountAuthenticatorResponse(response), account);
@@ -335,10 +335,10 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
         @Override
         public void getAccountCredentialsForCloning(IAccountAuthenticatorResponse response,
                 Account account) throws RemoteException {
-            checkBinderPermission();
             try {
                 final Bundle result =
                         AbstractAccountAuthenticator.this.getAccountCredentialsForCloning(
@@ -351,11 +351,11 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
         @Override
         public void addAccountFromCredentials(IAccountAuthenticatorResponse response,
                 Account account,
                 Bundle accountCredentials) throws RemoteException {
-            checkBinderPermission();
             try {
                 final Bundle result =
                         AbstractAccountAuthenticator.this.addAccountFromCredentials(
@@ -465,12 +465,12 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCOUNT_MANAGER)
         @Override
         public void isCredentialsUpdateSuggested(
                 IAccountAuthenticatorResponse response,
                 Account account,
                 String statusToken) throws RemoteException {
-            checkBinderPermission();
             try {
                 final Bundle result = AbstractAccountAuthenticator.this
                         .isCredentialsUpdateSuggested(
@@ -938,7 +938,7 @@
         String authTokenType = sessionBundle.getString(KEY_AUTH_TOKEN_TYPE);
         Bundle options = sessionBundle.getBundle(KEY_OPTIONS);
         String[] requiredFeatures = sessionBundle.getStringArray(KEY_REQUIRED_FEATURES);
-        Account account = sessionBundle.getParcelable(KEY_ACCOUNT);
+        Account account = sessionBundle.getParcelable(KEY_ACCOUNT, android.accounts.Account.class);
         boolean containsKeyAccount = sessionBundle.containsKey(KEY_ACCOUNT);
 
         // Actual options passed to add account or update credentials flow.
diff --git a/core/java/android/accounts/AccountAuthenticatorActivity.java b/core/java/android/accounts/AccountAuthenticatorActivity.java
index 65ba35f..5f620f3 100644
--- a/core/java/android/accounts/AccountAuthenticatorActivity.java
+++ b/core/java/android/accounts/AccountAuthenticatorActivity.java
@@ -60,7 +60,7 @@
         super.onCreate(icicle);
 
         mAccountAuthenticatorResponse =
-                getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE);
+                getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, android.accounts.AccountAuthenticatorResponse.class);
 
         if (mAccountAuthenticatorResponse != null) {
             mAccountAuthenticatorResponse.onRequestContinued();
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index fa9de6e..a573776 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -2450,7 +2450,7 @@
                     onError(ERROR_CODE_INVALID_RESPONSE, "null bundle returned");
                     return;
                 }
-                Intent intent = bundle.getParcelable(KEY_INTENT);
+                Intent intent = bundle.getParcelable(KEY_INTENT, android.content.Intent.class);
                 if (intent != null && mActivity != null) {
                     // since the user provided an Activity we will silently start intents
                     // that we see
diff --git a/core/java/android/accounts/ChooseAccountActivity.java b/core/java/android/accounts/ChooseAccountActivity.java
index 6c8744f..20142a6 100644
--- a/core/java/android/accounts/ChooseAccountActivity.java
+++ b/core/java/android/accounts/ChooseAccountActivity.java
@@ -62,7 +62,7 @@
                         .SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
         mAccounts = getIntent().getParcelableArrayExtra(AccountManager.KEY_ACCOUNTS);
         mAccountManagerResponse =
-                getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_MANAGER_RESPONSE);
+                getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_MANAGER_RESPONSE, android.accounts.AccountManagerResponse.class);
 
         // KEY_ACCOUNTS is a required parameter
         if (mAccounts == null) {
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
index f623295d..4d4a4d7 100644
--- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java
+++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
@@ -186,7 +186,7 @@
             mExistingAccounts = null;
             // If the selected account as specified in the intent matches one in the list we will
             // show is as pre-selected.
-            Account selectedAccount = (Account) intent.getParcelableExtra(EXTRA_SELECTED_ACCOUNT);
+            Account selectedAccount = (Account) intent.getParcelableExtra(EXTRA_SELECTED_ACCOUNT, android.accounts.Account.class);
             if (selectedAccount != null) {
                 mSelectedAccountName = selectedAccount.name;
             }
@@ -396,7 +396,7 @@
         try {
             final Bundle accountManagerResult = accountManagerFuture.getResult();
             final Intent intent = (Intent)accountManagerResult.getParcelable(
-                    AccountManager.KEY_INTENT);
+                    AccountManager.KEY_INTENT, android.content.Intent.class);
             if (intent != null) {
                 mPendingRequest = REQUEST_ADD_ACCOUNT;
                 mExistingAccounts = AccountManager.get(this).getAccountsForPackage(mCallingPackage,
diff --git a/core/java/android/accounts/GrantCredentialsPermissionActivity.java b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
index 74dae0e..a89fae7 100644
--- a/core/java/android/accounts/GrantCredentialsPermissionActivity.java
+++ b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
@@ -68,7 +68,7 @@
         }
 
         // Grant 'account'/'type' to mUID
-        mAccount = extras.getParcelable(EXTRAS_ACCOUNT);
+        mAccount = extras.getParcelable(EXTRAS_ACCOUNT, android.accounts.Account.class);
         mAuthTokenType = extras.getString(EXTRAS_AUTH_TOKEN_TYPE);
         mUid = extras.getInt(EXTRAS_REQUESTING_UID);
         final PackageManager pm = getPackageManager();
@@ -199,7 +199,7 @@
      */
     public void finish() {
         Intent intent = getIntent();
-        AccountAuthenticatorResponse response = intent.getParcelableExtra(EXTRAS_RESPONSE);
+        AccountAuthenticatorResponse response = intent.getParcelableExtra(EXTRAS_RESPONSE, android.accounts.AccountAuthenticatorResponse.class);
         if (response != null) {
             // send the result bundle back if set, otherwise send an error.
             if (mResultBundle != null) {
diff --git a/core/java/android/accounts/IAccountAuthenticator.aidl b/core/java/android/accounts/IAccountAuthenticator.aidl
index 701cecf..0575c07 100644
--- a/core/java/android/accounts/IAccountAuthenticator.aidl
+++ b/core/java/android/accounts/IAccountAuthenticator.aidl
@@ -62,6 +62,7 @@
     /**
      * launches an activity that lets the user edit and set the properties for an authenticator
      */
+    @EnforcePermission("ACCOUNT_MANAGER")
     @UnsupportedAppUsage
     void editProperties(in IAccountAuthenticatorResponse response, String accountType);
 
@@ -69,6 +70,7 @@
      * returns a Bundle where the boolean value BOOLEAN_RESULT_KEY is set if the account has the
      * specified features
      */
+    @EnforcePermission("ACCOUNT_MANAGER")
     @UnsupportedAppUsage
     void hasFeatures(in IAccountAuthenticatorResponse response, in Account account, 
         in String[] features);
@@ -76,12 +78,14 @@
     /**
      * Gets whether or not the account is allowed to be removed.
      */
+    @EnforcePermission("ACCOUNT_MANAGER")
     @UnsupportedAppUsage
     void getAccountRemovalAllowed(in IAccountAuthenticatorResponse response, in Account account);
 
     /**
      * Returns a Bundle containing the required credentials to copy the account across users.
      */
+    @EnforcePermission("ACCOUNT_MANAGER")
     void getAccountCredentialsForCloning(in IAccountAuthenticatorResponse response,
             in Account account);
 
@@ -89,6 +93,7 @@
      * Uses the Bundle containing credentials from another instance of the authenticator to create
      * a copy of the account on this user.
      */
+    @EnforcePermission("ACCOUNT_MANAGER")
     void addAccountFromCredentials(in IAccountAuthenticatorResponse response, in Account account,
             in Bundle accountCredentials);
 
@@ -116,6 +121,7 @@
     /**
      * Checks if the credentials of the provided account should be updated.
      */
+    @EnforcePermission("ACCOUNT_MANAGER")
     void isCredentialsUpdateSuggested(in IAccountAuthenticatorResponse response, in Account account,
         String statusToken);
 }
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 90c37d1..d8a48c9 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3999,13 +3999,12 @@
 
     /**
      * Called when a touch screen event was not handled by any of the views
-     * under it.  This is most useful to process touch events that happen
+     * inside of the activity.  This is most useful to process touch events that happen
      * outside of your window bounds, where there is no view to receive it.
      *
      * @param event The touch screen event being processed.
      *
      * @return Return true if you have consumed the event, false if you haven't.
-     * The default implementation always returns false.
      */
     public boolean onTouchEvent(MotionEvent event) {
         if (mWindow.shouldCloseOnTouch(this, event)) {
@@ -4038,12 +4037,12 @@
      * Called when a generic motion event was not handled by any of the
      * views inside of the activity.
      * <p>
-     * Generic motion events describe joystick movements, mouse hovers, track pad
-     * touches, scroll wheel movements and other input events.  The
-     * {@link MotionEvent#getSource() source} of the motion event specifies
+     * Generic motion events describe joystick movements, hover events from mouse or stylus
+     * devices, trackpad touches, scroll wheel movements and other motion events not handled
+     * by {@link #onTouchEvent(MotionEvent)} or {@link #onTrackballEvent(MotionEvent)}.
+     * The {@link MotionEvent#getSource() source} of the motion event specifies
      * the class of input that was received.  Implementations of this method
      * must examine the bits in the source before processing the event.
-     * The following code example shows how this is done.
      * </p><p>
      * Generic motion events with source class
      * {@link android.view.InputDevice#SOURCE_CLASS_POINTER}
@@ -4254,6 +4253,8 @@
      * @param ev The touch screen event.
      *
      * @return boolean Return true if this event was consumed.
+     *
+     * @see #onTouchEvent(MotionEvent)
      */
     public boolean dispatchTouchEvent(MotionEvent ev) {
         if (ev.getAction() == MotionEvent.ACTION_DOWN) {
@@ -4274,6 +4275,8 @@
      * @param ev The trackball event.
      *
      * @return boolean Return true if this event was consumed.
+     *
+     * @see #onTrackballEvent(MotionEvent)
      */
     public boolean dispatchTrackballEvent(MotionEvent ev) {
         onUserInteraction();
@@ -4292,6 +4295,8 @@
      * @param ev The generic motion event.
      *
      * @return boolean Return true if this event was consumed.
+     *
+     * @see #onGenericMotionEvent(MotionEvent)
      */
     public boolean dispatchGenericMotionEvent(MotionEvent ev) {
         onUserInteraction();
@@ -6496,7 +6501,7 @@
         Intent intent = getIntent();
         if (intent != null) {
             try {
-                Uri referrer = intent.getParcelableExtra(Intent.EXTRA_REFERRER);
+                Uri referrer = intent.getParcelableExtra(Intent.EXTRA_REFERRER, android.net.Uri.class);
                 if (referrer != null) {
                     return referrer;
                 }
diff --git a/core/java/android/app/ActivityClient.java b/core/java/android/app/ActivityClient.java
index 1d3b5e2..482f456 100644
--- a/core/java/android/app/ActivityClient.java
+++ b/core/java/android/app/ActivityClient.java
@@ -227,6 +227,18 @@
     }
 
     /**
+     * Returns the windowing mode of the task that hosts the activity, or {@code -1} if task is not
+     * found.
+     */
+    public int getTaskWindowingMode(IBinder activityToken) {
+        try {
+            return getActivityClientController().getTaskWindowingMode(activityToken);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Returns the non-finishing activity token below in the same task if it belongs to the same
      * process.
      */
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 00ab559..1a06c6f 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -1159,7 +1159,6 @@
         opts.mLaunchIntoPipParams = new PictureInPictureParams.Builder(pictureInPictureParams)
                 .setIsLaunchIntoPip(true)
                 .build();
-        opts.mLaunchBounds = new Rect(pictureInPictureParams.getSourceRectHint());
         return opts;
     }
 
@@ -1182,7 +1181,7 @@
         } catch (RuntimeException e) {
             Slog.w(TAG, e);
         }
-        mLaunchBounds = opts.getParcelable(KEY_LAUNCH_BOUNDS);
+        mLaunchBounds = opts.getParcelable(KEY_LAUNCH_BOUNDS, android.graphics.Rect.class);
         mAnimationType = opts.getInt(KEY_ANIM_TYPE, ANIM_UNDEFINED);
         switch (mAnimationType) {
             case ANIM_CUSTOM:
@@ -1210,7 +1209,7 @@
             case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
             case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
                 // Unpackage the HardwareBuffer from the parceled thumbnail
-                final HardwareBuffer buffer = opts.getParcelable(KEY_ANIM_THUMBNAIL);
+                final HardwareBuffer buffer = opts.getParcelable(KEY_ANIM_THUMBNAIL, android.hardware.HardwareBuffer.class);
                 if (buffer != null) {
                     mThumbnail = Bitmap.wrapHardwareBuffer(buffer, null);
                 }
@@ -1223,10 +1222,10 @@
                 break;
 
             case ANIM_SCENE_TRANSITION:
-                mTransitionReceiver = opts.getParcelable(KEY_TRANSITION_COMPLETE_LISTENER);
+                mTransitionReceiver = opts.getParcelable(KEY_TRANSITION_COMPLETE_LISTENER, android.os.ResultReceiver.class);
                 mIsReturning = opts.getBoolean(KEY_TRANSITION_IS_RETURNING, false);
                 mSharedElementNames = opts.getStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS);
-                mResultData = opts.getParcelable(KEY_RESULT_DATA);
+                mResultData = opts.getParcelable(KEY_RESULT_DATA, android.content.Intent.class);
                 mResultCode = opts.getInt(KEY_RESULT_CODE);
                 mExitCoordinatorIndex = opts.getInt(KEY_EXIT_COORDINATOR_INDEX);
                 break;
@@ -1234,10 +1233,10 @@
         mLockTaskMode = opts.getBoolean(KEY_LOCK_TASK_MODE, false);
         mLaunchDisplayId = opts.getInt(KEY_LAUNCH_DISPLAY_ID, INVALID_DISPLAY);
         mCallerDisplayId = opts.getInt(KEY_CALLER_DISPLAY_ID, INVALID_DISPLAY);
-        mLaunchTaskDisplayArea = opts.getParcelable(KEY_LAUNCH_TASK_DISPLAY_AREA_TOKEN);
+        mLaunchTaskDisplayArea = opts.getParcelable(KEY_LAUNCH_TASK_DISPLAY_AREA_TOKEN, android.window.WindowContainerToken.class);
         mLaunchTaskDisplayAreaFeatureId = opts.getInt(KEY_LAUNCH_TASK_DISPLAY_AREA_FEATURE_ID,
                 FEATURE_UNDEFINED);
-        mLaunchRootTask = opts.getParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN);
+        mLaunchRootTask = opts.getParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN, android.window.WindowContainerToken.class);
         mLaunchTaskFragmentToken = opts.getBinder(KEY_LAUNCH_TASK_FRAGMENT_TOKEN);
         mLaunchWindowingMode = opts.getInt(KEY_LAUNCH_WINDOWING_MODE, WINDOWING_MODE_UNDEFINED);
         mLaunchActivityType = opts.getInt(KEY_LAUNCH_ACTIVITY_TYPE, ACTIVITY_TYPE_UNDEFINED);
@@ -1263,23 +1262,23 @@
             mAnimationFinishedListener = IRemoteCallback.Stub.asInterface(
                     opts.getBinder(KEY_ANIMATION_FINISHED_LISTENER));
         }
-        mSourceInfo = opts.getParcelable(KEY_SOURCE_INFO);
+        mSourceInfo = opts.getParcelable(KEY_SOURCE_INFO, android.app.ActivityOptions.SourceInfo.class);
         mRotationAnimationHint = opts.getInt(KEY_ROTATION_ANIMATION_HINT, -1);
         mAppVerificationBundle = opts.getBundle(KEY_INSTANT_APP_VERIFICATION_BUNDLE);
         if (opts.containsKey(KEY_SPECS_FUTURE)) {
             mSpecsFuture = IAppTransitionAnimationSpecsFuture.Stub.asInterface(opts.getBinder(
                     KEY_SPECS_FUTURE));
         }
-        mRemoteAnimationAdapter = opts.getParcelable(KEY_REMOTE_ANIMATION_ADAPTER);
+        mRemoteAnimationAdapter = opts.getParcelable(KEY_REMOTE_ANIMATION_ADAPTER, android.view.RemoteAnimationAdapter.class);
         mLaunchCookie = opts.getBinder(KEY_LAUNCH_COOKIE);
-        mRemoteTransition = opts.getParcelable(KEY_REMOTE_TRANSITION);
+        mRemoteTransition = opts.getParcelable(KEY_REMOTE_TRANSITION, android.window.RemoteTransition.class);
         mOverrideTaskTransition = opts.getBoolean(KEY_OVERRIDE_TASK_TRANSITION);
         mSplashScreenThemeResName = opts.getString(KEY_SPLASH_SCREEN_THEME);
         mRemoveWithTaskOrganizer = opts.getBoolean(KEY_REMOVE_WITH_TASK_ORGANIZER);
         mLaunchedFromBubble = opts.getBoolean(KEY_LAUNCHED_FROM_BUBBLE);
         mTransientLaunch = opts.getBoolean(KEY_TRANSIENT_LAUNCH);
         mSplashScreenStyle = opts.getInt(KEY_SPLASH_SCREEN_STYLE);
-        mLaunchIntoPipParams = opts.getParcelable(KEY_LAUNCH_INTO_PIP_PARAMS);
+        mLaunchIntoPipParams = opts.getParcelable(KEY_LAUNCH_INTO_PIP_PARAMS, android.app.PictureInPictureParams.class);
         mIsEligibleForLegacyPermissionPrompt =
                 opts.getBoolean(KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE);
         mDismissKeyguard = opts.getBoolean(KEY_DISMISS_KEYGUARD);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 8a9ec09..2a83cbd 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -5885,20 +5885,20 @@
 
         final boolean movedToDifferentDisplay = isDifferentDisplay(activity.getDisplayId(),
                 displayId);
-        final Configuration currentConfig = activity.mCurrentConfig;
-        final int diff = currentConfig.diffPublicOnly(newConfig);
-        final boolean hasPublicConfigChange = diff != 0;
+        final Configuration currentResConfig = activity.getResources().getConfiguration();
+        final int diff = currentResConfig.diffPublicOnly(newConfig);
+        final boolean hasPublicResConfigChange = diff != 0;
         final ActivityClientRecord r = getActivityClient(activityToken);
         // TODO(b/173090263): Use diff instead after the improvement of AssetManager and
         // ResourcesImpl constructions.
-        final boolean shouldUpdateResources = hasPublicConfigChange
-                || shouldUpdateResources(activityToken, currentConfig, newConfig, amOverrideConfig,
-                movedToDifferentDisplay, hasPublicConfigChange);
-        final boolean shouldReportChange = shouldReportChange(diff, currentConfig, newConfig,
+        final boolean shouldUpdateResources = hasPublicResConfigChange
+                || shouldUpdateResources(activityToken, currentResConfig, newConfig,
+                amOverrideConfig, movedToDifferentDisplay, hasPublicResConfigChange);
+        final boolean shouldReportChange = shouldReportChange(activity.mCurrentConfig, newConfig,
                 r != null ? r.mSizeConfigurations : null,
                 activity.mActivityInfo.getRealConfigChanged());
         // Nothing significant, don't proceed with updating and reporting.
-        if (!shouldUpdateResources) {
+        if (!shouldUpdateResources && !shouldReportChange) {
             return null;
         }
 
@@ -5918,9 +5918,6 @@
                 amOverrideConfig, contextThemeWrapperOverrideConfig);
         mResourcesManager.updateResourcesForActivity(activityToken, finalOverrideConfig, displayId);
 
-        activity.mConfigChangeFlags = 0;
-        activity.mCurrentConfig = new Configuration(newConfig);
-
         // Apply the ContextThemeWrapper override if necessary.
         // NOTE: Make sure the configurations are not modified, as they are treated as immutable
         // in many places.
@@ -5931,8 +5928,10 @@
             activity.dispatchMovedToDisplay(displayId, configToReport);
         }
 
+        activity.mConfigChangeFlags = 0;
         if (shouldReportChange) {
             activity.mCalled = false;
+            activity.mCurrentConfig = new Configuration(newConfig);
             activity.onConfigurationChanged(configToReport);
             if (!activity.mCalled) {
                 throw new SuperNotCalledException("Activity " + activity.getLocalClassName() +
@@ -5947,8 +5946,6 @@
      * Returns {@code true} if {@link Activity#onConfigurationChanged(Configuration)} should be
      * dispatched.
      *
-     * @param publicDiff Usually computed by {@link Configuration#diffPublicOnly(Configuration)}.
-     *                   This parameter is to prevent we compute it again.
      * @param currentConfig The current configuration cached in {@link Activity#mCurrentConfig}.
      *                      It is {@code null} before the first config update from the server side.
      * @param newConfig The updated {@link Configuration}
@@ -5957,9 +5954,10 @@
      * @return {@code true} if the config change should be reported to the Activity
      */
     @VisibleForTesting
-    public static boolean shouldReportChange(int publicDiff, @Nullable Configuration currentConfig,
+    public static boolean shouldReportChange(@Nullable Configuration currentConfig,
             @NonNull Configuration newConfig, @Nullable SizeConfigurationBuckets sizeBuckets,
             int handledConfigChanges) {
+        final int publicDiff = currentConfig.diffPublicOnly(newConfig);
         // Don't report the change if there's no public diff between current and new config.
         if (publicDiff == 0) {
             return false;
diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java
index 877e7d3..57dacd0 100644
--- a/core/java/android/app/ActivityTransitionState.java
+++ b/core/java/android/app/ActivityTransitionState.java
@@ -263,6 +263,11 @@
         // After orientation change, the onResume can come in before the top Activity has
         // left, so if the Activity is not top, wait a second for the top Activity to exit.
         if (mEnterTransitionCoordinator == null || activity.isTopOfTask()) {
+            if (mEnterTransitionCoordinator != null) {
+                mEnterTransitionCoordinator.runAfterTransitionsComplete(() -> {
+                    mEnterTransitionCoordinator = null;
+                });
+            }
             restoreExitedViews();
             restoreReenteringViews();
         } else {
@@ -271,6 +276,11 @@
                 public void run() {
                     if (mEnterTransitionCoordinator == null ||
                             mEnterTransitionCoordinator.isWaitingForRemoteExit()) {
+                        if (mEnterTransitionCoordinator != null) {
+                            mEnterTransitionCoordinator.runAfterTransitionsComplete(() -> {
+                                mEnterTransitionCoordinator = null;
+                            });
+                        }
                         restoreExitedViews();
                         restoreReenteringViews();
                     } else if (mEnterTransitionCoordinator.isReturning()) {
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 125f5e4..9072b50 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -7693,7 +7693,7 @@
                     request.mOpNames, request.mHistoryFlags, request.mFilter,
                     request.mBeginTimeMillis, request.mEndTimeMillis, request.mFlags,
                     new RemoteCallback((result) -> {
-                final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
+                final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS, android.app.AppOpsManager.HistoricalOps.class);
                 final long identity = Binder.clearCallingIdentity();
                 try {
                     executor.execute(() -> callback.accept(ops));
@@ -7733,7 +7733,7 @@
                     request.mAttributionTag, request.mOpNames, request.mHistoryFlags,
                     request.mFilter, request.mBeginTimeMillis, request.mEndTimeMillis,
                     request.mFlags, new RemoteCallback((result) -> {
-                final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
+                final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS, android.app.AppOpsManager.HistoricalOps.class);
                 final long identity = Binder.clearCallingIdentity();
                 try {
                     executor.execute(() -> callback.accept(ops));
@@ -10291,6 +10291,9 @@
 
         // system alert window is disable on low ram phones starting from Q
         final PackageManager pm = context.getPackageManager();
+        if (null == pm) {
+            return AppOpsManager.MODE_DEFAULT;
+        }
         // TVs are constantly plugged in and has less concern for memory/power
         if (ActivityManager.isLowRamDeviceStatic()
                 && !pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK, 0)) {
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index fea3027..569f4dd 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -3657,15 +3657,6 @@
     }
 
     @Override
-    public String getContentCaptureServicePackageName() {
-        try {
-            return mPM.getContentCaptureServicePackageName();
-        } catch (RemoteException e) {
-            throw e.rethrowAsRuntimeException();
-        }
-    }
-
-    @Override
     public boolean isPackageStateProtected(String packageName, int userId) {
         try {
             return mPM.isPackageStateProtected(packageName, userId);
diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java
index 56f8760..f0e1448 100644
--- a/core/java/android/app/BroadcastOptions.java
+++ b/core/java/android/app/BroadcastOptions.java
@@ -53,6 +53,7 @@
     private String[] mRequireNoneOfPermissions;
     private long mRequireCompatChangeId = CHANGE_INVALID;
     private boolean mRequireCompatChangeEnabled = true;
+    private boolean mIsAlarmBroadcast = false;
     private long mIdForResponseEvent;
 
     /**
@@ -149,6 +150,13 @@
             "android:broadcast.requireCompatChangeEnabled";
 
     /**
+     * Corresponds to {@link #setAlarmBroadcast(boolean)}
+     * @hide
+     */
+    public static final String KEY_ALARM_BROADCAST =
+            "android:broadcast.is_alarm";
+
+    /**
      * @hide
      * @deprecated Use {@link android.os.PowerExemptionManager#
      * TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED} instead.
@@ -207,6 +215,7 @@
         mRequireCompatChangeId = opts.getLong(KEY_REQUIRE_COMPAT_CHANGE_ID, CHANGE_INVALID);
         mRequireCompatChangeEnabled = opts.getBoolean(KEY_REQUIRE_COMPAT_CHANGE_ENABLED, true);
         mIdForResponseEvent = opts.getLong(KEY_ID_FOR_RESPONSE_EVENT);
+        mIsAlarmBroadcast = opts.getBoolean(KEY_ALARM_BROADCAST, false);
     }
 
     /**
@@ -498,6 +507,27 @@
         mRequireCompatChangeEnabled = true;
     }
 
+    /**
+     * When set, this broadcast will be understood as having originated from an
+     * alarm going off.  Only the OS itself can use this option; uses by other
+     * senders will be ignored.
+     * @hide
+     *
+     * @param senderIsAlarm Whether the broadcast is alarm-triggered.
+     */
+    public void setAlarmBroadcast(boolean senderIsAlarm) {
+        mIsAlarmBroadcast = senderIsAlarm;
+    }
+
+    /**
+     * Did this broadcast originate from an alarm triggering?
+     * @return true if this broadcast is an alarm message, false otherwise
+     * @hide
+     */
+    public boolean isAlarmBroadcast() {
+        return mIsAlarmBroadcast;
+    }
+
     /** {@hide} */
     public long getRequireCompatChangeId() {
         return mRequireCompatChangeId;
@@ -560,6 +590,9 @@
             b.putInt(KEY_TEMPORARY_APP_ALLOWLIST_REASON_CODE, mTemporaryAppAllowlistReasonCode);
             b.putString(KEY_TEMPORARY_APP_ALLOWLIST_REASON, mTemporaryAppAllowlistReason);
         }
+        if (mIsAlarmBroadcast) {
+            b.putBoolean(KEY_ALARM_BROADCAST, true);
+        }
         if (mMinManifestReceiverApiLevel != 0) {
             b.putInt(KEY_MIN_MANIFEST_RECEIVER_API_LEVEL, mMinManifestReceiverApiLevel);
         }
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index cd84e56..930750e 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -81,7 +81,7 @@
         switch (resultCode) {
             case MSG_SET_REMOTE_RECEIVER:
                 stopCancel();
-                mResultReceiver = resultData.getParcelable(KEY_REMOTE_RECEIVER);
+                mResultReceiver = resultData.getParcelable(KEY_REMOTE_RECEIVER, android.os.ResultReceiver.class);
                 if (mIsCanceled) {
                     mResultReceiver.send(MSG_CANCEL, null);
                     mResultReceiver = null;
diff --git a/core/java/android/app/IActivityClientController.aidl b/core/java/android/app/IActivityClientController.aidl
index 7aeb2b2..f5e5cda 100644
--- a/core/java/android/app/IActivityClientController.aidl
+++ b/core/java/android/app/IActivityClientController.aidl
@@ -78,6 +78,7 @@
     boolean willActivityBeVisible(in IBinder token);
     int getDisplayId(in IBinder activityToken);
     int getTaskForActivity(in IBinder token, in boolean onlyRoot);
+    int getTaskWindowingMode(in IBinder activityToken);
     IBinder getActivityTokenBelow(IBinder token);
     ComponentName getCallingActivity(in IBinder token);
     String getCallingPackage(in IBinder token);
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index da6a551..ddfbc68 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -235,5 +235,6 @@
     void setListenerFilter(in ComponentName cn, int userId, in NotificationListenerFilter nlf);
     void migrateNotificationFilter(in INotificationListener token, int defaultTypes, in List<String> disallowedPkgs);
 
+    @EnforcePermission("MANAGE_TOAST_RATE_LIMITING")
     void setToastRateLimitingEnabled(boolean enable);
 }
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 8984c42..556058b 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -783,6 +783,17 @@
             return null;
         }
 
+        /**
+         * This is called after starting an Activity and provides the result code that defined in
+         * {@link ActivityManager}, like {@link ActivityManager#START_SUCCESS}.
+         *
+         * @param result the result code that returns after starting an Activity.
+         * @param bOptions the bundle generated from {@link ActivityOptions} that originally
+         *                 being used to start the Activity.
+         * @hide
+         */
+        public void onStartActivityResult(int result, @NonNull Bundle bOptions) {}
+
         final boolean match(Context who,
                             Activity activity,
                             Intent intent) {
@@ -1344,6 +1355,28 @@
         return apk.getAppFactory();
     }
 
+    /**
+     * This should be called before {@link #checkStartActivityResult(int, Object)}, because
+     * exceptions might be thrown while checking the results.
+     */
+    private void notifyStartActivityResult(int result, @Nullable Bundle options) {
+        if (mActivityMonitors == null) {
+            return;
+        }
+        synchronized (mSync) {
+            final int size = mActivityMonitors.size();
+            for (int i = 0; i < size; i++) {
+                final ActivityMonitor am = mActivityMonitors.get(i);
+                if (am.ignoreMatchingSpecificIntents()) {
+                    if (options == null) {
+                        options = ActivityOptions.makeBasic().toBundle();
+                    }
+                    am.onStartActivityResult(result, options);
+                }
+            }
+        }
+    }
+
     private void prePerformCreate(Activity activity) {
         if (mWaitingActivities != null) {
             synchronized (mSync) {
@@ -1802,6 +1835,7 @@
                     who.getOpPackageName(), who.getAttributionTag(), intent,
                     intent.resolveTypeIfNeeded(who.getContentResolver()), token,
                     target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
+            notifyStartActivityResult(result, options);
             checkStartActivityResult(result, intent);
         } catch (RemoteException e) {
             throw new RuntimeException("Failure from system", e);
@@ -1876,6 +1910,7 @@
             int result = ActivityTaskManager.getService().startActivities(whoThread,
                     who.getOpPackageName(), who.getAttributionTag(), intents, resolvedTypes,
                     token, options, userId);
+            notifyStartActivityResult(result, options);
             checkStartActivityResult(result, intents[0]);
             return result;
         } catch (RemoteException e) {
@@ -1947,6 +1982,7 @@
                     who.getOpPackageName(), who.getAttributionTag(), intent,
                     intent.resolveTypeIfNeeded(who.getContentResolver()), token, target,
                     requestCode, 0, null, options);
+            notifyStartActivityResult(result, options);
             checkStartActivityResult(result, intent);
         } catch (RemoteException e) {
             throw new RuntimeException("Failure from system", e);
@@ -2017,6 +2053,7 @@
                     who.getOpPackageName(), who.getAttributionTag(), intent,
                     intent.resolveTypeIfNeeded(who.getContentResolver()), token, resultWho,
                     requestCode, 0, null, options, user.getIdentifier());
+            notifyStartActivityResult(result, options);
             checkStartActivityResult(result, intent);
         } catch (RemoteException e) {
             throw new RuntimeException("Failure from system", e);
@@ -2068,6 +2105,7 @@
                             token, target != null ? target.mEmbeddedID : null,
                             requestCode, 0, null, options,
                             ignoreTargetSecurity, userId);
+            notifyStartActivityResult(result, options);
             checkStartActivityResult(result, intent);
         } catch (RemoteException e) {
             throw new RuntimeException("Failure from system", e);
@@ -2115,6 +2153,7 @@
             int result = appTask.startActivity(whoThread.asBinder(), who.getOpPackageName(),
                     who.getAttributionTag(), intent,
                     intent.resolveTypeIfNeeded(who.getContentResolver()), options);
+            notifyStartActivityResult(result, options);
             checkStartActivityResult(result, intent);
         } catch (RemoteException e) {
             throw new RuntimeException("Failure from system", e);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index e820733..343adb8 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -2842,7 +2842,7 @@
                 visitor.accept(Uri.parse(extras.getString(EXTRA_BACKGROUND_IMAGE_URI)));
             }
 
-            ArrayList<Person> people = extras.getParcelableArrayList(EXTRA_PEOPLE_LIST);
+            ArrayList<Person> people = extras.getParcelableArrayList(EXTRA_PEOPLE_LIST, android.app.Person.class);
             if (people != null && !people.isEmpty()) {
                 for (Person p : people) {
                     visitor.accept(p.getIconUri());
@@ -3882,7 +3882,7 @@
                 }
 
                 if (mN.extras.containsKey(EXTRA_PEOPLE_LIST)) {
-                    ArrayList<Person> people = mN.extras.getParcelableArrayList(EXTRA_PEOPLE_LIST);
+                    ArrayList<Person> people = mN.extras.getParcelableArrayList(EXTRA_PEOPLE_LIST, android.app.Person.class);
                     mPersonList.addAll(people);
                 }
 
@@ -9777,7 +9777,7 @@
             mCallType = extras.getInt(EXTRA_CALL_TYPE);
             mIsVideo = extras.getBoolean(EXTRA_CALL_IS_VIDEO);
             mPerson = extras.getParcelable(EXTRA_CALL_PERSON, Person.class);
-            mVerificationIcon = extras.getParcelable(EXTRA_VERIFICATION_ICON);
+            mVerificationIcon = extras.getParcelable(EXTRA_VERIFICATION_ICON, android.graphics.drawable.Icon.class);
             mVerificationText = extras.getCharSequence(EXTRA_VERIFICATION_TEXT);
             mAnswerIntent = extras.getParcelable(EXTRA_ANSWER_INTENT, PendingIntent.class);
             mDeclineIntent = extras.getParcelable(EXTRA_DECLINE_INTENT, PendingIntent.class);
@@ -10895,7 +10895,7 @@
         public WearableExtender(Notification notif) {
             Bundle wearableBundle = notif.extras.getBundle(EXTRA_WEARABLE_EXTENSIONS);
             if (wearableBundle != null) {
-                List<Action> actions = wearableBundle.getParcelableArrayList(KEY_ACTIONS);
+                List<Action> actions = wearableBundle.getParcelableArrayList(KEY_ACTIONS, android.app.Notification.Action.class);
                 if (actions != null) {
                     mActions.addAll(actions);
                 }
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index c9cc1a1..0e89b25 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -564,8 +564,10 @@
 
     /**
      * Sets the vibration pattern for notifications posted to this channel. If the provided
-     * pattern is valid (non-null, non-empty), will {@link #enableVibration(boolean)} enable
-     * vibration} as well. Otherwise, vibration will be disabled.
+     * pattern is valid (non-null, non-empty), will enable vibration on this channel
+     * (equivalent to calling {@link #enableVibration(boolean)} with {@code true}).
+     * Otherwise, vibration will be disabled unless {@link #enableVibration(boolean)} is
+     * used with {@code true}, in which case the default vibration will be used.
      *
      * Only modifiable before the channel is submitted to
      * {@link NotificationManager#createNotificationChannel(NotificationChannel)}.
diff --git a/core/java/android/app/RecoverableSecurityException.java b/core/java/android/app/RecoverableSecurityException.java
index 21fb2a6..176f141 100644
--- a/core/java/android/app/RecoverableSecurityException.java
+++ b/core/java/android/app/RecoverableSecurityException.java
@@ -164,7 +164,7 @@
     public static class LocalDialog extends DialogFragment {
         @Override
         public Dialog onCreateDialog(Bundle savedInstanceState) {
-            final RecoverableSecurityException e = getArguments().getParcelable(TAG);
+            final RecoverableSecurityException e = getArguments().getParcelable(TAG, android.app.RecoverableSecurityException.class);
             return new AlertDialog.Builder(getActivity())
                     .setMessage(e.mUserMessage)
                     .setPositiveButton(e.mUserAction.getTitle(), (dialog, which) -> {
diff --git a/core/java/android/app/RemoteInput.java b/core/java/android/app/RemoteInput.java
index 36c524b..8816109 100644
--- a/core/java/android/app/RemoteInput.java
+++ b/core/java/android/app/RemoteInput.java
@@ -429,7 +429,7 @@
         if (clipDataIntent == null) {
             return null;
         }
-        return clipDataIntent.getExtras().getParcelable(EXTRA_RESULTS_DATA);
+        return clipDataIntent.getExtras().getParcelable(EXTRA_RESULTS_DATA, android.os.Bundle.class);
     }
 
     /**
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 9fe894b..5757604 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -352,7 +352,7 @@
     public void onRestoreInstanceState(Bundle savedInstanceState) {
         if (savedInstanceState == null) return;
 
-        ComponentName launchComponent = savedInstanceState.getParcelable(INSTANCE_KEY_COMPONENT);
+        ComponentName launchComponent = savedInstanceState.getParcelable(INSTANCE_KEY_COMPONENT, android.content.ComponentName.class);
         Bundle appSearchData = savedInstanceState.getBundle(INSTANCE_KEY_APPDATA);
         String userQuery = savedInstanceState.getString(INSTANCE_KEY_USER_QUERY);
 
diff --git a/core/java/android/app/SharedElementCallback.java b/core/java/android/app/SharedElementCallback.java
index 8eb7e72..594d297 100644
--- a/core/java/android/app/SharedElementCallback.java
+++ b/core/java/android/app/SharedElementCallback.java
@@ -234,8 +234,8 @@
         View view = null;
         if (snapshot instanceof Bundle) {
             Bundle bundle = (Bundle) snapshot;
-            HardwareBuffer buffer = bundle.getParcelable(BUNDLE_SNAPSHOT_HARDWARE_BUFFER);
-            Bitmap bitmap = bundle.getParcelable(BUNDLE_SNAPSHOT_BITMAP);
+            HardwareBuffer buffer = bundle.getParcelable(BUNDLE_SNAPSHOT_HARDWARE_BUFFER, android.hardware.HardwareBuffer.class);
+            Bitmap bitmap = bundle.getParcelable(BUNDLE_SNAPSHOT_BITMAP, android.graphics.Bitmap.class);
             if (buffer == null && bitmap == null) {
                 return null;
             }
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 6615374..36e1eee 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -1606,6 +1606,7 @@
                 case Context.APP_PREDICTION_SERVICE:
                 case Context.INCREMENTAL_SERVICE:
                 case Context.ETHERNET_SERVICE:
+                case Context.CONTEXTHUB_SERVICE:
                     return null;
             }
             Slog.wtf(TAG, "Manager wrapper not available: " + name);
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index b09463e..a2dc47d 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -427,6 +427,15 @@
     }
 
     /**
+     * @return The id of the display this task is associated with.
+     * @hide
+     */
+    @TestApi
+    public int getDisplayId() {
+        return displayId;
+    }
+
+    /**
      * Returns {@code true} if the parameters that are important for task organizers are equal
      * between this {@link TaskInfo} and {@param that}.
      * @hide
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index ac67593..ad7c53b 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -1068,10 +1068,7 @@
      * @param window Window to take a screenshot of
      *
      * @return The screenshot bitmap on success, null otherwise.
-     *
-     * @hide
      */
-    @TestApi
     @Nullable
     public Bitmap takeScreenshot(@NonNull Window window) {
         if (window == null) {
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index 7964ae9..a045157 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -549,7 +549,6 @@
                 | AccessibilityServiceInfo.FLAG_FORCE_DIRECT_BOOT_AWARE;
         info.setCapabilities(AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT
                 | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
-                | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY
                 | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS);
         try {
             // Calling out with a lock held is fine since if the system
diff --git a/core/java/android/app/admin/DelegatedAdminReceiver.java b/core/java/android/app/admin/DelegatedAdminReceiver.java
index c74ddb2..30509d6 100644
--- a/core/java/android/app/admin/DelegatedAdminReceiver.java
+++ b/core/java/android/app/admin/DelegatedAdminReceiver.java
@@ -156,7 +156,7 @@
 
         if (ACTION_CHOOSE_PRIVATE_KEY_ALIAS.equals(action)) {
             int uid = intent.getIntExtra(EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID, -1);
-            Uri uri = intent.getParcelableExtra(EXTRA_CHOOSE_PRIVATE_KEY_URI);
+            Uri uri = intent.getParcelableExtra(EXTRA_CHOOSE_PRIVATE_KEY_URI, android.net.Uri.class);
             String alias = intent.getStringExtra(EXTRA_CHOOSE_PRIVATE_KEY_ALIAS);
             String chosenAlias = onChoosePrivateKeyAlias(context, intent, uid, uri, alias);
             setResultData(chosenAlias);
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index 27e8c46..f21e11a 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -1179,11 +1179,11 @@
         }
 
         if (ACTION_PASSWORD_CHANGED.equals(action)) {
-            onPasswordChanged(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER));
+            onPasswordChanged(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class));
         } else if (ACTION_PASSWORD_FAILED.equals(action)) {
-            onPasswordFailed(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER));
+            onPasswordFailed(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class));
         } else if (ACTION_PASSWORD_SUCCEEDED.equals(action)) {
-            onPasswordSucceeded(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER));
+            onPasswordSucceeded(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class));
         } else if (ACTION_DEVICE_ADMIN_ENABLED.equals(action)) {
             onEnabled(context, intent);
         } else if (ACTION_DEVICE_ADMIN_DISABLE_REQUESTED.equals(action)) {
@@ -1195,12 +1195,12 @@
         } else if (ACTION_DEVICE_ADMIN_DISABLED.equals(action)) {
             onDisabled(context, intent);
         } else if (ACTION_PASSWORD_EXPIRING.equals(action)) {
-            onPasswordExpiring(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER));
+            onPasswordExpiring(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class));
         } else if (ACTION_PROFILE_PROVISIONING_COMPLETE.equals(action)) {
             onProfileProvisioningComplete(context, intent);
         } else if (ACTION_CHOOSE_PRIVATE_KEY_ALIAS.equals(action)) {
             int uid = intent.getIntExtra(EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID, -1);
-            Uri uri = intent.getParcelableExtra(EXTRA_CHOOSE_PRIVATE_KEY_URI);
+            Uri uri = intent.getParcelableExtra(EXTRA_CHOOSE_PRIVATE_KEY_URI, android.net.Uri.class);
             String alias = intent.getStringExtra(EXTRA_CHOOSE_PRIVATE_KEY_ALIAS);
             String chosenAlias = onChoosePrivateKeyAlias(context, intent, uid, uri, alias);
             setResultData(chosenAlias);
@@ -1228,22 +1228,22 @@
             int networkLogsCount = intent.getIntExtra(EXTRA_NETWORK_LOGS_COUNT, 0);
             onNetworkLogsAvailable(context, intent, batchToken, networkLogsCount);
         } else if (ACTION_USER_ADDED.equals(action)) {
-            onUserAdded(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER));
+            onUserAdded(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class));
         } else if (ACTION_USER_REMOVED.equals(action)) {
-            onUserRemoved(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER));
+            onUserRemoved(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class));
         } else if (ACTION_USER_STARTED.equals(action)) {
-            onUserStarted(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER));
+            onUserStarted(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class));
         } else if (ACTION_USER_STOPPED.equals(action)) {
-            onUserStopped(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER));
+            onUserStopped(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class));
         } else if (ACTION_USER_SWITCHED.equals(action)) {
-            onUserSwitched(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER));
+            onUserSwitched(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class));
         } else if (ACTION_TRANSFER_OWNERSHIP_COMPLETE.equals(action)) {
             PersistableBundle bundle =
-                    intent.getParcelableExtra(EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE);
+                    intent.getParcelableExtra(EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE, android.os.PersistableBundle.class);
             onTransferOwnershipComplete(context, bundle);
         } else if (ACTION_AFFILIATED_PROFILE_TRANSFER_OWNERSHIP_COMPLETE.equals(action)) {
             onTransferAffiliatedProfileOwnershipComplete(context,
-                    intent.getParcelableExtra(Intent.EXTRA_USER));
+                    intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class));
         } else if (ACTION_OPERATION_SAFETY_STATE_CHANGED.equals(action)) {
             onOperationSafetyStateChanged(context, intent);
         } else if (ACTION_COMPLIANCE_ACKNOWLEDGEMENT_REQUIRED.equals(action)) {
diff --git a/core/java/android/app/ambientcontext/AmbientContextManager.java b/core/java/android/app/ambientcontext/AmbientContextManager.java
index dd1dd0c..308c5ed 100644
--- a/core/java/android/app/ambientcontext/AmbientContextManager.java
+++ b/core/java/android/app/ambientcontext/AmbientContextManager.java
@@ -117,7 +117,7 @@
      */
     @NonNull public static List<AmbientContextEvent> getEventsFromIntent(@NonNull Intent intent) {
         if (intent.hasExtra(AmbientContextManager.EXTRA_AMBIENT_CONTEXT_EVENTS)) {
-            return intent.getParcelableArrayListExtra(EXTRA_AMBIENT_CONTEXT_EVENTS);
+            return intent.getParcelableArrayListExtra(EXTRA_AMBIENT_CONTEXT_EVENTS, android.app.ambientcontext.AmbientContextEvent.class);
         } else {
             return new ArrayList<>();
         }
diff --git a/core/java/android/app/search/SearchAction.java b/core/java/android/app/search/SearchAction.java
index 9e40e7e..0c4508a 100644
--- a/core/java/android/app/search/SearchAction.java
+++ b/core/java/android/app/search/SearchAction.java
@@ -67,7 +67,7 @@
     private final UserHandle mUserHandle;
 
     @Nullable
-    private Bundle mExtras;
+    private final Bundle mExtras;
 
     SearchAction(Parcel in) {
         mId = in.readString();
@@ -99,7 +99,7 @@
         mPendingIntent = pendingIntent;
         mIntent = intent;
         mUserHandle = userHandle;
-        mExtras = extras;
+        mExtras = extras != null ? extras : new Bundle();
 
         if (mPendingIntent == null && mIntent == null) {
             throw new IllegalStateException("At least one type of intent should be available.");
diff --git a/core/java/android/app/search/SearchTarget.java b/core/java/android/app/search/SearchTarget.java
index a590a5d..a3874f7 100644
--- a/core/java/android/app/search/SearchTarget.java
+++ b/core/java/android/app/search/SearchTarget.java
@@ -185,7 +185,7 @@
         mShortcutInfo = shortcutInfo;
         mAppWidgetProviderInfo = appWidgetProviderInfo;
         mSliceUri = sliceUri;
-        mExtras = extras;
+        mExtras = extras != null ? extras : new Bundle();
 
         int published = 0;
         if (mSearchAction != null) published++;
diff --git a/core/java/android/app/slice/SliceManager.java b/core/java/android/app/slice/SliceManager.java
index ed4ea74..1e4934e 100644
--- a/core/java/android/app/slice/SliceManager.java
+++ b/core/java/android/app/slice/SliceManager.java
@@ -231,7 +231,7 @@
                 extras.putParcelable(SliceProvider.EXTRA_BIND_URI, uri);
                 final Bundle res = provider.call(
                         SliceProvider.METHOD_GET_DESCENDANTS, null, extras);
-                return res.getParcelableArrayList(SliceProvider.EXTRA_SLICE_DESCENDANTS);
+                return res.getParcelableArrayList(SliceProvider.EXTRA_SLICE_DESCENDANTS, android.net.Uri.class);
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Unable to get slice descendants", e);
@@ -264,7 +264,7 @@
             if (res == null) {
                 return null;
             }
-            return res.getParcelable(SliceProvider.EXTRA_SLICE);
+            return res.getParcelable(SliceProvider.EXTRA_SLICE, android.app.slice.Slice.class);
         } catch (RemoteException e) {
             // Arbitrary and not worth documenting, as Activity
             // Manager will kill this process shortly anyway.
@@ -323,7 +323,7 @@
             if (res == null) {
                 return null;
             }
-            return res.getParcelable(SliceProvider.EXTRA_SLICE);
+            return res.getParcelable(SliceProvider.EXTRA_SLICE, android.net.Uri.class);
         } catch (RemoteException e) {
             // Arbitrary and not worth documenting, as Activity
             // Manager will kill this process shortly anyway.
@@ -403,7 +403,7 @@
             if (res == null) {
                 return null;
             }
-            return res.getParcelable(SliceProvider.EXTRA_SLICE);
+            return res.getParcelable(SliceProvider.EXTRA_SLICE, android.app.slice.Slice.class);
         } catch (RemoteException e) {
             // Arbitrary and not worth documenting, as Activity
             // Manager will kill this process shortly anyway.
diff --git a/core/java/android/app/slice/SliceProvider.java b/core/java/android/app/slice/SliceProvider.java
index e6c88a3..63835cb 100644
--- a/core/java/android/app/slice/SliceProvider.java
+++ b/core/java/android/app/slice/SliceProvider.java
@@ -352,8 +352,8 @@
     public Bundle call(String method, String arg, Bundle extras) {
         if (method.equals(METHOD_SLICE)) {
             Uri uri = getUriWithoutUserId(validateIncomingUriOrNull(
-                    extras.getParcelable(EXTRA_BIND_URI)));
-            List<SliceSpec> supportedSpecs = extras.getParcelableArrayList(EXTRA_SUPPORTED_SPECS);
+                    extras.getParcelable(EXTRA_BIND_URI, android.net.Uri.class)));
+            List<SliceSpec> supportedSpecs = extras.getParcelableArrayList(EXTRA_SUPPORTED_SPECS, android.app.slice.SliceSpec.class);
 
             String callingPackage = getCallingPackage();
             int callingUid = Binder.getCallingUid();
@@ -364,10 +364,10 @@
             b.putParcelable(EXTRA_SLICE, s);
             return b;
         } else if (method.equals(METHOD_MAP_INTENT)) {
-            Intent intent = extras.getParcelable(EXTRA_INTENT);
+            Intent intent = extras.getParcelable(EXTRA_INTENT, android.content.Intent.class);
             if (intent == null) return null;
             Uri uri = validateIncomingUriOrNull(onMapIntentToUri(intent));
-            List<SliceSpec> supportedSpecs = extras.getParcelableArrayList(EXTRA_SUPPORTED_SPECS);
+            List<SliceSpec> supportedSpecs = extras.getParcelableArrayList(EXTRA_SUPPORTED_SPECS, android.app.slice.SliceSpec.class);
             Bundle b = new Bundle();
             if (uri != null) {
                 Slice s = handleBindSlice(uri, supportedSpecs, getCallingPackage(),
@@ -378,7 +378,7 @@
             }
             return b;
         } else if (method.equals(METHOD_MAP_ONLY_INTENT)) {
-            Intent intent = extras.getParcelable(EXTRA_INTENT);
+            Intent intent = extras.getParcelable(EXTRA_INTENT, android.content.Intent.class);
             if (intent == null) return null;
             Uri uri = validateIncomingUriOrNull(onMapIntentToUri(intent));
             Bundle b = new Bundle();
@@ -386,21 +386,21 @@
             return b;
         } else if (method.equals(METHOD_PIN)) {
             Uri uri = getUriWithoutUserId(validateIncomingUriOrNull(
-                    extras.getParcelable(EXTRA_BIND_URI)));
+                    extras.getParcelable(EXTRA_BIND_URI, android.net.Uri.class)));
             if (Binder.getCallingUid() != Process.SYSTEM_UID) {
                 throw new SecurityException("Only the system can pin/unpin slices");
             }
             handlePinSlice(uri);
         } else if (method.equals(METHOD_UNPIN)) {
             Uri uri = getUriWithoutUserId(validateIncomingUriOrNull(
-                    extras.getParcelable(EXTRA_BIND_URI)));
+                    extras.getParcelable(EXTRA_BIND_URI, android.net.Uri.class)));
             if (Binder.getCallingUid() != Process.SYSTEM_UID) {
                 throw new SecurityException("Only the system can pin/unpin slices");
             }
             handleUnpinSlice(uri);
         } else if (method.equals(METHOD_GET_DESCENDANTS)) {
             Uri uri = getUriWithoutUserId(
-                    validateIncomingUriOrNull(extras.getParcelable(EXTRA_BIND_URI)));
+                    validateIncomingUriOrNull(extras.getParcelable(EXTRA_BIND_URI, android.net.Uri.class)));
             Bundle b = new Bundle();
             b.putParcelableArrayList(EXTRA_SLICE_DESCENDANTS,
                     new ArrayList<>(handleGetDescendants(uri)));
diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl
index 45146fd..94a9656 100644
--- a/core/java/android/app/trust/ITrustManager.aidl
+++ b/core/java/android/app/trust/ITrustManager.aidl
@@ -36,6 +36,7 @@
     void setDeviceLockedForUser(int userId, boolean locked);
     boolean isDeviceLocked(int userId, int displayId);
     boolean isDeviceSecure(int userId, int displayId);
+    @EnforcePermission("TRUST_LISTENER")
     boolean isTrustUsuallyManaged(int userId);
     void unlockedByBiometricForUser(int userId, in BiometricSourceType source);
     void clearAllBiometricRecognized(in BiometricSourceType target, int unlockedUser);
diff --git a/core/java/android/app/usage/IUsageStatsManager.aidl b/core/java/android/app/usage/IUsageStatsManager.aidl
index d4fbdc6..cc78f1a 100644
--- a/core/java/android/app/usage/IUsageStatsManager.aidl
+++ b/core/java/android/app/usage/IUsageStatsManager.aidl
@@ -50,11 +50,15 @@
     void reportChooserSelection(String packageName, int userId, String contentType,
             in String[] annotations, String action);
     int getAppStandbyBucket(String packageName, String callingPackage, int userId);
+    @EnforcePermission("CHANGE_APP_IDLE_STATE")
     void setAppStandbyBucket(String packageName, int bucket, int userId);
     ParceledListSlice getAppStandbyBuckets(String callingPackage, int userId);
+    @EnforcePermission("CHANGE_APP_IDLE_STATE")
     void setAppStandbyBuckets(in ParceledListSlice appBuckets, int userId);
     int getAppMinStandbyBucket(String packageName, String callingPackage, int userId);
+    @EnforcePermission("CHANGE_APP_LAUNCH_TIME_ESTIMATE")
     void setEstimatedLaunchTime(String packageName, long estimatedLaunchTime, int userId);
+    @EnforcePermission("CHANGE_APP_LAUNCH_TIME_ESTIMATE")
     void setEstimatedLaunchTimes(in ParceledListSlice appLaunchTimes, int userId);
     void registerAppUsageObserver(int observerId, in String[] packages, long timeLimitMs,
             in PendingIntent callback, String callingPackage);
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 966347f..fd94969 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -1167,7 +1167,9 @@
      * @param intent        The intent of the service which will be providing the data to the
      *                      RemoteViewsAdapter.
      * @param connection    The callback interface to be notified when a connection is made or lost.
-     * @param flags         Flags used for binding to the service
+     * @param flags         Flags used for binding to the service. Currently only
+     *                     {@link Context#BIND_AUTO_CREATE} and
+     *                     {@link Context#BIND_FOREGROUND_SERVICE_WHILE_AWAKE} are supported.
      *
      * @see Context#getServiceDispatcher(ServiceConnection, Handler, int)
      * @hide
diff --git a/core/java/android/content/ClipboardManager.java b/core/java/android/content/ClipboardManager.java
index d41cda1..85af877 100644
--- a/core/java/android/content/ClipboardManager.java
+++ b/core/java/android/content/ClipboardManager.java
@@ -129,7 +129,11 @@
         try {
             Objects.requireNonNull(clip);
             clip.prepareToLeaveProcess(true);
-            mService.setPrimaryClip(clip, mContext.getOpPackageName(), mContext.getUserId());
+            mService.setPrimaryClip(
+                    clip,
+                    mContext.getOpPackageName(),
+                    mContext.getAttributionTag(),
+                    mContext.getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -154,7 +158,11 @@
             Objects.requireNonNull(sourcePackage);
             clip.prepareToLeaveProcess(true);
             mService.setPrimaryClipAsPackage(
-                    clip, mContext.getOpPackageName(), mContext.getUserId(), sourcePackage);
+                    clip,
+                    mContext.getOpPackageName(),
+                    mContext.getAttributionTag(),
+                    mContext.getUserId(),
+                    sourcePackage);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -167,7 +175,10 @@
      */
     public void clearPrimaryClip() {
         try {
-            mService.clearPrimaryClip(mContext.getOpPackageName(), mContext.getUserId());
+            mService.clearPrimaryClip(
+                    mContext.getOpPackageName(),
+                    mContext.getAttributionTag(),
+                    mContext.getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -183,24 +194,29 @@
      */
     public @Nullable ClipData getPrimaryClip() {
         try {
-            return mService.getPrimaryClip(mContext.getOpPackageName(), mContext.getUserId());
+            return mService.getPrimaryClip(
+                    mContext.getOpPackageName(),
+                    mContext.getAttributionTag(),
+                    mContext.getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
     /**
-     * Returns a description of the current primary clip on the clipboard
-     * but not a copy of its data.
+     * Returns a description of the current primary clip on the clipboard but not a copy of its
+     * data.
      *
-     * <em>If the application is not the default IME or does not have input focus this return
+     * <p><em>If the application is not the default IME or does not have input focus this return
      * {@code null}.</em>
      *
      * @see #setPrimaryClip(ClipData)
      */
     public @Nullable ClipDescription getPrimaryClipDescription() {
         try {
-            return mService.getPrimaryClipDescription(mContext.getOpPackageName(),
+            return mService.getPrimaryClipDescription(
+                    mContext.getOpPackageName(),
+                    mContext.getAttributionTag(),
                     mContext.getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -215,7 +231,10 @@
      */
     public boolean hasPrimaryClip() {
         try {
-            return mService.hasPrimaryClip(mContext.getOpPackageName(), mContext.getUserId());
+            return mService.hasPrimaryClip(
+                    mContext.getOpPackageName(),
+                    mContext.getAttributionTag(),
+                    mContext.getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -226,7 +245,9 @@
             if (mPrimaryClipChangedListeners.isEmpty()) {
                 try {
                     mService.addPrimaryClipChangedListener(
-                            mPrimaryClipChangedServiceListener, mContext.getOpPackageName(),
+                            mPrimaryClipChangedServiceListener,
+                            mContext.getOpPackageName(),
+                            mContext.getAttributionTag(),
                             mContext.getUserId());
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
@@ -242,7 +263,9 @@
             if (mPrimaryClipChangedListeners.isEmpty()) {
                 try {
                     mService.removePrimaryClipChangedListener(
-                            mPrimaryClipChangedServiceListener, mContext.getOpPackageName(),
+                            mPrimaryClipChangedServiceListener,
+                            mContext.getOpPackageName(),
+                            mContext.getAttributionTag(),
                             mContext.getUserId());
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
@@ -280,7 +303,10 @@
     @Deprecated
     public boolean hasText() {
         try {
-            return mService.hasClipboardText(mContext.getOpPackageName(), mContext.getUserId());
+            return mService.hasClipboardText(
+                    mContext.getOpPackageName(),
+                    mContext.getAttributionTag(),
+                    mContext.getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -297,7 +323,10 @@
     @RequiresPermission(Manifest.permission.SET_CLIP_SOURCE)
     public String getPrimaryClipSource() {
         try {
-            return mService.getPrimaryClipSource(mContext.getOpPackageName(), mContext.getUserId());
+            return mService.getPrimaryClipSource(
+                    mContext.getOpPackageName(),
+                    mContext.getAttributionTag(),
+                    mContext.getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 7b9d37e..3779453 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -980,7 +980,7 @@
         @Override
         public void onResult(Bundle result) {
             synchronized (this) {
-                ParcelableException e = result.getParcelable(REMOTE_CALLBACK_ERROR);
+                ParcelableException e = result.getParcelable(REMOTE_CALLBACK_ERROR, android.os.ParcelableException.class);
                 if (e != null) {
                     Throwable t = e.getCause();
                     if (t instanceof RuntimeException) {
@@ -1021,7 +1021,7 @@
     private static class UriResultListener extends ResultListener<Uri> {
         @Override
         protected Uri getResultFromBundle(Bundle result) {
-            return result.getParcelable(REMOTE_CALLBACK_RESULT);
+            return result.getParcelable(REMOTE_CALLBACK_RESULT, android.net.Uri.class);
         }
     }
 
diff --git a/core/java/android/content/IClipboard.aidl b/core/java/android/content/IClipboard.aidl
index 102b8e7..46ece2b 100644
--- a/core/java/android/content/IClipboard.aidl
+++ b/core/java/android/content/IClipboard.aidl
@@ -26,22 +26,22 @@
  * {@hide}
  */
 interface IClipboard {
-    void setPrimaryClip(in ClipData clip, String callingPackage, int userId);
-    void setPrimaryClipAsPackage(in ClipData clip, String callingPackage, int userId,
+    void setPrimaryClip(in ClipData clip, String callingPackage, String attributionTag, int userId);
+    void setPrimaryClipAsPackage(in ClipData clip, String callingPackage, String attributionTag, int userId,
             String sourcePackage);
-    void clearPrimaryClip(String callingPackage, int userId);
-    ClipData getPrimaryClip(String pkg, int userId);
-    ClipDescription getPrimaryClipDescription(String callingPackage, int userId);
-    boolean hasPrimaryClip(String callingPackage, int userId);
+    void clearPrimaryClip(String callingPackage, String attributionTag, int userId);
+    ClipData getPrimaryClip(String pkg, String attributionTag, int userId);
+    ClipDescription getPrimaryClipDescription(String callingPackage, String attributionTag, int userId);
+    boolean hasPrimaryClip(String callingPackage, String attributionTag, int userId);
     void addPrimaryClipChangedListener(in IOnPrimaryClipChangedListener listener,
-            String callingPackage, int userId);
+            String callingPackage, String attributionTag, int userId);
     void removePrimaryClipChangedListener(in IOnPrimaryClipChangedListener listener,
-            String callingPackage, int userId);
+            String callingPackage, String attributionTag, int userId);
 
     /**
      * Returns true if the clipboard contains text; false otherwise.
      */
-    boolean hasClipboardText(String callingPackage, int userId);
+    boolean hasClipboardText(String callingPackage, String attributionTag, int userId);
 
-    String getPrimaryClipSource(String callingPackage, int userId);
+    String getPrimaryClipSource(String callingPackage, String attributionTag, int userId);
 }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 7a88a057..26b2f07 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -11940,7 +11940,7 @@
         // passed via Bluetooth intents
         if (mAction != null && mAction.startsWith("android.bluetooth.")
                 && hasExtra(BluetoothDevice.EXTRA_DEVICE)) {
-            final BluetoothDevice device = getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+            final BluetoothDevice device = getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, BluetoothDevice.class);
             if (device != null) {
                 device.prepareToEnterProcess(source);
             }
@@ -11989,12 +11989,12 @@
         }
         String action = getAction();
         if (ACTION_SEND.equals(action)) {
-            final Uri stream = getParcelableExtra(EXTRA_STREAM);
+            final Uri stream = getParcelableExtra(EXTRA_STREAM, Uri.class);
             if (stream != null) {
                 putExtra(EXTRA_STREAM, maybeAddUserId(stream, contentUserHint));
             }
         } else if (ACTION_SEND_MULTIPLE.equals(action)) {
-            final ArrayList<Uri> streams = getParcelableArrayListExtra(EXTRA_STREAM);
+            final ArrayList<Uri> streams = getParcelableArrayListExtra(EXTRA_STREAM, Uri.class);
             if (streams != null) {
                 ArrayList<Uri> newStreams = new ArrayList<Uri>();
                 for (int i = 0; i < streams.size(); i++) {
@@ -12003,7 +12003,7 @@
                 putParcelableArrayListExtra(EXTRA_STREAM, newStreams);
             }
         } else if (isImageCaptureIntent()) {
-            final Uri output = getParcelableExtra(MediaStore.EXTRA_OUTPUT);
+            final Uri output = getParcelableExtra(MediaStore.EXTRA_OUTPUT, Uri.class);
             if (output != null) {
                 putExtra(MediaStore.EXTRA_OUTPUT, maybeAddUserId(output, contentUserHint));
             }
@@ -12047,7 +12047,7 @@
 
             boolean migrated = false;
             try {
-                final Intent intent = getParcelableExtra(EXTRA_INTENT);
+                final Intent intent = getParcelableExtra(EXTRA_INTENT, Intent.class);
                 if (intent != null) {
                     migrated |= intent.migrateExtraStreamToClipData(context);
                 }
@@ -12069,7 +12069,7 @@
 
         } else if (ACTION_SEND.equals(action)) {
             try {
-                final Uri stream = getParcelableExtra(EXTRA_STREAM);
+                final Uri stream = getParcelableExtra(EXTRA_STREAM, Uri.class);
                 final CharSequence text = getCharSequenceExtra(EXTRA_TEXT);
                 final String htmlText = getStringExtra(EXTRA_HTML_TEXT);
                 if (stream != null || text != null || htmlText != null) {
@@ -12085,7 +12085,7 @@
 
         } else if (ACTION_SEND_MULTIPLE.equals(action)) {
             try {
-                final ArrayList<Uri> streams = getParcelableArrayListExtra(EXTRA_STREAM);
+                final ArrayList<Uri> streams = getParcelableArrayListExtra(EXTRA_STREAM, Uri.class);
                 final ArrayList<CharSequence> texts = getCharSequenceArrayListExtra(EXTRA_TEXT);
                 final ArrayList<String> htmlTexts = getStringArrayListExtra(EXTRA_HTML_TEXT);
                 int num = -1;
@@ -12124,7 +12124,7 @@
         } else if (isImageCaptureIntent()) {
             Uri output;
             try {
-                output = getParcelableExtra(MediaStore.EXTRA_OUTPUT);
+                output = getParcelableExtra(MediaStore.EXTRA_OUTPUT, Uri.class);
             } catch (ClassCastException e) {
                 return false;
             }
diff --git a/core/java/android/content/SyncActivityTooManyDeletes.java b/core/java/android/content/SyncActivityTooManyDeletes.java
index 093fb08..1a4eedd 100644
--- a/core/java/android/content/SyncActivityTooManyDeletes.java
+++ b/core/java/android/content/SyncActivityTooManyDeletes.java
@@ -54,7 +54,7 @@
         }
 
         mNumDeletes = extras.getLong("numDeletes");
-        mAccount = (Account) extras.getParcelable("account");
+        mAccount = (Account) extras.getParcelable("account", android.accounts.Account.class);
         mAuthority = extras.getString("authority");
         mProvider = extras.getString("provider");
 
diff --git a/core/java/android/content/integrity/AppInstallMetadata.java b/core/java/android/content/integrity/AppInstallMetadata.java
index 9874890..91b0007 100644
--- a/core/java/android/content/integrity/AppInstallMetadata.java
+++ b/core/java/android/content/integrity/AppInstallMetadata.java
@@ -129,9 +129,18 @@
     @Override
     public String toString() {
         return String.format(
-                "AppInstallMetadata { PackageName = %s, AppCerts = %s, InstallerName = %s,"
-                    + " InstallerCerts = %s, VersionCode = %d, PreInstalled = %b, StampPresent ="
-                    + " %b, StampVerified = %b, StampTrusted = %b, StampCert = %s }",
+                "AppInstallMetadata {"
+                    + " PackageName = %s,"
+                    + " AppCerts = %s,"
+                    + " AppCertsLineage = %s,"
+                    + " InstallerName = %s,"
+                    + " InstallerCerts = %s,"
+                    + " VersionCode = %d,"
+                    + " PreInstalled = %b,"
+                    + " StampPresent = %b,"
+                    + " StampVerified = %b,"
+                    + " StampTrusted = %b,"
+                    + " StampCert = %s }",
                 mPackageName,
                 mAppCertificates,
                 mAppCertificateLineage,
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index f08fa51..756c468 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -178,7 +178,7 @@
      * signature checks} or
      * <a href="https://developer.android.com/training/articles/security-tips#Permissions">permissions</a>.
      *
-     * <p><b>Warning:</b> Note that does flag not behave the same as
+     * <p><b>Warning:</b> Note that this flag does not behave the same as
      * {@link android.R.attr#protectionLevel android:protectionLevel} {@code system} or
      * {@code signatureOrSystem}.
      */
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 2ef1c78..35afe9f 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -715,8 +715,6 @@
 
     String getIncidentReportApproverPackageName();
 
-    String getContentCaptureServicePackageName();
-
     boolean isPackageStateProtected(String packageName, int userId);
 
     void sendDeviceCustomizationReadyBroadcast();
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 301d1bbc..f780f81 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -2062,7 +2062,7 @@
      * the {@link #EXTRA_PIN_ITEM_REQUEST} extra.
      */
     public PinItemRequest getPinItemRequest(Intent intent) {
-        return intent.getParcelableExtra(EXTRA_PIN_ITEM_REQUEST);
+        return intent.getParcelableExtra(EXTRA_PIN_ITEM_REQUEST, android.content.pm.LauncherApps.PinItemRequest.class);
     }
 
     /**
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 53c23f3..ccc2441 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -10083,15 +10083,21 @@
     }
 
     /**
-     * @return the system defined content capture package name, or null if there's none.
+     * @deprecated This function throws an {@link UnsupportedOperationException}. For pre-granting
+     * permissions, instead of looking up the package that provides {@code ContentCaptureService},
+     * use roles.
      *
      * @hide
      */
+    // This function cannot yet be removed because it is referenced from GTS tests. The tests have
+    // been updated to not rely on it when running on Android T and above, but in order to compile
+    // the tests we must keep this method.
+    @Deprecated
     @TestApi
     @Nullable
-    public String getContentCaptureServicePackageName() {
+    public final String getContentCaptureServicePackageName() {
         throw new UnsupportedOperationException(
-                "getContentCaptureServicePackageName not implemented in subclass");
+                "getContentCaptureServicePackageName is deprecated");
     }
 
     /**
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 44dc28d..c15b3e0 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -713,6 +713,15 @@
         if (!checkUseInstalledOrHidden(flags, state, p.applicationInfo) || !p.isMatch(flags)) {
             return null;
         }
+
+        final ApplicationInfo applicationInfo;
+        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
+                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
+            applicationInfo = generateApplicationInfo(p, flags, state, userId);
+        } else {
+            applicationInfo = null;
+        }
+
         PackageInfo pi = new PackageInfo();
         pi.packageName = p.packageName;
         pi.splitNames = p.splitNames;
@@ -773,7 +782,7 @@
                         if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(a.className)) {
                             continue;
                         }
-                        res[num++] = generateActivityInfo(a, flags, state, userId);
+                        res[num++] = generateActivityInfo(a, flags, state, userId, applicationInfo);
                     }
                 }
                 pi.activities = ArrayUtils.trimToSize(res, num);
@@ -787,7 +796,7 @@
                 for (int i = 0; i < N; i++) {
                     final Activity a = p.receivers.get(i);
                     if (isMatch(state, a.info, flags)) {
-                        res[num++] = generateActivityInfo(a, flags, state, userId);
+                        res[num++] = generateActivityInfo(a, flags, state, userId, applicationInfo);
                     }
                 }
                 pi.receivers = ArrayUtils.trimToSize(res, num);
@@ -801,7 +810,7 @@
                 for (int i = 0; i < N; i++) {
                     final Service s = p.services.get(i);
                     if (isMatch(state, s.info, flags)) {
-                        res[num++] = generateServiceInfo(s, flags, state, userId);
+                        res[num++] = generateServiceInfo(s, flags, state, userId, applicationInfo);
                     }
                 }
                 pi.services = ArrayUtils.trimToSize(res, num);
@@ -815,7 +824,8 @@
                 for (int i = 0; i < N; i++) {
                     final Provider pr = p.providers.get(i);
                     if (isMatch(state, pr.info, flags)) {
-                        res[num++] = generateProviderInfo(pr, flags, state, userId);
+                        res[num++] = generateProviderInfo(pr, flags, state, userId,
+                                applicationInfo);
                     }
                 }
                 pi.providers = ArrayUtils.trimToSize(res, num);
@@ -8216,6 +8226,11 @@
     @UnsupportedAppUsage
     public static final ActivityInfo generateActivityInfo(Activity a, int flags,
             FrameworkPackageUserState state, int userId) {
+        return generateActivityInfo(a, flags, state, userId, null);
+    }
+
+    private static ActivityInfo generateActivityInfo(Activity a, int flags,
+            FrameworkPackageUserState state, int userId, ApplicationInfo applicationInfo) {
         if (a == null) return null;
         if (!checkUseInstalledOrHidden(flags, state, a.owner.applicationInfo)) {
             return null;
@@ -8227,7 +8242,12 @@
         // Make shallow copies so we can store the metadata safely
         ActivityInfo ai = new ActivityInfo(a.info);
         ai.metaData = a.metaData;
-        ai.applicationInfo = generateApplicationInfo(a.owner, flags, state, userId);
+
+        if (applicationInfo == null) {
+            applicationInfo = generateApplicationInfo(a.owner, flags, state, userId);
+        }
+        ai.applicationInfo = applicationInfo;
+
         return ai;
     }
 
@@ -8308,6 +8328,11 @@
     @UnsupportedAppUsage
     public static final ServiceInfo generateServiceInfo(Service s, int flags,
             FrameworkPackageUserState state, int userId) {
+        return generateServiceInfo(s, flags, state, userId, null);
+    }
+
+    private static ServiceInfo generateServiceInfo(Service s, int flags,
+            FrameworkPackageUserState state, int userId, ApplicationInfo applicationInfo) {
         if (s == null) return null;
         if (!checkUseInstalledOrHidden(flags, state, s.owner.applicationInfo)) {
             return null;
@@ -8319,7 +8344,12 @@
         // Make shallow copies so we can store the metadata safely
         ServiceInfo si = new ServiceInfo(s.info);
         si.metaData = s.metaData;
-        si.applicationInfo = generateApplicationInfo(s.owner, flags, state, userId);
+
+        if (applicationInfo == null) {
+            applicationInfo = generateApplicationInfo(s.owner, flags, state, userId);
+        }
+        si.applicationInfo = applicationInfo;
+
         return si;
     }
 
@@ -8406,13 +8436,18 @@
     @UnsupportedAppUsage
     public static final ProviderInfo generateProviderInfo(Provider p, int flags,
             FrameworkPackageUserState state, int userId) {
+        return generateProviderInfo(p, flags, state, userId, null);
+    }
+
+    private static ProviderInfo generateProviderInfo(Provider p, int flags,
+            FrameworkPackageUserState state, int userId, ApplicationInfo applicationInfo) {
         if (p == null) return null;
         if (!checkUseInstalledOrHidden(flags, state, p.owner.applicationInfo)) {
             return null;
         }
         if (!copyNeeded(flags, p.owner, state, p.metaData, userId)
                 && ((flags & PackageManager.GET_URI_PERMISSION_PATTERNS) != 0
-                        || p.info.uriPermissionPatterns == null)) {
+                || p.info.uriPermissionPatterns == null)) {
             updateApplicationInfo(p.info.applicationInfo, flags, state);
             return p.info;
         }
@@ -8422,7 +8457,12 @@
         if ((flags & PackageManager.GET_URI_PERMISSION_PATTERNS) == 0) {
             pi.uriPermissionPatterns = null;
         }
-        pi.applicationInfo = generateApplicationInfo(p.owner, flags, state, userId);
+
+        if (applicationInfo == null) {
+            applicationInfo = generateApplicationInfo(p.owner, flags, state, userId);
+        }
+        pi.applicationInfo = applicationInfo;
+
         return pi;
     }
 
diff --git a/core/java/android/hardware/biometrics/BiometricConstants.java b/core/java/android/hardware/biometrics/BiometricConstants.java
index 99e4feb..943eee4 100644
--- a/core/java/android/hardware/biometrics/BiometricConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricConstants.java
@@ -157,6 +157,11 @@
     int BIOMETRIC_ERROR_SENSOR_PRIVACY_ENABLED = 18;
 
     /**
+     * A power press stopped this biometric operation.
+     * @hide
+     */
+    int BIOMETRIC_ERROR_POWER_PRESSED = 19;
+    /**
      * This constant is only used by SystemUI. It notifies SystemUI that authentication was paused
      * because the authentication attempt was unsuccessful.
      * @hide
diff --git a/core/java/android/hardware/biometrics/BiometricFaceConstants.java b/core/java/android/hardware/biometrics/BiometricFaceConstants.java
index fd46f24..2b62b98 100644
--- a/core/java/android/hardware/biometrics/BiometricFaceConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricFaceConstants.java
@@ -70,6 +70,7 @@
             BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED,
             BIOMETRIC_ERROR_RE_ENROLL,
             FACE_ERROR_UNKNOWN,
+            BIOMETRIC_ERROR_POWER_PRESSED,
     })
     @Retention(RetentionPolicy.SOURCE)
     @interface FaceError {}
@@ -184,6 +185,12 @@
     int FACE_ERROR_UNKNOWN = 17;
 
     /**
+     * A power press stopped this biometric operation.
+     * @hide
+     */
+    int BIOMETRIC_ERROR_POWER_PRESSED = 19;
+
+    /**
      * Vendor codes received from the HAL start at 0. Codes that the framework exposes to keyguard
      * append this value for some reason. We should probably remove this and just send the actual
      * vendor code.
diff --git a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
index d8ebb62..98f571b 100644
--- a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
@@ -61,7 +61,8 @@
             BIOMETRIC_ERROR_RE_ENROLL,
             BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED,
             FINGERPRINT_ERROR_UNKNOWN,
-            FINGERPRINT_ERROR_BAD_CALIBRATION})
+            FINGERPRINT_ERROR_BAD_CALIBRATION,
+            BIOMETRIC_ERROR_POWER_PRESSED})
     @Retention(RetentionPolicy.SOURCE)
     @interface FingerprintError {}
 
@@ -188,6 +189,12 @@
     int FINGERPRINT_ERROR_BAD_CALIBRATION = 18;
 
     /**
+     * A power press stopped this biometric operation.
+     * @hide
+     */
+    int BIOMETRIC_ERROR_POWER_PRESSED = 19;
+
+    /**
      * @hide
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
diff --git a/core/java/android/hardware/biometrics/BiometricStateListener.java b/core/java/android/hardware/biometrics/BiometricStateListener.java
index 2ac0c1e..b167cc6 100644
--- a/core/java/android/hardware/biometrics/BiometricStateListener.java
+++ b/core/java/android/hardware/biometrics/BiometricStateListener.java
@@ -46,6 +46,14 @@
     public @interface State {
     }
 
+    // The sensor received a touch.
+    public static final int ACTION_SENSOR_TOUCH = 0;
+
+    @IntDef({ACTION_SENSOR_TOUCH})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Action {
+    }
+
     /**
      * Defines behavior in response to state update
      * @param newState new state of the biometric sensor
@@ -53,6 +61,13 @@
     public void onStateChanged(@BiometricStateListener.State int newState) {
     }
 
+
+    /**
+     * Invoked when a biometric action has occurred.
+     */
+    public void onBiometricAction(@BiometricStateListener.Action int action) {
+    }
+
     /**
      * Invoked when enrollment state changes for the specified user
      */
diff --git a/core/java/android/hardware/biometrics/IAuthService.aidl b/core/java/android/hardware/biometrics/IAuthService.aidl
index 91f794c..7c3cc10b 100644
--- a/core/java/android/hardware/biometrics/IAuthService.aidl
+++ b/core/java/android/hardware/biometrics/IAuthService.aidl
@@ -33,12 +33,15 @@
  */
 interface IAuthService {
     // Creates a test session with the specified sensorId
+    @EnforcePermission("TEST_BIOMETRIC")
     ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName);
 
     // Retrieve static sensor properties for all biometric sensors
+    @EnforcePermission("TEST_BIOMETRIC")
     List<SensorPropertiesInternal> getSensorProperties(String opPackageName);
 
     // Retrieve the package where BIometricOrompt's UI is implemented
+    @EnforcePermission("TEST_BIOMETRIC")
     String getUiPackage();
 
     // Requests authentication. The service chooses the appropriate biometric to use, and shows
diff --git a/core/java/android/hardware/biometrics/IBiometricService.aidl b/core/java/android/hardware/biometrics/IBiometricService.aidl
index 42aad36..08f9ed6 100644
--- a/core/java/android/hardware/biometrics/IBiometricService.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricService.aidl
@@ -31,59 +31,74 @@
  */
 interface IBiometricService {
     // Creates a test session with the specified sensorId
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName);
 
     // Retrieve static sensor properties for all biometric sensors
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     List<SensorPropertiesInternal> getSensorProperties(String opPackageName);
 
     // Requests authentication. The service chooses the appropriate biometric to use, and shows
     // the corresponding BiometricDialog. A requestId is returned that can be used to cancel
     // this operation.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     long authenticate(IBinder token, long operationId, int userId,
             IBiometricServiceReceiver receiver, String opPackageName, in PromptInfo promptInfo);
 
     // Cancel authentication for the given requestId.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void cancelAuthentication(IBinder token, String opPackageName, long requestId);
 
     // Checks if biometrics can be used.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     int canAuthenticate(String opPackageName, int userId, int callingUserId, int authenticators);
 
     // Checks if any biometrics are enrolled.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     boolean hasEnrolledBiometrics(int userId, String opPackageName);
 
     // Registers an authenticator (e.g. face, fingerprint, iris).
     // Id must be unique, whereas strength and modality don't need to be.
     // TODO(b/123321528): Turn strength and modality into enums.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void registerAuthenticator(int id, int modality, int strength,
             IBiometricAuthenticator authenticator);
 
     // Register callback for when keyguard biometric eligibility changes.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void registerEnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback,
             int callingUserId);
 
     // Notify BiometricService when <Biometric>Service is ready to start the prepared client.
     // Client lifecycle is still managed in <Biometric>Service.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void onReadyForAuthentication(long requestId, int cookie);
 
     // Requests all BIOMETRIC_STRONG sensors to have their authenticatorId invalidated for the
     // specified user. This happens when enrollments have been added on devices with multiple
     // biometric sensors.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void invalidateAuthenticatorIds(int userId, int fromSensorId, IInvalidationCallback callback);
 
     // Get a list of AuthenticatorIDs for authenticators which have enrolled templates and meet
     // the requirements for integrating with Keystore. The AuthenticatorID are known in Keystore
     // land as SIDs, and are used during key generation.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     long[] getAuthenticatorIds(int callingUserId);
 
     // See documentation in BiometricManager.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void resetLockoutTimeBound(IBinder token, String opPackageName, int fromSensorId, int userId,
             in byte[] hardwareAuthToken);
 
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     int getCurrentStrength(int sensorId);
 
     // Returns a bit field of the modality (or modalities) that are will be used for authentication.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     int getCurrentModality(String opPackageName, int userId, int callingUserId, int authenticators);
 
     // Returns a bit field of the authentication modalities that are supported by this device.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     int getSupportedModalities(int authenticators);
 }
diff --git a/core/java/android/hardware/biometrics/IBiometricStateListener.aidl b/core/java/android/hardware/biometrics/IBiometricStateListener.aidl
index 5bdced0..6bb170d 100644
--- a/core/java/android/hardware/biometrics/IBiometricStateListener.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricStateListener.aidl
@@ -22,5 +22,6 @@
  */
 oneway interface IBiometricStateListener {
     void onStateChanged(int newState);
+    void onBiometricAction(int action);
     void onEnrollmentsChanged(int userId, int sensorId, boolean hasEnrollments);
 }
diff --git a/core/java/android/hardware/biometrics/ITestSession.aidl b/core/java/android/hardware/biometrics/ITestSession.aidl
index f8395a1..df9f504 100644
--- a/core/java/android/hardware/biometrics/ITestSession.aidl
+++ b/core/java/android/hardware/biometrics/ITestSession.aidl
@@ -27,28 +27,36 @@
     // portion of the framework code that would otherwise require human interaction. Note that
     // secure pathways such as HAT/Keystore are not testable, since they depend on the TEE or its
     // equivalent for the secret key.
+    @EnforcePermission("TEST_BIOMETRIC")
     void setTestHalEnabled(boolean enableTestHal);
 
     // Starts the enrollment process. This should generally be used when the test HAL is enabled.
+    @EnforcePermission("TEST_BIOMETRIC")
     void startEnroll(int userId);
 
     // Finishes the enrollment process. Simulates the HAL's callback.
+    @EnforcePermission("TEST_BIOMETRIC")
     void finishEnroll(int userId);
 
     // Simulates a successful authentication, but does not provide a valid HAT.
+    @EnforcePermission("TEST_BIOMETRIC")
     void acceptAuthentication(int userId);
 
     // Simulates a rejected attempt.
+    @EnforcePermission("TEST_BIOMETRIC")
     void rejectAuthentication(int userId);
 
     // Simulates an acquired message from the HAL.
+    @EnforcePermission("TEST_BIOMETRIC")
     void notifyAcquired(int userId, int acquireInfo);
 
     // Simulates an error message from the HAL.
+    @EnforcePermission("TEST_BIOMETRIC")
     void notifyError(int userId, int errorCode);
 
     // Matches the framework's cached enrollments against the HAL's enrollments. Any enrollment
     // that isn't known by both sides are deleted. This should generally be used when the test
     // HAL is disabled (e.g. to clean up after a test).
+    @EnforcePermission("TEST_BIOMETRIC")
     void cleanupInternalState(int userId);
 }
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index dac55ae..8db298f 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -1325,7 +1325,8 @@
      * flashlight brightness level via
      * {@link android.hardware.camera2.CameraManager#turnOnTorchWithStrengthLevel }.
      * If this value is equal to 1, flashlight brightness control is not supported.
-     * The value for this key will be null for devices with no flash unit.</p>
+     * The value for this key will be null for devices with no flash unit.
+     * This level must be set to a safe value to prevent any burn out issues.</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      */
     @PublicKey
diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
index 4d0ba63..336ef7a 100644
--- a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
@@ -1739,6 +1739,20 @@
                     // abruptly.
                     Log.w(TAG, "Output surface likely abandoned, dropping buffer!");
                     img.close();
+                } catch (RuntimeException e) {
+                    // NOTE: This is intended to catch RuntimeException from ImageReader.detachImage
+                    // ImageReader.detachImage is not supposed to throw RuntimeExceptions but the
+                    // bug went unchecked for a few years and now its behavior cannot be changed
+                    // without breaking backwards compatibility.
+
+                    if (!e.getClass().equals(RuntimeException.class)) {
+                        // re-throw any exceptions that aren't base RuntimeException since they are
+                        // coming from elsewhere, and we shouldn't silently drop those.
+                        throw e;
+                    }
+
+                    Log.w(TAG, "Output surface likely abandoned, dropping buffer!");
+                    img.close();
                 }
             }
         }
@@ -1773,9 +1787,23 @@
                 }
                 try {
                     reader.detachImage(img);
-                } catch (Exception e) {
-                    Log.e(TAG,
-                            "Failed to detach image!");
+                } catch (IllegalStateException e) {
+                    Log.e(TAG, "Failed to detach image!");
+                    img.close();
+                    return;
+                } catch (RuntimeException e) {
+                    // NOTE: This is intended to catch RuntimeException from ImageReader.detachImage
+                    // ImageReader.detachImage is not supposed to throw RuntimeExceptions but the
+                    // bug went unchecked for a few years and now its behavior cannot be changed
+                    // without breaking backwards compatibility.
+
+                    if (!e.getClass().equals(RuntimeException.class)) {
+                        // re-throw any exceptions that aren't base RuntimeException since they are
+                        // coming from elsewhere, and we shouldn't silently drop those.
+                        throw e;
+                    }
+
+                    Log.e(TAG, "Failed to detach image!");
                     img.close();
                     return;
                 }
diff --git a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableArray.java b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableArray.java
index 6cf5d60..cbd8066 100644
--- a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableArray.java
+++ b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableArray.java
@@ -45,46 +45,41 @@
     private static final boolean DEBUG = false;
 
     private static interface PrimitiveArrayFiller {
-        public void fillPosition(Object arr, int index, ByteBuffer buffer);
+        public void fillArray(Object arr, int size, ByteBuffer buffer);
         static PrimitiveArrayFiller getPrimitiveArrayFiller(Class<?> componentType) {
             if (componentType == int.class) {
                 return new PrimitiveArrayFiller() {
                       @Override
-                      public void fillPosition(Object arr, int index, ByteBuffer buffer) {
-                          int i = buffer.getInt();
-                          Array.setInt(arr, index, i);
+                      public void fillArray(Object arr, int size, ByteBuffer buffer) {
+                          buffer.asIntBuffer().get(int[].class.cast(arr), 0, size);
                       }
                 };
             } else if (componentType == float.class) {
                 return new PrimitiveArrayFiller() {
                       @Override
-                      public void fillPosition(Object arr, int index, ByteBuffer buffer) {
-                          float i = buffer.getFloat();
-                          Array.setFloat(arr, index, i);
+                      public void fillArray(Object arr, int size, ByteBuffer buffer) {
+                          buffer.asFloatBuffer().get(float[].class.cast(arr), 0, size);
                       }
                 };
             } else if (componentType == long.class) {
                 return new PrimitiveArrayFiller() {
                       @Override
-                      public void fillPosition(Object arr, int index, ByteBuffer buffer) {
-                          long i = buffer.getLong();
-                          Array.setLong(arr, index, i);
+                      public void fillArray(Object arr, int size, ByteBuffer buffer) {
+                          buffer.asLongBuffer().get(long[].class.cast(arr), 0, size);
                       }
                 };
             } else if (componentType == double.class) {
                 return new PrimitiveArrayFiller() {
                       @Override
-                      public void fillPosition(Object arr, int index, ByteBuffer buffer) {
-                          double i = buffer.getDouble();
-                          Array.setDouble(arr, index, i);
+                      public void fillArray(Object arr, int size, ByteBuffer buffer) {
+                          buffer.asDoubleBuffer().get(double[].class.cast(arr), 0, size);
                       }
                 };
             } else if (componentType == byte.class) {
                 return new PrimitiveArrayFiller() {
                       @Override
-                      public void fillPosition(Object arr, int index, ByteBuffer buffer) {
-                          byte i = buffer.get();
-                          Array.setByte(arr, index, i);
+                      public void fillArray(Object arr, int size, ByteBuffer buffer) {
+                          buffer.get(byte[].class.cast(arr), 0, size);
                       }
                 };
             }
@@ -93,13 +88,6 @@
         }
     };
 
-    static void unmarshalPrimitiveArray(Object arr, int size, ByteBuffer buffer,
-            PrimitiveArrayFiller filler) {
-        for (int i = 0; i < size; i++) {
-            filler.fillPosition(arr, i, buffer);
-        }
-    }
-
     private class MarshalerArray extends Marshaler<T> {
         private final Class<T> mClass;
         private final Marshaler<?> mComponentMarshaler;
@@ -150,8 +138,8 @@
                 array = Array.newInstance(mComponentClass, arraySize);
                 if (isUnwrappedPrimitiveClass(mComponentClass) &&
                         mComponentClass == getPrimitiveTypeClass(mNativeType)) {
-                    unmarshalPrimitiveArray(array, arraySize, buffer,
-                            PrimitiveArrayFiller.getPrimitiveArrayFiller(mComponentClass));
+                    PrimitiveArrayFiller.getPrimitiveArrayFiller(mComponentClass).fillArray(array,
+                            arraySize, buffer);
                 } else {
                     for (int i = 0; i < arraySize; ++i) {
                         Object elem = mComponentMarshaler.unmarshal(buffer);
diff --git a/core/java/android/hardware/display/IColorDisplayManager.aidl b/core/java/android/hardware/display/IColorDisplayManager.aidl
index ef4f5f9..200cf736 100644
--- a/core/java/android/hardware/display/IColorDisplayManager.aidl
+++ b/core/java/android/hardware/display/IColorDisplayManager.aidl
@@ -23,9 +23,12 @@
     boolean isDeviceColorManaged();
 
     boolean setSaturationLevel(int saturationLevel);
+    @EnforcePermission("CONTROL_DISPLAY_COLOR_TRANSFORMS")
     boolean setAppSaturationLevel(String packageName, int saturationLevel);
+    @EnforcePermission("CONTROL_DISPLAY_COLOR_TRANSFORMS")
     boolean isSaturationActivated();
 
+    @EnforcePermission("CONTROL_DISPLAY_COLOR_TRANSFORMS")
     int getTransformCapabilities();
 
     boolean isNightDisplayActivated();
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index 989b001..369248e 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -33,24 +33,30 @@
 interface IFaceService {
 
     // Creates a test session with the specified sensorId
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName);
 
     // Requests a proto dump of the specified sensor
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer);
 
     // Retrieve static sensor properties for all face sensors
+    @EnforcePermission("MANAGE_BIOMETRIC")
     List<FaceSensorPropertiesInternal> getSensorPropertiesInternal(String opPackageName);
 
     // Retrieve static sensor properties for the specified sensor
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     FaceSensorPropertiesInternal getSensorProperties(int sensorId, String opPackageName);
 
     // Authenticate with a face. A requestId is returned that can be used to cancel this operation.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     long authenticate(IBinder token, long operationId, int userId, IFaceServiceReceiver receiver,
             String opPackageName, boolean isKeyguardBypassEnabled);
 
     // Uses the face hardware to detect for the presence of a face, without giving details
     // about accept/reject/lockout. A requestId is returned that can be used to cancel this
     // operation.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     long detectFace(IBinder token, int userId, IFaceServiceReceiver receiver, String opPackageName);
 
     // This method prepares the service to start authenticating, but doesn't start authentication.
@@ -58,80 +64,103 @@
     // called from BiometricService. The additional uid, pid, userId arguments should be determined
     // by BiometricService. To start authentication after the clients are ready, use
     // startPreparedClient().
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void prepareForAuthentication(int sensorId, boolean requireConfirmation, IBinder token,
             long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
             String opPackageName, long requestId, int cookie,
             boolean allowBackgroundAuthentication);
 
     // Starts authentication with the previously prepared client.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void startPreparedClient(int sensorId, int cookie);
 
     // Cancel authentication for the given requestId.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void cancelAuthentication(IBinder token, String opPackageName, long requestId);
 
     // Cancel face detection for the given requestId.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void cancelFaceDetect(IBinder token, String opPackageName, long requestId);
 
     // Same as above, with extra arguments.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void cancelAuthenticationFromService(int sensorId, IBinder token, String opPackageName, long requestId);
 
     // Start face enrollment
+    @EnforcePermission("MANAGE_BIOMETRIC")
     long enroll(int userId, IBinder token, in byte [] hardwareAuthToken, IFaceServiceReceiver receiver,
             String opPackageName, in int [] disabledFeatures,
             in Surface previewSurface, boolean debugConsent);
 
     // Start remote face enrollment
+    @EnforcePermission("MANAGE_BIOMETRIC")
     long enrollRemotely(int userId, IBinder token, in byte [] hardwareAuthToken, IFaceServiceReceiver receiver,
             String opPackageName, in int [] disabledFeatures);
 
     // Cancel enrollment in progress
+    @EnforcePermission("MANAGE_BIOMETRIC")
     void cancelEnrollment(IBinder token, long requestId);
 
     // Removes the specified face enrollment for the specified userId.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void remove(IBinder token, int faceId, int userId, IFaceServiceReceiver receiver,
             String opPackageName);
 
     // Removes all face enrollments for the specified userId.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void removeAll(IBinder token, int userId, IFaceServiceReceiver receiver, String opPackageName);
 
     // Get the enrolled face for user.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     List<Face> getEnrolledFaces(int sensorId, int userId, String opPackageName);
 
     // Determine if HAL is loaded and ready
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     boolean isHardwareDetected(int sensorId, String opPackageName);
 
     // Get a pre-enrollment authentication token
+    @EnforcePermission("MANAGE_BIOMETRIC")
     void generateChallenge(IBinder token, int sensorId, int userId, IFaceServiceReceiver receiver, String opPackageName);
 
     // Finish an enrollment sequence and invalidate the authentication token
+    @EnforcePermission("MANAGE_BIOMETRIC")
     void revokeChallenge(IBinder token, int sensorId, int userId, String opPackageName, long challenge);
 
     // Determine if a user has at least one enrolled face
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     boolean hasEnrolledFaces(int sensorId, int userId, String opPackageName);
 
     // Return the LockoutTracker status for the specified user
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     int getLockoutModeForUser(int sensorId, int userId);
 
     // Requests for the specified sensor+userId's authenticatorId to be invalidated
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void invalidateAuthenticatorId(int sensorId, int userId, IInvalidationCallback callback);
 
     // Gets the authenticator ID for face
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     long getAuthenticatorId(int sensorId, int callingUserId);
 
     // Reset the lockout when user authenticates with strong auth (e.g. PIN, pattern or password)
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void resetLockout(IBinder token, int sensorId, int userId, in byte [] hardwareAuthToken, String opPackageName);
 
     // Add a callback which gets notified when the face lockout period expired.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void addLockoutResetCallback(IBiometricServiceLockoutResetCallback callback, String opPackageName);
 
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void setFeature(IBinder token, int userId, int feature, boolean enabled,
             in byte [] hardwareAuthToken, IFaceServiceReceiver receiver, String opPackageName);
 
+    @EnforcePermission("MANAGE_BIOMETRIC")
     void getFeature(IBinder token, int userId, int feature, IFaceServiceReceiver receiver,
             String opPackageName);
 
     // Registers all HIDL and AIDL sensors. Only HIDL sensor properties need to be provided, because
     // AIDL sensor properties are retrieved directly from the available HALs. If no HIDL HALs exist,
     // hidlSensors must be non-null and empty. See AuthService.java
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void registerAuthenticators(in List<FaceSensorPropertiesInternal> hidlSensors);
 }
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 28f1f02..c614cdb 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -101,6 +101,7 @@
     private static final int MSG_FINGERPRINT_DETECTED = 107;
     private static final int MSG_UDFPS_POINTER_DOWN = 108;
     private static final int MSG_UDFPS_POINTER_UP = 109;
+    private static final int MSG_POWER_BUTTON_PRESSED = 110;
 
     /**
      * @hide
@@ -984,6 +985,16 @@
     }
 
     /**
+     * This is triggered by SideFpsEventHandler
+     * @hide
+     */
+    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
+    public void onPowerPressed() {
+        Slog.i(TAG, "onPowerPressed");
+        mHandler.obtainMessage(MSG_POWER_BUTTON_PRESSED).sendToTarget();
+    }
+
+    /**
      * Determine if there is at least one fingerprint enrolled.
      *
      * @return true if at least one fingerprint is enrolled, false otherwise
@@ -1196,6 +1207,9 @@
                 case MSG_UDFPS_POINTER_UP:
                     sendUdfpsPointerUp(msg.arg1 /* sensorId */);
                     break;
+                case MSG_POWER_BUTTON_PRESSED:
+                    sendPowerPressed();
+                    break;
                 default:
                     Slog.w(TAG, "Unknown message: " + msg.what);
 
@@ -1325,6 +1339,14 @@
         mAuthenticationCallback.onUdfpsPointerUp(sensorId);
     }
 
+    private void sendPowerPressed() {
+        try {
+            mService.onPowerPressed();
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Error sending power press", e);
+        }
+    }
+
     /**
      * @hide
      */
@@ -1461,6 +1483,9 @@
             case FINGERPRINT_ERROR_BAD_CALIBRATION:
                 return context.getString(
                             com.android.internal.R.string.fingerprint_error_bad_calibration);
+            case BIOMETRIC_ERROR_POWER_PRESSED:
+                return context.getString(
+                    com.android.internal.R.string.fingerprint_error_power_pressed);
             case FINGERPRINT_ERROR_VENDOR: {
                 String[] msgArray = context.getResources().getStringArray(
                         com.android.internal.R.array.fingerprint_error_vendor);
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 0b63446..cc7ed18 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -37,15 +37,18 @@
 interface IFingerprintService {
 
     // Creates a test session with the specified sensorId
+    @EnforcePermission("TEST_BIOMETRIC")
     ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName);
 
     // Requests a proto dump of the specified sensor
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer);
 
     // Retrieve static sensor properties for all fingerprint sensors
     List<FingerprintSensorPropertiesInternal> getSensorPropertiesInternal(String opPackageName);
 
     // Retrieve static sensor properties for the specified sensor
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     FingerprintSensorPropertiesInternal getSensorProperties(int sensorId, String opPackageName);
 
     // Authenticate with a fingerprint. This is protected by USE_FINGERPRINT/USE_BIOMETRIC
@@ -58,6 +61,7 @@
     // Uses the fingerprint hardware to detect for the presence of a finger, without giving details
     // about accept/reject/lockout. A requestId is returned that can be used to cancel this
     // operation.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     long detectFingerprint(IBinder token, int userId, IFingerprintServiceReceiver receiver,
             String opPackageName);
 
@@ -66,38 +70,47 @@
     // called from BiometricService. The additional uid, pid, userId arguments should be determined
     // by BiometricService. To start authentication after the clients are ready, use
     // startPreparedClient().
+    @EnforcePermission("MANAGE_BIOMETRIC")
     void prepareForAuthentication(int sensorId, IBinder token, long operationId, int userId,
             IBiometricSensorReceiver sensorReceiver, String opPackageName, long requestId,
             int cookie, boolean allowBackgroundAuthentication);
 
     // Starts authentication with the previously prepared client.
+    @EnforcePermission("MANAGE_BIOMETRIC")
     void startPreparedClient(int sensorId, int cookie);
 
     // Cancel authentication for the given requestId.
     void cancelAuthentication(IBinder token, String opPackageName, String attributionTag, long requestId);
 
     // Cancel finger detection for the given requestId.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void cancelFingerprintDetect(IBinder token, String opPackageName, long requestId);
 
     // Same as above, except this is protected by the MANAGE_BIOMETRIC signature permission. Takes
     // an additional uid, pid, userid.
+    @EnforcePermission("MANAGE_BIOMETRIC")
     void cancelAuthenticationFromService(int sensorId, IBinder token, String opPackageName, long requestId);
 
     // Start fingerprint enrollment
+    @EnforcePermission("MANAGE_FINGERPRINT")
     long enroll(IBinder token, in byte [] hardwareAuthToken, int userId, IFingerprintServiceReceiver receiver,
             String opPackageName, int enrollReason);
 
     // Cancel enrollment in progress
+    @EnforcePermission("MANAGE_FINGERPRINT")
     void cancelEnrollment(IBinder token, long requestId);
 
     // Any errors resulting from this call will be returned to the listener
+    @EnforcePermission("MANAGE_FINGERPRINT")
     void remove(IBinder token, int fingerId, int userId, IFingerprintServiceReceiver receiver,
             String opPackageName);
 
     // Removes all face enrollments for the specified userId.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void removeAll(IBinder token, int userId, IFingerprintServiceReceiver receiver, String opPackageName);
 
     // Rename the fingerprint specified by fingerId and userId to the given name
+    @EnforcePermission("MANAGE_FINGERPRINT")
     void rename(int fingerId, int userId, String name);
 
     // Get a list of enrolled fingerprints in the given userId.
@@ -107,68 +120,90 @@
     boolean isHardwareDetectedDeprecated(String opPackageName, String attributionTag);
 
     // Determine if the specified HAL is loaded and ready
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     boolean isHardwareDetected(int sensorId, String opPackageName);
 
     // Get a pre-enrollment authentication token
+    @EnforcePermission("MANAGE_FINGERPRINT")
     void generateChallenge(IBinder token, int sensorId, int userId, IFingerprintServiceReceiver receiver, String opPackageName);
 
     // Finish an enrollment sequence and invalidate the authentication token
+    @EnforcePermission("MANAGE_FINGERPRINT")
     void revokeChallenge(IBinder token, int sensorId, int userId, String opPackageName, long challenge);
 
     // Determine if a user has at least one enrolled fingerprint. Meant to support the deprecated FingerprintManager APIs
     boolean hasEnrolledFingerprintsDeprecated(int userId, String opPackageName, String attributionTag);
 
     // Determine if a user has at least one enrolled fingerprint.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     boolean hasEnrolledFingerprints(int sensorId, int userId, String opPackageName);
 
     // Return the LockoutTracker status for the specified user
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     int getLockoutModeForUser(int sensorId, int userId);
 
     // Requests for the specified sensor+userId's authenticatorId to be invalidated
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void invalidateAuthenticatorId(int sensorId, int userId, IInvalidationCallback callback);
 
     // Gets the authenticator ID for fingerprint
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     long getAuthenticatorId(int sensorId, int callingUserId);
 
     // Reset the timeout when user authenticates with strong auth (e.g. PIN, pattern or password)
+    @EnforcePermission("RESET_FINGERPRINT_LOCKOUT")
     void resetLockout(IBinder token, int sensorId, int userId, in byte[] hardwareAuthToken, String opPackageNAame);
 
     // Add a callback which gets notified when the fingerprint lockout period expired.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void addLockoutResetCallback(IBiometricServiceLockoutResetCallback callback, String opPackageName);
 
     // Check if a client request is currently being handled
+    @EnforcePermission("MANAGE_FINGERPRINT")
     boolean isClientActive();
 
     // Add a callback which gets notified when the service starts and stops handling client requests
+    @EnforcePermission("MANAGE_FINGERPRINT")
     void addClientActiveCallback(IFingerprintClientActiveCallback callback);
 
     // Removes a callback set by addClientActiveCallback
+    @EnforcePermission("MANAGE_FINGERPRINT")
     void removeClientActiveCallback(IFingerprintClientActiveCallback callback);
 
     // Registers all HIDL and AIDL sensors. Only HIDL sensor properties need to be provided, because
     // AIDL sensor properties are retrieved directly from the available HALs. If no HIDL HALs exist,
     // hidlSensors must be non-null and empty. See AuthService.java
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void registerAuthenticators(in List<FingerprintSensorPropertiesInternal> hidlSensors);
 
     // Adds a callback which gets called when the service registers all of the fingerprint
     // authenticators. The callback is automatically removed after it's invoked.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void addAuthenticatorsRegisteredCallback(IFingerprintAuthenticatorsRegisteredCallback callback);
 
     // Notifies about a finger touching the sensor area.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void onPointerDown(long requestId, int sensorId, int x, int y, float minor, float major);
 
     // Notifies about a finger leaving the sensor area.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void onPointerUp(long requestId, int sensorId);
 
     // Notifies about the fingerprint UI being ready (e.g. HBM illumination is enabled).
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void onUiReady(long requestId, int sensorId);
 
     // Sets the controller for managing the UDFPS overlay.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void setUdfpsOverlayController(in IUdfpsOverlayController controller);
 
     // Sets the controller for managing the SideFPS overlay.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void setSidefpsController(in ISidefpsController controller);
 
     // Registers BiometricStateListener.
     void registerBiometricStateListener(IBiometricStateListener listener);
+
+    // Sends a power button pressed event to all listeners.
+    oneway void onPowerPressed();
 }
diff --git a/core/java/android/hardware/iris/IIrisService.aidl b/core/java/android/hardware/iris/IIrisService.aidl
index 98057d5..764f4d4 100644
--- a/core/java/android/hardware/iris/IIrisService.aidl
+++ b/core/java/android/hardware/iris/IIrisService.aidl
@@ -26,5 +26,6 @@
     // Registers all HIDL and AIDL sensors. Only HIDL sensor properties need to be provided, because
     // AIDL sensor properties are retrieved directly from the available HALs. If no HIDL HALs exist,
     // hidlSensors must be non-null and empty. See AuthService.java
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void registerAuthenticators(in List<SensorPropertiesInternal> hidlSensors);
 }
diff --git a/core/java/android/hardware/location/ActivityRecognitionHardware.java b/core/java/android/hardware/location/ActivityRecognitionHardware.java
index 8acd1ff..20d6338 100644
--- a/core/java/android/hardware/location/ActivityRecognitionHardware.java
+++ b/core/java/android/hardware/location/ActivityRecognitionHardware.java
@@ -88,34 +88,34 @@
         return nativeIsSupported();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
     @Override
     public String[] getSupportedActivities() {
-        checkPermissions();
         return mSupportedActivities;
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
     @Override
     public boolean isActivitySupported(String activity) {
-        checkPermissions();
         int activityType = getActivityType(activity);
         return activityType != INVALID_ACTIVITY_TYPE;
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
     @Override
     public boolean registerSink(IActivityRecognitionHardwareSink sink) {
-        checkPermissions();
         return mSinks.register(sink);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
     @Override
     public boolean unregisterSink(IActivityRecognitionHardwareSink sink) {
-        checkPermissions();
         return mSinks.unregister(sink);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
     @Override
     public boolean enableActivityEvent(String activity, int eventType, long reportLatencyNs) {
-        checkPermissions();
 
         int activityType = getActivityType(activity);
         if (activityType == INVALID_ACTIVITY_TYPE) {
@@ -130,9 +130,9 @@
         return false;
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
     @Override
     public boolean disableActivityEvent(String activity, int eventType) {
-        checkPermissions();
 
         int activityType = getActivityType(activity);
         if (activityType == INVALID_ACTIVITY_TYPE) {
@@ -147,9 +147,9 @@
         return false;
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
     @Override
     public boolean flush() {
-        checkPermissions();
         int result = nativeFlush();
         return result == NATIVE_SUCCESS_RESULT;
     }
diff --git a/core/java/android/hardware/location/ContextHubClient.java b/core/java/android/hardware/location/ContextHubClient.java
index 54060cc..0848697 100644
--- a/core/java/android/hardware/location/ContextHubClient.java
+++ b/core/java/android/hardware/location/ContextHubClient.java
@@ -31,8 +31,8 @@
 
 /**
  * A class describing a client of the Context Hub Service.
- * <p>
- * Clients can send messages to nanoapps at a Context Hub through this object. The APIs supported
+ *
+ * <p>Clients can send messages to nanoapps at a Context Hub through this object. The APIs supported
  * by this object are thread-safe and can be used without external synchronization.
  *
  * @hide
@@ -75,8 +75,8 @@
     }
 
     /**
-     * Sets the proxy interface of the client at the service. This method should always be called
-     * by the ContextHubManager after the client is registered at the service, and should only be
+     * Sets the proxy interface of the client at the service. This method should always be called by
+     * the ContextHubManager after the client is registered at the service, and should only be
      * called once.
      *
      * @param clientProxy the proxy of the client at the service
@@ -89,7 +89,7 @@
 
         mClientProxy = clientProxy;
         try {
-            mId = Integer.valueOf(mClientProxy.getId());
+            mId = mClientProxy.getId();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -108,16 +108,16 @@
     /**
      * Returns the system-wide unique identifier for this ContextHubClient.
      *
-     * This value can be used as an identifier for the messaging channel between a
-     * ContextHubClient and the Context Hub. This may be used as a routing mechanism
-     * between various ContextHubClient objects within an application.
-     * <p>
-     * The value returned by this method will remain the same if it is associated with
-     * the same client reference at the ContextHubService (for instance, the ID of a
-     * PendingIntent ContextHubClient will remain the same even if the local object
-     * has been regenerated with the equivalent PendingIntent). If the ContextHubClient
-     * is newly generated (e.g. any regeneration of a callback client, or generation
-     * of a non-equal PendingIntent client), the ID will not be the same.
+     * <p>This value can be used as an identifier for the messaging channel between a
+     * ContextHubClient and the Context Hub. This may be used as a routing mechanism between various
+     * ContextHubClient objects within an application.
+     *
+     * <p>The value returned by this method will remain the same if it is associated with the same
+     * client reference at the ContextHubService (for instance, the ID of a PendingIntent
+     * ContextHubClient will remain the same even if the local object has been regenerated with the
+     * equivalent PendingIntent). If the ContextHubClient is newly generated (e.g. any regeneration
+     * of a callback client, or generation of a non-equal PendingIntent client), the ID will not be
+     * the same.
      *
      * @return The ID of this ContextHubClient, in the range [0, 65535].
      */
@@ -132,13 +132,13 @@
     /**
      * Closes the connection for this client and the Context Hub Service.
      *
-     * When this function is invoked, the messaging associated with this client is invalidated.
+     * <p>When this function is invoked, the messaging associated with this client is invalidated.
      * All futures messages targeted for this client are dropped at the service, and the
      * ContextHubClient is unregistered from the service.
-     * <p>
-     * If this object has a PendingIntent, i.e. the object was generated via
-     * {@link ContextHubManager.createClient(PendingIntent, ContextHubInfo, long)}, then the
-     * Intent events corresponding to the PendingIntent will no longer be triggered.
+     *
+     * <p>If this object has a PendingIntent, i.e. the object was generated via {@link
+     * ContextHubManager#createClient(ContextHubInfo, PendingIntent, long)}, then the Intent events
+     * corresponding to the PendingIntent will no longer be triggered.
      */
     public void close() {
         if (!mIsClosed.getAndSet(true)) {
@@ -174,13 +174,10 @@
      *    have sent it a message.
      *
      * @param message the message object to send
-     *
      * @return the result of sending the message defined as in ContextHubTransaction.Result
-     *
      * @throws NullPointerException if NanoAppMessage is null
      * @throws SecurityException if this client doesn't have permissions to send a message to the
-     * nanoapp.
-     *
+     *     nanoapp.
      * @see NanoAppMessage
      * @see ContextHubTransaction.Result
      */
@@ -192,8 +189,13 @@
         int maxPayloadBytes = mAttachedHub.getMaxPacketLengthBytes();
         byte[] payload = message.getMessageBody();
         if (payload != null && payload.length > maxPayloadBytes) {
-            Log.e(TAG, "Message (" + payload.length + " bytes) exceeds max payload length ("
-                    + maxPayloadBytes + " bytes)");
+            Log.e(
+                    TAG,
+                    "Message ("
+                            + payload.length
+                            + " bytes) exceeds max payload length ("
+                            + maxPayloadBytes
+                            + " bytes)");
             return ContextHubTransaction.RESULT_FAILED_BAD_PARAMS;
         }
 
@@ -217,4 +219,13 @@
             super.finalize();
         }
     }
+
+    /** @hide */
+    public void callbackFinished() {
+        try {
+            mClientProxy.callbackFinished();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/android/hardware/location/ContextHubIntentEvent.java b/core/java/android/hardware/location/ContextHubIntentEvent.java
index 3e8f421..06c5334 100644
--- a/core/java/android/hardware/location/ContextHubIntentEvent.java
+++ b/core/java/android/hardware/location/ContextHubIntentEvent.java
@@ -98,7 +98,7 @@
         Objects.requireNonNull(intent, "Intent cannot be null");
 
         hasExtraOrThrow(intent, ContextHubManager.EXTRA_CONTEXT_HUB_INFO);
-        ContextHubInfo info = intent.getParcelableExtra(ContextHubManager.EXTRA_CONTEXT_HUB_INFO);
+        ContextHubInfo info = intent.getParcelableExtra(ContextHubManager.EXTRA_CONTEXT_HUB_INFO, android.hardware.location.ContextHubInfo.class);
         if (info == null) {
             throw new IllegalArgumentException("ContextHubInfo extra was null");
         }
@@ -117,7 +117,7 @@
                 if (eventType == ContextHubManager.EVENT_NANOAPP_MESSAGE) {
                     hasExtraOrThrow(intent, ContextHubManager.EXTRA_MESSAGE);
                     NanoAppMessage message =
-                            intent.getParcelableExtra(ContextHubManager.EXTRA_MESSAGE);
+                            intent.getParcelableExtra(ContextHubManager.EXTRA_MESSAGE, android.hardware.location.NanoAppMessage.class);
                     if (message == null) {
                         throw new IllegalArgumentException("NanoAppMessage extra was null");
                     }
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java
index cec4326..b54da6c 100644
--- a/core/java/android/hardware/location/ContextHubManager.java
+++ b/core/java/android/hardware/location/ContextHubManager.java
@@ -726,45 +726,75 @@
         return new IContextHubClientCallback.Stub() {
             @Override
             public void onMessageFromNanoApp(NanoAppMessage message) {
-                executor.execute(() -> callback.onMessageFromNanoApp(client, message));
+                executor.execute(
+                        () -> {
+                            callback.onMessageFromNanoApp(client, message);
+                            client.callbackFinished();
+                        });
             }
 
             @Override
             public void onHubReset() {
-                executor.execute(() -> callback.onHubReset(client));
+                executor.execute(
+                        () -> {
+                            callback.onHubReset(client);
+                            client.callbackFinished();
+                        });
             }
 
             @Override
             public void onNanoAppAborted(long nanoAppId, int abortCode) {
-                executor.execute(() -> callback.onNanoAppAborted(client, nanoAppId, abortCode));
+                executor.execute(
+                        () -> {
+                            callback.onNanoAppAborted(client, nanoAppId, abortCode);
+                            client.callbackFinished();
+                        });
             }
 
             @Override
             public void onNanoAppLoaded(long nanoAppId) {
-                executor.execute(() -> callback.onNanoAppLoaded(client, nanoAppId));
+                executor.execute(
+                        () -> {
+                            callback.onNanoAppLoaded(client, nanoAppId);
+                            client.callbackFinished();
+                        });
             }
 
             @Override
             public void onNanoAppUnloaded(long nanoAppId) {
-                executor.execute(() -> callback.onNanoAppUnloaded(client, nanoAppId));
+                executor.execute(
+                        () -> {
+                            callback.onNanoAppUnloaded(client, nanoAppId);
+                            client.callbackFinished();
+                        });
             }
 
             @Override
             public void onNanoAppEnabled(long nanoAppId) {
-                executor.execute(() -> callback.onNanoAppEnabled(client, nanoAppId));
+                executor.execute(
+                        () -> {
+                            callback.onNanoAppEnabled(client, nanoAppId);
+                            client.callbackFinished();
+                        });
             }
 
             @Override
             public void onNanoAppDisabled(long nanoAppId) {
-                executor.execute(() -> callback.onNanoAppDisabled(client, nanoAppId));
+                executor.execute(
+                        () -> {
+                            callback.onNanoAppDisabled(client, nanoAppId);
+                            client.callbackFinished();
+                        });
             }
 
             @Override
             public void onClientAuthorizationChanged(
                     long nanoAppId, @ContextHubManager.AuthorizationState int authorization) {
                 executor.execute(
-                        () -> callback.onClientAuthorizationChanged(
-                                client, nanoAppId, authorization));
+                        () -> {
+                            callback.onClientAuthorizationChanged(client, nanoAppId, authorization);
+                            client.callbackFinished();
+                        });
             }
         };
     }
diff --git a/core/java/android/hardware/location/GeofenceHardwareService.java b/core/java/android/hardware/location/GeofenceHardwareService.java
index c0bcb27..106bfd5 100644
--- a/core/java/android/hardware/location/GeofenceHardwareService.java
+++ b/core/java/android/hardware/location/GeofenceHardwareService.java
@@ -75,76 +75,68 @@
             mGeofenceHardwareImpl.setFusedGeofenceHardware(service);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
         @Override
         public int[] getMonitoringTypes() {
-            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
-                    "Location Hardware permission not granted to access hardware geofence");
 
             return mGeofenceHardwareImpl.getMonitoringTypes();
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
         @Override
         public int getStatusOfMonitoringType(int monitoringType) {
-            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
-                    "Location Hardware permission not granted to access hardware geofence");
 
             return mGeofenceHardwareImpl.getStatusOfMonitoringType(monitoringType);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
         @Override
         public boolean addCircularFence(
                 int monitoringType,
                 GeofenceHardwareRequestParcelable request,
                 IGeofenceHardwareCallback callback) {
-            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
-                    "Location Hardware permission not granted to access hardware geofence");
             checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
             return mGeofenceHardwareImpl.addCircularFence(monitoringType, request, callback);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
         @Override
         public boolean removeGeofence(int id, int monitoringType) {
-            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
-                    "Location Hardware permission not granted to access hardware geofence");
 
             checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
             return mGeofenceHardwareImpl.removeGeofence(id, monitoringType);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
         @Override
         public boolean pauseGeofence(int id, int monitoringType) {
-            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
-                    "Location Hardware permission not granted to access hardware geofence");
 
             checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
             return mGeofenceHardwareImpl.pauseGeofence(id, monitoringType);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
         @Override
         public boolean resumeGeofence(int id, int monitoringType, int monitorTransitions) {
-            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
-                    "Location Hardware permission not granted to access hardware geofence");
 
             checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
             return mGeofenceHardwareImpl.resumeGeofence(id, monitoringType, monitorTransitions);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
         @Override
         public boolean registerForMonitorStateChangeCallback(int monitoringType,
                 IGeofenceHardwareMonitorCallback callback) {
-            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
-                    "Location Hardware permission not granted to access hardware geofence");
 
             checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
             return mGeofenceHardwareImpl.registerForMonitorStateChangeCallback(monitoringType,
                     callback);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
         @Override
         public boolean unregisterForMonitorStateChangeCallback(int monitoringType,
                 IGeofenceHardwareMonitorCallback callback) {
-            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
-                    "Location Hardware permission not granted to access hardware geofence");
 
             checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
             return mGeofenceHardwareImpl.unregisterForMonitorStateChangeCallback(monitoringType,
diff --git a/core/java/android/hardware/location/IActivityRecognitionHardware.aidl b/core/java/android/hardware/location/IActivityRecognitionHardware.aidl
index bc6b183..f093cd5 100644
--- a/core/java/android/hardware/location/IActivityRecognitionHardware.aidl
+++ b/core/java/android/hardware/location/IActivityRecognitionHardware.aidl
@@ -28,35 +28,42 @@
     /**
      * Gets an array of supported activities by hardware.
      */
+    @EnforcePermission("LOCATION_HARDWARE")
     String[] getSupportedActivities();
 
     /**
      * Returns true if the given activity is supported, false otherwise.
      */
+    @EnforcePermission("LOCATION_HARDWARE")
     boolean isActivitySupported(in String activityType);
 
     /**
      * Registers a sink with Hardware Activity-Recognition.
      */
+    @EnforcePermission("LOCATION_HARDWARE")
     boolean registerSink(in IActivityRecognitionHardwareSink sink);
 
     /**
      * Unregisters a sink with Hardware Activity-Recognition.
      */
+    @EnforcePermission("LOCATION_HARDWARE")
     boolean unregisterSink(in IActivityRecognitionHardwareSink sink);
 
     /**
      * Enables tracking of a given activity/event type, if the activity is supported.
      */
+    @EnforcePermission("LOCATION_HARDWARE")
     boolean enableActivityEvent(in String activityType, int eventType, long reportLatencyNs);
 
     /**
      * Disables tracking of a given activity/eventy type.
      */
+    @EnforcePermission("LOCATION_HARDWARE")
     boolean disableActivityEvent(in String activityType, int eventType);
 
     /**
      * Requests hardware for all the activity events detected up to the given point in time.
      */
+    @EnforcePermission("LOCATION_HARDWARE")
     boolean flush();
 }
\ No newline at end of file
diff --git a/core/java/android/hardware/location/IContextHubClient.aidl b/core/java/android/hardware/location/IContextHubClient.aidl
index 2423a58..1ee342e9 100644
--- a/core/java/android/hardware/location/IContextHubClient.aidl
+++ b/core/java/android/hardware/location/IContextHubClient.aidl
@@ -32,4 +32,7 @@
 
     // Returns the unique ID for this client.
     int getId();
+
+    // Notify direct-call message callback completed
+    void callbackFinished();
 }
diff --git a/core/java/android/hardware/location/IContextHubService.aidl b/core/java/android/hardware/location/IContextHubService.aidl
index 92882c4..ced75c4 100644
--- a/core/java/android/hardware/location/IContextHubService.aidl
+++ b/core/java/android/hardware/location/IContextHubService.aidl
@@ -35,62 +35,78 @@
 interface IContextHubService {
 
     // Registers a callback to receive messages
+    @EnforcePermission("ACCESS_CONTEXT_HUB")
     int registerCallback(in IContextHubCallback callback);
 
     // Gets a list of available context hub handles
+    @EnforcePermission("ACCESS_CONTEXT_HUB")
     int[] getContextHubHandles();
 
     // Gets the properties of a hub
+    @EnforcePermission("ACCESS_CONTEXT_HUB")
     ContextHubInfo getContextHubInfo(int contextHubHandle);
 
     // Loads a nanoapp at the specified hub (old API)
+    @EnforcePermission("ACCESS_CONTEXT_HUB")
     int loadNanoApp(int contextHubHandle, in NanoApp nanoApp);
 
     // Unloads a nanoapp given its instance ID (old API)
+    @EnforcePermission("ACCESS_CONTEXT_HUB")
     int unloadNanoApp(int nanoAppHandle);
 
     // Gets the NanoAppInstanceInfo of a nanoapp give its instance ID
+    @EnforcePermission("ACCESS_CONTEXT_HUB")
     NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppHandle);
 
     // Finds all nanoApp instances matching some filter
+    @EnforcePermission("ACCESS_CONTEXT_HUB")
     int[] findNanoAppOnHub(int contextHubHandle, in NanoAppFilter filter);
 
     // Sends a message to a nanoApp
+    @EnforcePermission("ACCESS_CONTEXT_HUB")
     int sendMessage(int contextHubHandle, int nanoAppHandle, in ContextHubMessage msg);
 
     // Creates a client to send and receive messages
+    @EnforcePermission("ACCESS_CONTEXT_HUB")
     IContextHubClient createClient(
             int contextHubId, in IContextHubClientCallback client, in String attributionTag,
             in String packageName);
 
     // Creates a PendingIntent-based client to send and receive messages
+    @EnforcePermission("ACCESS_CONTEXT_HUB")
     IContextHubClient createPendingIntentClient(
             int contextHubId, in PendingIntent pendingIntent, long nanoAppId,
             in String attributionTag);
 
     // Returns a list of ContextHub objects of available hubs
+    @EnforcePermission("ACCESS_CONTEXT_HUB")
     List<ContextHubInfo> getContextHubs();
 
     // Loads a nanoapp at the specified hub (new API)
+    @EnforcePermission("ACCESS_CONTEXT_HUB")
     void loadNanoAppOnHub(
             int contextHubId, in IContextHubTransactionCallback transactionCallback,
             in NanoAppBinary nanoAppBinary);
 
     // Unloads a nanoapp on a specified context hub (new API)
+    @EnforcePermission("ACCESS_CONTEXT_HUB")
     void unloadNanoAppFromHub(
             int contextHubId, in IContextHubTransactionCallback transactionCallback,
             long nanoAppId);
 
     // Enables a nanoapp at the specified hub
+    @EnforcePermission("ACCESS_CONTEXT_HUB")
     void enableNanoApp(
             int contextHubId, in IContextHubTransactionCallback transactionCallback,
             long nanoAppId);
 
     // Disables a nanoapp at the specified hub
+    @EnforcePermission("ACCESS_CONTEXT_HUB")
     void disableNanoApp(
             int contextHubId, in IContextHubTransactionCallback transactionCallback,
             long nanoAppId);
 
     // Queries for a list of nanoapps
+    @EnforcePermission("ACCESS_CONTEXT_HUB")
     void queryNanoApps(int contextHubId, in IContextHubTransactionCallback transactionCallback);
 }
diff --git a/core/java/android/hardware/location/IGeofenceHardware.aidl b/core/java/android/hardware/location/IGeofenceHardware.aidl
index 0e840c4..41804ad 100644
--- a/core/java/android/hardware/location/IGeofenceHardware.aidl
+++ b/core/java/android/hardware/location/IGeofenceHardware.aidl
@@ -26,17 +26,25 @@
 interface IGeofenceHardware {
     void setGpsGeofenceHardware(in IGpsGeofenceHardware service);
     void setFusedGeofenceHardware(in IFusedGeofenceHardware service);
+    @EnforcePermission("LOCATION_HARDWARE")
     int[] getMonitoringTypes();
+    @EnforcePermission("LOCATION_HARDWARE")
     int getStatusOfMonitoringType(int monitoringType);
+    @EnforcePermission("LOCATION_HARDWARE")
     boolean addCircularFence(
             int monitoringType,
             in GeofenceHardwareRequestParcelable request,
             in IGeofenceHardwareCallback callback);
+    @EnforcePermission("LOCATION_HARDWARE")
     boolean removeGeofence(int id, int monitoringType);
+    @EnforcePermission("LOCATION_HARDWARE")
     boolean pauseGeofence(int id, int monitoringType);
+    @EnforcePermission("LOCATION_HARDWARE")
     boolean resumeGeofence(int id, int monitoringType, int monitorTransitions);
+    @EnforcePermission("LOCATION_HARDWARE")
     boolean registerForMonitorStateChangeCallback(int monitoringType,
             IGeofenceHardwareMonitorCallback callback);
+    @EnforcePermission("LOCATION_HARDWARE")
     boolean unregisterForMonitorStateChangeCallback(int monitoringType,
             IGeofenceHardwareMonitorCallback callback);
 }
diff --git a/core/java/android/hardware/radio/ProgramList.java b/core/java/android/hardware/radio/ProgramList.java
index e8e4fc9..f2525d1 100644
--- a/core/java/android/hardware/radio/ProgramList.java
+++ b/core/java/android/hardware/radio/ProgramList.java
@@ -22,10 +22,11 @@
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.ArrayMap;
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -41,7 +42,7 @@
 
     private final Object mLock = new Object();
     private final Map<ProgramSelector.Identifier, RadioManager.ProgramInfo> mPrograms =
-            new HashMap<>();
+            new ArrayMap<>();
 
     private final List<ListCallback> mListCallbacks = new ArrayList<>();
     private final List<OnCompleteListener> mOnCompleteListeners = new ArrayList<>();
@@ -184,8 +185,14 @@
             listCallbacksCopied = new ArrayList<>(mListCallbacks);
 
             if (chunk.isPurge()) {
-                for (ProgramSelector.Identifier id : mPrograms.keySet()) {
-                    removeLocked(id, removedList);
+                Iterator<Map.Entry<ProgramSelector.Identifier, RadioManager.ProgramInfo>>
+                        programsIterator = mPrograms.entrySet().iterator();
+                while (programsIterator.hasNext()) {
+                    RadioManager.ProgramInfo removed = programsIterator.next().getValue();
+                    if (removed != null) {
+                        removedList.add(removed.getSelector().getPrimaryId());
+                    }
+                    programsIterator.remove();
                 }
             }
 
diff --git a/core/java/android/hardware/radio/RadioMetadata.java b/core/java/android/hardware/radio/RadioMetadata.java
index a882c2f..b7bf783 100644
--- a/core/java/android/hardware/radio/RadioMetadata.java
+++ b/core/java/android/hardware/radio/RadioMetadata.java
@@ -384,7 +384,7 @@
     public Bitmap getBitmap(String key) {
         Bitmap bmp = null;
         try {
-            bmp = mBundle.getParcelable(key);
+            bmp = mBundle.getParcelable(key, android.graphics.Bitmap.class);
         } catch (Exception e) {
             // ignore, value was not a bitmap
             Log.w(TAG, "Failed to retrieve a key as Bitmap.", e);
@@ -419,7 +419,7 @@
     public Clock getClock(String key) {
         Clock clock = null;
         try {
-            clock = mBundle.getParcelable(key);
+            clock = mBundle.getParcelable(key, android.hardware.radio.RadioMetadata.Clock.class);
         } catch (Exception e) {
             // ignore, value was not a clock.
             Log.w(TAG, "Failed to retrieve a key as Clock.", e);
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index c02f870..c6fc9ec 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -2163,13 +2163,13 @@
             mCandidatesVisibility = vis;
         }
     }
-    
+
     /**
      * Returns the visibility mode (either {@link View#INVISIBLE View.INVISIBLE}
      * or {@link View#GONE View.GONE}) of the candidates view when it is not
      * shown.  The default implementation returns GONE when
      * {@link #isExtractViewShown} returns true,
-     * otherwise VISIBLE.  Be careful if you change this to return GONE in
+     * otherwise INVISIBLE.  Be careful if you change this to return GONE in
      * other situations -- if showing or hiding the candidates view causes
      * your window to resize, this can cause temporary drawing artifacts as
      * the resize takes place.
diff --git a/core/java/android/net/ScoredNetwork.java b/core/java/android/net/ScoredNetwork.java
index a46bdd9a..758367d 100644
--- a/core/java/android/net/ScoredNetwork.java
+++ b/core/java/android/net/ScoredNetwork.java
@@ -299,7 +299,7 @@
     public int calculateBadge(int rssi) {
         if (attributes != null && attributes.containsKey(ATTRIBUTES_KEY_BADGING_CURVE)) {
             RssiCurve badgingCurve =
-                    attributes.getParcelable(ATTRIBUTES_KEY_BADGING_CURVE);
+                    attributes.getParcelable(ATTRIBUTES_KEY_BADGING_CURVE, android.net.RssiCurve.class);
             return badgingCurve.lookupScore(rssi);
         }
 
diff --git a/core/java/android/nfc/tech/Ndef.java b/core/java/android/nfc/tech/Ndef.java
index 2256365..39c355a 100644
--- a/core/java/android/nfc/tech/Ndef.java
+++ b/core/java/android/nfc/tech/Ndef.java
@@ -161,7 +161,7 @@
         if (extras != null) {
             mMaxNdefSize = extras.getInt(EXTRA_NDEF_MAXLENGTH);
             mCardState = extras.getInt(EXTRA_NDEF_CARDSTATE);
-            mNdefMsg = extras.getParcelable(EXTRA_NDEF_MSG);
+            mNdefMsg = extras.getParcelable(EXTRA_NDEF_MSG, android.nfc.NdefMessage.class);
             mNdefType = extras.getInt(EXTRA_NDEF_TYPE);
         } else {
             throw new NullPointerException("NDEF tech extras are null.");
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index b4930fa..399f11b 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -1155,6 +1155,8 @@
      * consequences.
      *
      * To temporarily enable tracing, use {@link #startNativeTracing()}.
+     *
+     * @deprecated Please use other tracing method in this class.
      */
     public static void enableEmulatorTraceOutput() {
         Log.w(TAG, "Unimplemented");
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 1dedc26..aa61558 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -33,6 +33,7 @@
 import android.util.ExceptionUtils;
 import android.util.Log;
 import android.util.MathUtils;
+import android.util.Pair;
 import android.util.Size;
 import android.util.SizeF;
 import android.util.Slog;
@@ -3034,7 +3035,7 @@
         switch (code) {
             case EX_PARCELABLE:
                 if (readInt() > 0) {
-                    return (Exception) readParcelable(Parcelable.class.getClassLoader());
+                    return (Exception) readParcelable(Parcelable.class.getClassLoader(), java.lang.Exception.class);
                 } else {
                     return new RuntimeException(msg + " [missing Parcelable]");
                 }
@@ -4865,28 +4866,36 @@
         if (name == null) {
             return null;
         }
-        Parcelable.Creator<?> creator;
-        HashMap<String, Parcelable.Creator<?>> map;
-        synchronized (mCreators) {
-            map = mCreators.get(loader);
+
+        Pair<Parcelable.Creator<?>, Class<?>> creatorAndParcelableClass;
+        synchronized (sPairedCreators) {
+            HashMap<String, Pair<Parcelable.Creator<?>, Class<?>>> map =
+                    sPairedCreators.get(loader);
             if (map == null) {
-                map = new HashMap<>();
-                mCreators.put(loader, map);
+                sPairedCreators.put(loader, new HashMap<>());
+                mCreators.put(loader, new HashMap<>());
+                creatorAndParcelableClass = null;
+            } else {
+                creatorAndParcelableClass = map.get(name);
             }
-            creator = map.get(name);
         }
-        if (creator != null) {
+
+        if (creatorAndParcelableClass != null) {
+            Parcelable.Creator<?> creator = creatorAndParcelableClass.first;
+            Class<?> parcelableClass = creatorAndParcelableClass.second;
             if (clazz != null) {
-                Class<?> parcelableClass = creator.getClass().getEnclosingClass();
                 if (!clazz.isAssignableFrom(parcelableClass)) {
                     throw new BadTypeParcelableException("Parcelable creator " + name + " is not "
                             + "a subclass of required class " + clazz.getName()
                             + " provided in the parameter");
                 }
             }
+
             return (Parcelable.Creator<T>) creator;
         }
 
+        Parcelable.Creator<?> creator;
+        Class<?> parcelableClass;
         try {
             // If loader == null, explicitly emulate Class.forName(String) "caller
             // classloader" behavior.
@@ -4894,7 +4903,7 @@
                     (loader == null ? getClass().getClassLoader() : loader);
             // Avoid initializing the Parcelable class until we know it implements
             // Parcelable and has the necessary CREATOR field. http://b/1171613.
-            Class<?> parcelableClass = Class.forName(name, false /* initialize */,
+            parcelableClass = Class.forName(name, false /* initialize */,
                     parcelableClassLoader);
             if (!Parcelable.class.isAssignableFrom(parcelableClass)) {
                 throw new BadParcelableException("Parcelable protocol requires subclassing "
@@ -4941,8 +4950,9 @@
                     + "CREATOR on class " + name);
         }
 
-        synchronized (mCreators) {
-            map.put(name, creator);
+        synchronized (sPairedCreators) {
+            sPairedCreators.get(loader).put(name, Pair.create(creator, parcelableClass));
+            mCreators.get(loader).put(name, creator);
         }
 
         return (Parcelable.Creator<T>) creator;
@@ -5093,12 +5103,17 @@
         }
     }
 
-    // Cache of previously looked up CREATOR.createFromParcel() methods for
-    // particular classes.  Keys are the names of the classes, values are
-    // Method objects.
+
+    // Left due to the UnsupportedAppUsage. Do not use anymore - use sPairedCreators instead
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
-    private static final HashMap<ClassLoader,HashMap<String,Parcelable.Creator<?>>>
-        mCreators = new HashMap<>();
+    private static final HashMap<ClassLoader, HashMap<String, Parcelable.Creator<?>>>
+            mCreators = new HashMap<>();
+
+    // Cache of previously looked up CREATOR.createFromParcel() methods for particular classes.
+    // Keys are the names of the classes, values are a pair consisting of a parcelable creator,
+    // and the class of the parcelable type for the object.
+    private static final HashMap<ClassLoader, HashMap<String,
+            Pair<Parcelable.Creator<?>, Class<?>>>> sPairedCreators = new HashMap<>();
 
     /** @hide for internal use only. */
     static protected final Parcel obtain(int obj) {
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 5123a9f..3063d3a 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -571,7 +571,8 @@
             WAKE_REASON_DISPLAY_GROUP_ADDED,
             WAKE_REASON_DISPLAY_GROUP_TURNED_ON,
             WAKE_REASON_UNFOLD_DEVICE,
-            WAKE_REASON_DREAM_FINISHED
+            WAKE_REASON_DREAM_FINISHED,
+            WAKE_REASON_TILT
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface WakeReason{}
@@ -686,6 +687,12 @@
     public static final int WAKE_REASON_DREAM_FINISHED = 13;
 
     /**
+     * Wake up reason code: Waking due to tilt.
+     * @hide
+     */
+    public static final int WAKE_REASON_TILT = 14;
+
+    /**
      * Convert the wake reason to a string for debugging purposes.
      * @hide
      */
@@ -705,6 +712,7 @@
             case WAKE_REASON_DISPLAY_GROUP_TURNED_ON: return "WAKE_REASON_DISPLAY_GROUP_TURNED_ON";
             case WAKE_REASON_UNFOLD_DEVICE: return "WAKE_REASON_UNFOLD_DEVICE";
             case WAKE_REASON_DREAM_FINISHED: return "WAKE_REASON_DREAM_FINISHED";
+            case WAKE_REASON_TILT: return "WAKE_REASON_TILT";
             default: return Integer.toString(wakeReason);
         }
     }
@@ -715,28 +723,28 @@
      * @hide
      */
     public static class WakeData {
-        public WakeData(long wakeTime, @WakeReason int wakeReason, long sleepDuration) {
+        public WakeData(long wakeTime, @WakeReason int wakeReason, long sleepDurationRealtime) {
             this.wakeTime = wakeTime;
             this.wakeReason = wakeReason;
-            this.sleepDuration = sleepDuration;
+            this.sleepDurationRealtime = sleepDurationRealtime;
         }
         public final long wakeTime;
         public final @WakeReason int wakeReason;
-        public final long sleepDuration;
+        public final long sleepDurationRealtime;
 
         @Override
         public boolean equals(@Nullable Object o) {
             if (o instanceof WakeData) {
                 final WakeData other = (WakeData) o;
                 return wakeTime == other.wakeTime && wakeReason == other.wakeReason
-                        && sleepDuration == other.sleepDuration;
+                        && sleepDurationRealtime == other.sleepDurationRealtime;
             }
             return false;
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(wakeTime, wakeReason, sleepDuration);
+            return Objects.hash(wakeTime, wakeReason, sleepDurationRealtime);
         }
     }
 
diff --git a/core/java/android/os/image/DynamicSystemClient.java b/core/java/android/os/image/DynamicSystemClient.java
index 5aa4e27..63259ed 100644
--- a/core/java/android/os/image/DynamicSystemClient.java
+++ b/core/java/android/os/image/DynamicSystemClient.java
@@ -420,7 +420,7 @@
                 Bundle bundle = (Bundle) msg.obj;
                 long progress = bundle.getLong(KEY_INSTALLED_SIZE);
                 ParcelableException t = (ParcelableException) bundle.getSerializable(
-                        KEY_EXCEPTION_DETAIL);
+                        KEY_EXCEPTION_DETAIL, android.os.ParcelableException.class);
 
                 Throwable detail = t == null ? null : t.getCause();
 
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl
index a0f6598..df0bee7 100644
--- a/core/java/android/os/storage/IStorageManager.aidl
+++ b/core/java/android/os/storage/IStorageManager.aidl
@@ -52,6 +52,7 @@
      * Shuts down the StorageManagerService and gracefully unmounts all external media.
      * Invokes call back once the shutdown is complete.
      */
+    @EnforcePermission("SHUTDOWN")
     void shutdown(IStorageShutdownObserver observer) = 19;
     /**
      * Mounts an Opaque Binary Blob (OBB). Only allows the calling process's UID
@@ -100,33 +101,55 @@
      * Kick off an immediate maintenance operation
      * @throws RemoteException
      */
+    @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
     void runMaintenance() = 42;
     DiskInfo[] getDisks() = 44;
     VolumeInfo[] getVolumes(int flags) = 45;
     VolumeRecord[] getVolumeRecords(int flags) = 46;
+    @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
     void mount(in String volId) = 47;
+    @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
     void unmount(in String volId) = 48;
+    @EnforcePermission("MOUNT_FORMAT_FILESYSTEMS")
     void format(in String volId) = 49;
+    @EnforcePermission("MOUNT_FORMAT_FILESYSTEMS")
     void partitionPublic(in String diskId) = 50;
+    @EnforcePermission("MOUNT_FORMAT_FILESYSTEMS")
     void partitionPrivate(in String diskId) = 51;
+    @EnforcePermission("MOUNT_FORMAT_FILESYSTEMS")
     void partitionMixed(in String diskId, int ratio) = 52;
+    @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
     void setVolumeNickname(in String fsUuid, in String nickname) = 53;
+    @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
     void setVolumeUserFlags(in String fsUuid, int flags, int mask) = 54;
+    @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
     void forgetVolume(in String fsUuid) = 55;
+    @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
     void forgetAllVolumes() = 56;
     String getPrimaryStorageUuid() = 57;
+    @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
     void setPrimaryStorageUuid(in String volumeUuid, IPackageMoveObserver callback) = 58;
+    @EnforcePermission("MOUNT_FORMAT_FILESYSTEMS")
     void benchmark(in String volId, IVoldTaskListener listener) = 59;
+    @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
     void setDebugFlags(int flags, int mask) = 60;
+    @EnforcePermission("STORAGE_INTERNAL")
     void createUserKey(int userId, int serialNumber, boolean ephemeral) = 61;
+    @EnforcePermission("STORAGE_INTERNAL")
     void destroyUserKey(int userId) = 62;
     void unlockUserKey(int userId, int serialNumber, in byte[] secret) = 63;
+    @EnforcePermission("STORAGE_INTERNAL")
     void lockUserKey(int userId) = 64;
     boolean isUserKeyUnlocked(int userId) = 65;
+    @EnforcePermission("STORAGE_INTERNAL")
     void prepareUserStorage(in String volumeUuid, int userId, int serialNumber, int flags) = 66;
+    @EnforcePermission("STORAGE_INTERNAL")
     void destroyUserStorage(in String volumeUuid, int userId, int flags) = 67;
+    @EnforcePermission("STORAGE_INTERNAL")
     void addUserKeyAuth(int userId, int serialNumber, in byte[] secret) = 70;
+    @EnforcePermission("STORAGE_INTERNAL")
     void fixateNewestUserKeyAuth(int userId) = 71;
+    @EnforcePermission("MOUNT_FORMAT_FILESYSTEMS")
     void fstrim(int flags, IVoldTaskListener listener) = 72;
     AppFuseMount mountProxyFileDescriptorBridge() = 73;
     ParcelFileDescriptor openProxyFileDescriptor(int mountPointId, int fileId, int mode) = 74;
@@ -139,14 +162,17 @@
     void commitChanges() = 83;
     boolean supportsCheckpoint() = 84;
     void startCheckpoint(int numTries) = 85;
+    @EnforcePermission("MOUNT_FORMAT_FILESYSTEMS")
     boolean needsCheckpoint() = 86;
     void abortChanges(in String message, boolean retry) = 87;
+    @EnforcePermission("STORAGE_INTERNAL")
     void clearUserKeyAuth(int userId, int serialNumber, in byte[] secret) = 88;
     void fixupAppDir(in String path) = 89;
     void disableAppDataIsolation(in String pkgName, int pid, int userId) = 90;
     PendingIntent getManageSpaceActivityIntent(in String packageName, int requestCode) = 91;
     void notifyAppIoBlocked(in String volumeUuid, int uid, int tid, int reason) = 92;
     void notifyAppIoResumed(in String volumeUuid, int uid, int tid, int reason) = 93;
+    @EnforcePermission("WRITE_MEDIA_STORAGE")
     int getExternalStorageMountMode(int uid, in String packageName) = 94;
     boolean isAppIoBlocked(in String volumeUuid, int uid, int tid, int reason) = 95;
     void setCloudMediaProvider(in String authority) = 96;
diff --git a/core/java/android/permission/DEFAULT_PERMISSION_GRANT_POLICY_OWNERS b/core/java/android/permission/DEFAULT_PERMISSION_GRANT_POLICY_OWNERS
index cb521c8..4564c30 100644
--- a/core/java/android/permission/DEFAULT_PERMISSION_GRANT_POLICY_OWNERS
+++ b/core/java/android/permission/DEFAULT_PERMISSION_GRANT_POLICY_OWNERS
@@ -1,8 +1,7 @@
-ewol@google.com
+ashfall@google.com
 hackbod@google.com
 jsharkey@google.com
 narayan@google.com
 patb@google.com
-svetoslavganov@google.com
 yamasani@google.com
 zhanghai@google.com
diff --git a/core/java/android/permission/IPermissionManager.aidl b/core/java/android/permission/IPermissionManager.aidl
index 6a93b35..8534c66 100644
--- a/core/java/android/permission/IPermissionManager.aidl
+++ b/core/java/android/permission/IPermissionManager.aidl
@@ -80,6 +80,7 @@
             long revokeAfterKilledDelay, int importanceToResetTimer,
             int importanceToKeepSessionAlive);
 
+    @EnforcePermission("MANAGE_ONE_TIME_PERMISSION_SESSIONS")
     void stopOneTimePermissionSession(String packageName, int userId);
 
     List<String> getAutoRevokeExemptionRequestedPackages(int userId);
diff --git a/core/java/android/permission/OWNERS b/core/java/android/permission/OWNERS
index 49f4bf7..d34b45b 100644
--- a/core/java/android/permission/OWNERS
+++ b/core/java/android/permission/OWNERS
@@ -2,7 +2,7 @@
 
 evanseverson@google.com
 evanxinchen@google.com
-ewol@google.com
+ashfall@google.com
 guojing@google.com
 jaysullivan@google.com
 kvakil@google.com
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 53b1dab..f6bdc18 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -578,7 +578,7 @@
         if (savedInstanceState != null) {
             // We are restarting from a previous saved state; used that to
             // initialize, instead of starting fresh.
-            ArrayList<Header> headers = savedInstanceState.getParcelableArrayList(HEADERS_TAG);
+            ArrayList<Header> headers = savedInstanceState.getParcelableArrayList(HEADERS_TAG, android.preference.PreferenceActivity.Header.class);
             if (headers != null) {
                 mHeaders.addAll(headers);
                 int curHeader = savedInstanceState.getInt(CUR_HEADER_TAG,
diff --git a/core/java/android/preference/RingtonePreference.java b/core/java/android/preference/RingtonePreference.java
index c6d8c08..e15244a 100644
--- a/core/java/android/preference/RingtonePreference.java
+++ b/core/java/android/preference/RingtonePreference.java
@@ -248,7 +248,7 @@
         if (requestCode == mRequestCode) {
             
             if (data != null) {
-                Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
+                Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI, android.net.Uri.class);
                 
                 if (callChangeListener(uri != null ? uri.toString() : "")) {
                     onSaveRingtone(uri);
diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java
index a5e2f33..931adb5 100644
--- a/core/java/android/print/PrintManager.java
+++ b/core/java/android/print/PrintManager.java
@@ -529,8 +529,8 @@
             Bundle result = mService.print(printJobName, delegate,
                     attributes, mContext.getPackageName(), mAppId, mUserId);
             if (result != null) {
-                PrintJobInfo printJob = result.getParcelable(EXTRA_PRINT_JOB);
-                IntentSender intent = result.getParcelable(EXTRA_PRINT_DIALOG_INTENT);
+                PrintJobInfo printJob = result.getParcelable(EXTRA_PRINT_JOB, android.print.PrintJobInfo.class);
+                IntentSender intent = result.getParcelable(EXTRA_PRINT_DIALOG_INTENT, android.content.IntentSender.class);
                 if (printJob == null || intent == null) {
                     return null;
                 }
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 3c1b4ba..d50ba8d 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -8448,7 +8448,7 @@
             Bundle response = contentResolver.call(ContactsContract.AUTHORITY_URI,
                     ContactsContract.SimContacts.QUERY_SIM_ACCOUNTS_METHOD,
                     null, null);
-            List<SimAccount> result = response.getParcelableArrayList(KEY_SIM_ACCOUNTS);
+            List<SimAccount> result = response.getParcelableArrayList(KEY_SIM_ACCOUNTS, android.provider.ContactsContract.SimAccount.class);
 
             if (result == null) {
                 result = new ArrayList<>();
@@ -8821,7 +8821,7 @@
         public static Account getDefaultAccount(@NonNull ContentResolver resolver) {
             Bundle response = resolver.call(ContactsContract.AUTHORITY_URI,
                     QUERY_DEFAULT_ACCOUNT_METHOD, null, null);
-            return response.getParcelable(KEY_DEFAULT_ACCOUNT);
+            return response.getParcelable(KEY_DEFAULT_ACCOUNT, android.accounts.Account.class);
         }
 
         /**
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 620fa65..1884d56 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -1379,7 +1379,7 @@
 
             final Bundle out = content.call(parentDocumentUri.getAuthority(),
                     METHOD_CREATE_DOCUMENT, null, in);
-            return out.getParcelable(DocumentsContract.EXTRA_URI);
+            return out.getParcelable(DocumentsContract.EXTRA_URI, android.net.Uri.class);
         } catch (Exception e) {
             Log.w(TAG, "Failed to create document", e);
             rethrowIfNecessary(e);
@@ -1445,7 +1445,7 @@
 
             final Bundle out = content.call(documentUri.getAuthority(),
                     METHOD_RENAME_DOCUMENT, null, in);
-            final Uri outUri = out.getParcelable(DocumentsContract.EXTRA_URI);
+            final Uri outUri = out.getParcelable(DocumentsContract.EXTRA_URI, android.net.Uri.class);
             return (outUri != null) ? outUri : documentUri;
         } catch (Exception e) {
             Log.w(TAG, "Failed to rename document", e);
@@ -1494,7 +1494,7 @@
 
             final Bundle out = content.call(sourceDocumentUri.getAuthority(),
                     METHOD_COPY_DOCUMENT, null, in);
-            return out.getParcelable(DocumentsContract.EXTRA_URI);
+            return out.getParcelable(DocumentsContract.EXTRA_URI, android.net.Uri.class);
         } catch (Exception e) {
             Log.w(TAG, "Failed to copy document", e);
             rethrowIfNecessary(e);
@@ -1522,7 +1522,7 @@
 
             final Bundle out = content.call(sourceDocumentUri.getAuthority(),
                     METHOD_MOVE_DOCUMENT, null, in);
-            return out.getParcelable(DocumentsContract.EXTRA_URI);
+            return out.getParcelable(DocumentsContract.EXTRA_URI, android.net.Uri.class);
         } catch (Exception e) {
             Log.w(TAG, "Failed to move document", e);
             rethrowIfNecessary(e);
@@ -1642,7 +1642,7 @@
 
             final Bundle out = content.call(treeUri.getAuthority(),
                     METHOD_FIND_DOCUMENT_PATH, null, in);
-            return out.getParcelable(DocumentsContract.EXTRA_RESULT);
+            return out.getParcelable(DocumentsContract.EXTRA_RESULT, android.provider.DocumentsContract.Path.class);
         } catch (Exception e) {
             Log.w(TAG, "Failed to find path", e);
             rethrowIfNecessary(e);
@@ -1715,7 +1715,7 @@
 
             final Bundle out = content.call(uri.getAuthority(),
                     METHOD_CREATE_WEB_LINK_INTENT, null, in);
-            return out.getParcelable(DocumentsContract.EXTRA_RESULT);
+            return out.getParcelable(DocumentsContract.EXTRA_RESULT, android.content.IntentSender.class);
         } catch (Exception e) {
             Log.w(TAG, "Failed to create a web link intent", e);
             rethrowIfNecessary(e);
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index a5a24c0..07d5001 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -219,9 +219,9 @@
 
     /** {@hide} */
     private void enforceTreeForExtraUris(Bundle extras) {
-        enforceTree(extras.getParcelable(DocumentsContract.EXTRA_URI));
-        enforceTree(extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI));
-        enforceTree(extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI));
+        enforceTree(extras.getParcelable(DocumentsContract.EXTRA_URI, android.net.Uri.class));
+        enforceTree(extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI, android.net.Uri.class));
+        enforceTree(extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI, android.net.Uri.class));
     }
 
     /** {@hide} */
@@ -1091,11 +1091,11 @@
         enforceTreeForExtraUris(extras);
 
         final Uri extraUri = validateIncomingNullableUri(
-                extras.getParcelable(DocumentsContract.EXTRA_URI));
+                extras.getParcelable(DocumentsContract.EXTRA_URI, android.net.Uri.class));
         final Uri extraTargetUri = validateIncomingNullableUri(
-                extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI));
+                extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI, android.net.Uri.class));
         final Uri extraParentUri = validateIncomingNullableUri(
-                extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI));
+                extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI, android.net.Uri.class));
 
         if (METHOD_EJECT_ROOT.equals(method)) {
             // Given that certain system apps can hold MOUNT_UNMOUNT permission, but only apps
@@ -1436,7 +1436,7 @@
         enforceTree(uri);
         final String documentId = getDocumentId(uri);
         if (opts != null && opts.containsKey(ContentResolver.EXTRA_SIZE)) {
-            final Point sizeHint = opts.getParcelable(ContentResolver.EXTRA_SIZE);
+            final Point sizeHint = opts.getParcelable(ContentResolver.EXTRA_SIZE, android.graphics.Point.class);
             return openDocumentThumbnail(documentId, sizeHint, signal);
         }
         if ("*/*".equals(mimeTypeFilter)) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 8745f7a..73bbc40 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3168,7 +3168,7 @@
                             synchronized (NameValueCache.this) {
                                 if (needsGenerationTracker) {
                                     MemoryIntArray array = b.getParcelable(
-                                            CALL_METHOD_TRACK_GENERATION_KEY);
+                                            CALL_METHOD_TRACK_GENERATION_KEY, android.util.MemoryIntArray.class);
                                     final int index = b.getInt(
                                             CALL_METHOD_GENERATION_INDEX_KEY, -1);
                                     if (array != null && index >= 0) {
@@ -3354,7 +3354,7 @@
 
                 // All flags for the namespace
                 Map<String, String> flagsToValues =
-                        (HashMap) b.getSerializable(Settings.NameValueTable.VALUE);
+                        (HashMap) b.getSerializable(Settings.NameValueTable.VALUE, java.util.HashMap.class);
                 // Only the flags requested by the caller
                 if (!names.isEmpty()) {
                     for (Map.Entry<String, String> flag : flagsToValues.entrySet()) {
@@ -3369,7 +3369,7 @@
                 synchronized (NameValueCache.this) {
                     if (needsGenerationTracker) {
                         MemoryIntArray array = b.getParcelable(
-                                CALL_METHOD_TRACK_GENERATION_KEY);
+                                CALL_METHOD_TRACK_GENERATION_KEY, android.util.MemoryIntArray.class);
                         final int index = b.getInt(
                                 CALL_METHOD_GENERATION_INDEX_KEY, -1);
                         if (array != null && index >= 0) {
@@ -9739,6 +9739,43 @@
         public static final String FACE_UNLOCK_RE_ENROLL = "face_unlock_re_enroll";
 
         /**
+         * The time (in millis) to wait for a power button before sending a
+         * successful auth in to keyguard(for side fingerprint)
+         * @hide
+         */
+        @Readable
+        public static final String FINGERPRINT_SIDE_FPS_KG_POWER_WINDOW =
+                "fingerprint_side_fps_kg_power_window";
+
+        /**
+         * The time (in millis) to wait for a power button before sending
+         * a successful auth in biometric prompt(for side fingerprint)
+         * @hide
+         */
+        @Readable
+        public static final String FINGERPRINT_SIDE_FPS_BP_POWER_WINDOW =
+                "fingerprint_side_fps_bp_power_window";
+
+        /**
+         * The time (in millis) that a finger tap will wait for a power button
+         * before dismissing the power dialog during enrollment(for side
+         * fingerprint)
+         * @hide
+         */
+        @Readable
+        public static final String FINGERPRINT_SIDE_FPS_ENROLL_TAP_WINDOW =
+                "fingerprint_side_fps_enroll_tap_window";
+
+        /**
+         * The time (in millis) that a power event will ignore future authentications
+         * (for side fingerprint)
+         * @hide
+         */
+        @Readable
+        public static final String FINGERPRINT_SIDE_FPS_AUTH_DOWNTIME =
+                "fingerprint_side_fps_auth_downtime";
+
+        /**
          * Whether or not debugging is enabled.
          * @hide
          */
@@ -11371,6 +11408,7 @@
          * <li>{@link BatteryManager#BATTERY_PLUGGED_AC} to stay on for AC charger</li>
          * <li>{@link BatteryManager#BATTERY_PLUGGED_USB} to stay on for USB charger</li>
          * <li>{@link BatteryManager#BATTERY_PLUGGED_WIRELESS} to stay on for wireless charger</li>
+         * <li>{@link BatteryManager#BATTERY_PLUGGED_DOCK} to stay on for dock charger</li>
          * </ul>
          * These values can be OR-ed together.
          */
@@ -17462,7 +17500,8 @@
              * Whether touch and hold to edit WF is enabled
              * @hide
              */
-            public static final String TOUCH_AND_HOLD_WATCH_FACE = "touch_and_hold_watchface";
+            public static final String GESTURE_TOUCH_AND_HOLD_WATCH_FACE_ENABLED =
+                    "gesture_touch_and_hold_watchface_enabled";
 
             /**
              * Whether bedtime mode is enabled.
diff --git a/core/java/android/service/autofill/FillRequest.java b/core/java/android/service/autofill/FillRequest.java
index 327cda3..b4010a4 100644
--- a/core/java/android/service/autofill/FillRequest.java
+++ b/core/java/android/service/autofill/FillRequest.java
@@ -453,7 +453,7 @@
         byte flg = in.readByte();
         int id = in.readInt();
         List<FillContext> fillContexts = new ArrayList<>();
-        in.readParcelableList(fillContexts, FillContext.class.getClassLoader());
+        in.readParcelableList(fillContexts, FillContext.class.getClassLoader(), android.service.autofill.FillContext.class);
         Bundle clientState = (flg & 0x4) == 0 ? null : in.readBundle();
         int flags = in.readInt();
         InlineSuggestionsRequest inlineSuggestionsRequest = (flg & 0x10) == 0 ? null : (InlineSuggestionsRequest) in.readTypedObject(InlineSuggestionsRequest.CREATOR);
diff --git a/core/java/android/service/contentsuggestions/ContentSuggestionsService.java b/core/java/android/service/contentsuggestions/ContentSuggestionsService.java
index 50efbac..0b4739e 100644
--- a/core/java/android/service/contentsuggestions/ContentSuggestionsService.java
+++ b/core/java/android/service/contentsuggestions/ContentSuggestionsService.java
@@ -72,7 +72,7 @@
             Bitmap wrappedBuffer = null;
             if (imageContextRequestExtras.containsKey(ContentSuggestionsManager.EXTRA_BITMAP)) {
                 wrappedBuffer = imageContextRequestExtras.getParcelable(
-                        ContentSuggestionsManager.EXTRA_BITMAP);
+                        ContentSuggestionsManager.EXTRA_BITMAP, android.graphics.Bitmap.class);
             } else {
                 if (contextImage != null) {
                     ColorSpace colorSpace = null;
diff --git a/core/java/android/service/controls/templates/ThumbnailTemplate.java b/core/java/android/service/controls/templates/ThumbnailTemplate.java
index a7c481e..e058b76 100644
--- a/core/java/android/service/controls/templates/ThumbnailTemplate.java
+++ b/core/java/android/service/controls/templates/ThumbnailTemplate.java
@@ -65,7 +65,7 @@
     ThumbnailTemplate(Bundle b) {
         super(b);
         mActive = b.getBoolean(KEY_ACTIVE);
-        mThumbnail = b.getParcelable(KEY_ICON);
+        mThumbnail = b.getParcelable(KEY_ICON, android.graphics.drawable.Icon.class);
         mContentDescription = b.getCharSequence(KEY_CONTENT_DESCRIPTION, "");
     }
 
diff --git a/core/java/android/service/controls/templates/ToggleRangeTemplate.java b/core/java/android/service/controls/templates/ToggleRangeTemplate.java
index cd6a2fc..4ad42a3 100644
--- a/core/java/android/service/controls/templates/ToggleRangeTemplate.java
+++ b/core/java/android/service/controls/templates/ToggleRangeTemplate.java
@@ -43,7 +43,7 @@
      */
     ToggleRangeTemplate(@NonNull Bundle b) {
         super(b);
-        mControlButton = b.getParcelable(KEY_BUTTON);
+        mControlButton = b.getParcelable(KEY_BUTTON, android.service.controls.templates.ControlButton.class);
         mRangeTemplate = new RangeTemplate(b.getBundle(KEY_RANGE));
     }
 
diff --git a/core/java/android/service/controls/templates/ToggleTemplate.java b/core/java/android/service/controls/templates/ToggleTemplate.java
index e4aa6b0..687e750 100644
--- a/core/java/android/service/controls/templates/ToggleTemplate.java
+++ b/core/java/android/service/controls/templates/ToggleTemplate.java
@@ -53,7 +53,7 @@
      */
     ToggleTemplate(Bundle b) {
         super(b);
-        mButton = b.getParcelable(KEY_BUTTON);
+        mButton = b.getParcelable(KEY_BUTTON, android.service.controls.templates.ControlButton.class);
     }
 
     public boolean isChecked() {
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 2d461c6..b0c5d83 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -993,7 +993,7 @@
         if (!mWindowless) {
             mOverlayConnection.bind(
                     /* context= */ this,
-                    intent.getParcelableExtra(EXTRA_DREAM_OVERLAY_COMPONENT),
+                    intent.getParcelableExtra(EXTRA_DREAM_OVERLAY_COMPONENT, android.content.ComponentName.class),
                     new ComponentName(this, getClass()));
         }
 
diff --git a/core/java/android/service/games/GameSessionTrampolineActivity.java b/core/java/android/service/games/GameSessionTrampolineActivity.java
index b237918..93f19d5 100644
--- a/core/java/android/service/games/GameSessionTrampolineActivity.java
+++ b/core/java/android/service/games/GameSessionTrampolineActivity.java
@@ -94,7 +94,7 @@
 
         try {
             startActivityAsCaller(
-                    getIntent().getParcelableExtra(INTENT_KEY),
+                    getIntent().getParcelableExtra(INTENT_KEY, android.content.Intent.class),
                     getIntent().getBundleExtra(OPTIONS_KEY),
                     false,
                     getUserId(),
@@ -102,7 +102,7 @@
         } catch (Exception e) {
             Slog.w(TAG, "Unable to launch activity from game session");
             AndroidFuture<GameSessionActivityResult> future = getIntent().getParcelableExtra(
-                    FUTURE_KEY);
+                    FUTURE_KEY, com.android.internal.infra.AndroidFuture.class);
             future.completeExceptionally(e);
             finish();
             overridePendingTransition(0, 0);
@@ -123,7 +123,7 @@
         }
 
         AndroidFuture<GameSessionActivityResult> future = getIntent().getParcelableExtra(
-                FUTURE_KEY);
+                FUTURE_KEY, com.android.internal.infra.AndroidFuture.class);
         future.complete(new GameSessionActivityResult(resultCode, data));
         finish();
         overridePendingTransition(0, 0);
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 65f0824..02176b0 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -1379,7 +1379,7 @@
     private void maybePopulatePeople(Notification notification) {
         if (getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.P) {
             ArrayList<Person> people = notification.extras.getParcelableArrayList(
-                    Notification.EXTRA_PEOPLE_LIST);
+                    Notification.EXTRA_PEOPLE_LIST, android.app.Person.class);
             if (people != null && people.isEmpty()) {
                 int size = people.size();
                 String[] peopleArray = new String[size];
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 66188cd..e2c84dc 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -500,7 +500,7 @@
                         template.hashCode());
             }
             ArrayList<Person> people = getNotification().extras.getParcelableArrayList(
-                    Notification.EXTRA_PEOPLE_LIST);
+                    Notification.EXTRA_PEOPLE_LIST, android.app.Person.class);
             if (people != null && !people.isEmpty()) {
                 logMaker.addTaggedData(MetricsEvent.FIELD_NOTIFICATION_PEOPLE, people.size());
             }
diff --git a/core/java/android/service/restrictions/RestrictionsReceiver.java b/core/java/android/service/restrictions/RestrictionsReceiver.java
index e8d481a..badd0c2 100644
--- a/core/java/android/service/restrictions/RestrictionsReceiver.java
+++ b/core/java/android/service/restrictions/RestrictionsReceiver.java
@@ -77,7 +77,7 @@
             String requestType = intent.getStringExtra(RestrictionsManager.EXTRA_REQUEST_TYPE);
             String requestId = intent.getStringExtra(RestrictionsManager.EXTRA_REQUEST_ID);
             PersistableBundle request = (PersistableBundle)
-                    intent.getParcelableExtra(RestrictionsManager.EXTRA_REQUEST_BUNDLE);
+                    intent.getParcelableExtra(RestrictionsManager.EXTRA_REQUEST_BUNDLE, android.os.PersistableBundle.class);
             onRequestPermission(context, packageName, requestType, requestId, request);
         }
     }
diff --git a/core/java/android/service/trust/TrustAgentService.java b/core/java/android/service/trust/TrustAgentService.java
index 559313a..ad4f9f7 100644
--- a/core/java/android/service/trust/TrustAgentService.java
+++ b/core/java/android/service/trust/TrustAgentService.java
@@ -257,7 +257,7 @@
                     Bundle data = msg.getData();
                     byte[] token = data.getByteArray(EXTRA_TOKEN);
                     long handle = data.getLong(EXTRA_TOKEN_HANDLE);
-                    UserHandle user = (UserHandle) data.getParcelable(EXTRA_USER_HANDLE);
+                    UserHandle user = (UserHandle) data.getParcelable(EXTRA_USER_HANDLE, android.os.UserHandle.class);
                     onEscrowTokenAdded(token, handle, user);
                     break;
                 }
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index 7d17093..42500b4 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -1547,7 +1547,7 @@
                     list = Collections.emptyList();
                 } else {
                     final ParceledListSlice<DirectAction> pls = result.getParcelable(
-                            DirectAction.KEY_ACTIONS_LIST);
+                            DirectAction.KEY_ACTIONS_LIST, android.content.pm.ParceledListSlice.class);
                     if (pls != null) {
                         final List<DirectAction> receivedList = pls.getList();
                         list = (receivedList != null) ? receivedList : Collections.emptyList();
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 1df7dbc..46ca8f7 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -22,7 +22,6 @@
 import static android.graphics.Matrix.MSCALE_Y;
 import static android.graphics.Matrix.MSKEW_X;
 import static android.graphics.Matrix.MSKEW_Y;
-import static android.view.SurfaceControl.METADATA_WINDOW_TYPE;
 import static android.view.View.SYSTEM_UI_FLAG_VISIBLE;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 
@@ -1168,12 +1167,14 @@
                             mBbqSurfaceControl = new SurfaceControl.Builder()
                                     .setName("Wallpaper BBQ wrapper")
                                     .setHidden(false)
-                                    // TODO(b/192291754)
-                                    .setMetadata(METADATA_WINDOW_TYPE, TYPE_WALLPAPER)
                                     .setBLASTLayer()
                                     .setParent(mSurfaceControl)
                                     .setCallsite("Wallpaper#relayout")
                                     .build();
+                            SurfaceControl.Transaction transaction =
+                                    new SurfaceControl.Transaction();
+                            transaction.setDefaultFrameRateCompatibility(mBbqSurfaceControl,
+                                Surface.FRAME_RATE_COMPATIBILITY_MIN).apply();
                         }
                         // Propagate transform hint from WM, so we can use the right hint for the
                         // first frame.
diff --git a/core/java/android/speech/AlternativeSpans.java b/core/java/android/speech/AlternativeSpans.java
index 0de8c3e..2277e55 100644
--- a/core/java/android/speech/AlternativeSpans.java
+++ b/core/java/android/speech/AlternativeSpans.java
@@ -140,7 +140,7 @@
         // static FieldType unparcelFieldName(Parcel in) { ... }
 
         List<AlternativeSpan> spans = new ArrayList<>();
-        in.readParcelableList(spans, AlternativeSpan.class.getClassLoader());
+        in.readParcelableList(spans, AlternativeSpan.class.getClassLoader(), android.speech.AlternativeSpan.class);
 
         this.mSpans = spans;
         com.android.internal.util.AnnotationValidations.validate(
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index 26c8314..a00d8cf 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -742,7 +742,7 @@
 
             AudioAttributes audioAttributes =
                     (AudioAttributes) paramsBundle.getParcelable(
-                            Engine.KEY_PARAM_AUDIO_ATTRIBUTES);
+                            Engine.KEY_PARAM_AUDIO_ATTRIBUTES, android.media.AudioAttributes.class);
             if (audioAttributes == null) {
                 int streamType = paramsBundle.getInt(
                         Engine.KEY_PARAM_STREAM, Engine.DEFAULT_STREAM);
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index e39231c..7394c22 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -408,14 +408,14 @@
                     final boolean sameDirection = (mDir == Layout.DIR_RIGHT_TO_LEFT) == runIsRtl;
 
                     if (targetIsInThisSegment && sameDirection) {
-                        return h + measureRun(segStart, offset, j, runIsRtl, fmi);
+                        return h + measureRun(segStart, offset, j, runIsRtl, fmi, null, 0);
                     }
 
-                    final float segmentWidth = measureRun(segStart, j, j, runIsRtl, fmi);
+                    final float segmentWidth = measureRun(segStart, j, j, runIsRtl, fmi, null, 0);
                     h += sameDirection ? segmentWidth : -segmentWidth;
 
                     if (targetIsInThisSegment) {
-                        return h + measureRun(segStart, offset, j, runIsRtl, null);
+                        return h + measureRun(segStart, offset, j, runIsRtl, null, null, 0);
                     }
 
                     if (j != runLimit) {  // charAt(j) == TAB_CHAR
@@ -437,6 +437,116 @@
     }
 
     /**
+     * Return the signed horizontal bounds of the characters in the line.
+     *
+     * The length of the returned array equals to 2 * mLen. The left bound of the i th character
+     * is stored at index 2 * i. And the right bound of the i th character is stored at index
+     * (2 * i + 1).
+     *
+     * Check the following examples. LX(e.g. L0, L1, ...) denotes a character which has LTR BiDi
+     * property. On the other hand, RX(e.g. R0, R1, ...) denotes a character which has RTL BiDi
+     * property. Assuming all character has 1em width.
+     *
+     * Example 1: All LTR chars within LTR context
+     *   Input Text (logical)  :   L0 L1 L2 L3
+     *   Input Text (visual)   :   L0 L1 L2 L3
+     *   Output :  [0em, 1em, 1em, 2em, 2em, 3em, 3em, 4em]
+     *
+     * Example 2: All RTL chars within RTL context.
+     *   Input Text (logical)  :   R0 R1 R2 R3
+     *   Input Text (visual)   :   R3 R2 R1 R0
+     *   Output :  [-1em, 0em, -2em, -1em, -3em, -2em, -4em, -3em]
+
+     *
+     * Example 3: BiDi chars within LTR context.
+     *   Input Text (logical)  :   L0 L1 R2 R3 L4 L5
+     *   Input Text (visual)   :   L0 L1 R3 R2 L4 L5
+     *   Output :  [0em, 1em, 1em, 2em, 3em, 4em, 2em, 3em, 4em, 5em, 5em, 6em]
+
+     *
+     * Example 4: BiDi chars within RTL context.
+     *   Input Text (logical)  :   L0 L1 R2 R3 L4 L5
+     *   Input Text (visual)   :   L4 L5 R3 R2 L0 L1
+     *   Output :  [-2em, -1em, -1em, 0em, -3em, -2em, -4em, -3em, -6em, -5em, -5em, -4em]
+     *
+     * @param bounds the array to receive the character bounds data. Its length should be at least
+     *               2 times of the line length.
+     * @param advances the array to receive the character advance data, nullable. If provided, its
+     *                 length should be equal or larger than the line length.
+     *
+     * @throws IllegalArgumentException if the given {@code bounds} is null.
+     * @throws IndexOutOfBoundsException if the given {@code bounds} or {@code advances} doesn't
+     * have enough space to hold the result.
+     */
+    public void measureAllBounds(@NonNull float[] bounds, @Nullable float[] advances) {
+        if (bounds == null) {
+            throw new IllegalArgumentException("bounds can't be null");
+        }
+        if (bounds.length < 2 * mLen) {
+            throw new IndexOutOfBoundsException("bounds doesn't have enough space to receive the "
+                    + "result, needed: " + (2 * mLen) + " had: " + bounds.length);
+        }
+        if (advances == null) {
+            advances = new float[mLen];
+        }
+        if (advances.length < mLen) {
+            throw new IndexOutOfBoundsException("advance doesn't have enough space to receive the "
+                    + "result, needed: " + mLen + " had: " + advances.length);
+        }
+        float h = 0;
+        for (int runIndex = 0; runIndex < mDirections.getRunCount(); runIndex++) {
+            final int runStart = mDirections.getRunStart(runIndex);
+            if (runStart > mLen) break;
+            final int runLimit = Math.min(runStart + mDirections.getRunLength(runIndex), mLen);
+            final boolean runIsRtl = mDirections.isRunRtl(runIndex);
+
+            int segStart = runStart;
+            for (int j = mHasTabs ? runStart : runLimit; j <= runLimit; j++) {
+                if (j == runLimit || charAt(j) == TAB_CHAR) {
+                    final boolean sameDirection = (mDir == Layout.DIR_RIGHT_TO_LEFT) == runIsRtl;
+
+                    final float segmentWidth =
+                            measureRun(segStart, j, j, runIsRtl, null, advances, segStart);
+
+                    final float oldh = h;
+                    h += sameDirection ? segmentWidth : -segmentWidth;
+                    float currh = sameDirection ? oldh : h;
+                    for (int offset = segStart; offset < j && offset < mLen; ++offset) {
+                        if (runIsRtl) {
+                            bounds[2 * offset + 1] = currh;
+                            currh -= advances[offset];
+                            bounds[2 * offset] = currh;
+                        } else {
+                            bounds[2 * offset] = currh;
+                            currh += advances[offset];
+                            bounds[2 * offset + 1] = currh;
+                        }
+                    }
+
+                    if (j != runLimit) {  // charAt(j) == TAB_CHAR
+                        final float leftX;
+                        final float rightX;
+                        if (runIsRtl) {
+                            rightX = h;
+                            h = mDir * nextTab(h * mDir);
+                            leftX = h;
+                        } else {
+                            leftX = h;
+                            h = mDir * nextTab(h * mDir);
+                            rightX = h;
+                        }
+                        bounds[2 * j] = leftX;
+                        bounds[2 * j + 1] = rightX;
+                        advances[j] = rightX - leftX;
+                    }
+
+                    segStart = j + 1;
+                }
+            }
+        }
+    }
+
+    /**
      * @see #measure(int, boolean, FontMetricsInt)
      * @return The measure results for all possible offsets
      */
@@ -464,15 +574,15 @@
                 if (j == runLimit || charAt(j) == TAB_CHAR) {
                     final  float oldh = h;
                     final boolean advance = (mDir == Layout.DIR_RIGHT_TO_LEFT) == runIsRtl;
-                    final float w = measureRun(segStart, j, j, runIsRtl, fmi);
+                    final float w = measureRun(segStart, j, j, runIsRtl, fmi, null, 0);
                     h += advance ? w : -w;
 
                     final float baseh = advance ? oldh : h;
                     FontMetricsInt crtfmi = advance ? fmi : null;
                     for (int offset = segStart; offset <= j && offset <= mLen; ++offset) {
                         if (target[offset] >= segStart && target[offset] < j) {
-                            measurement[offset] =
-                                    baseh + measureRun(segStart, offset, j, runIsRtl, crtfmi);
+                            measurement[offset] = baseh
+                                    + measureRun(segStart, offset, j, runIsRtl, crtfmi, null, 0);
                         }
                     }
 
@@ -518,14 +628,14 @@
             boolean needWidth) {
 
         if ((mDir == Layout.DIR_LEFT_TO_RIGHT) == runIsRtl) {
-            float w = -measureRun(start, limit, limit, runIsRtl, null);
+            float w = -measureRun(start, limit, limit, runIsRtl, null, null, 0);
             handleRun(start, limit, limit, runIsRtl, c, null, x + w, top,
-                    y, bottom, null, false);
+                    y, bottom, null, false, null, 0);
             return w;
         }
 
         return handleRun(start, limit, limit, runIsRtl, c, null, x, top,
-                y, bottom, null, needWidth);
+                y, bottom, null, needWidth, null, 0);
     }
 
     /**
@@ -538,12 +648,15 @@
      * @param runIsRtl true if the run is right-to-left
      * @param fmi receives metrics information about the requested
      * run, can be null.
+     * @param advances receives the advance information about the requested run, can be null.
+     * @param advancesIndex the start index to fill in the advance information.
      * @return the signed width from the start of the run to the leading edge
      * of the character at offset, based on the run (not paragraph) direction
      */
     private float measureRun(int start, int offset, int limit, boolean runIsRtl,
-            FontMetricsInt fmi) {
-        return handleRun(start, offset, limit, runIsRtl, null, null, 0, 0, 0, 0, fmi, true);
+            @Nullable FontMetricsInt fmi, @Nullable float[] advances, int advancesIndex) {
+        return handleRun(start, offset, limit, runIsRtl, null, null, 0, 0, 0, 0, fmi, true,
+                advances, advancesIndex);
     }
 
     /**
@@ -562,13 +675,14 @@
             int limit, boolean runIsRtl, float x, boolean needWidth) {
 
         if ((mDir == Layout.DIR_LEFT_TO_RIGHT) == runIsRtl) {
-            float w = -measureRun(start, limit, limit, runIsRtl, null);
-            handleRun(start, limit, limit, runIsRtl, null, consumer, x + w, 0, 0, 0, null, false);
+            float w = -measureRun(start, limit, limit, runIsRtl, null, null, 0);
+            handleRun(start, limit, limit, runIsRtl, null, consumer, x + w, 0, 0, 0, null,
+                    false, null, 0);
             return w;
         }
 
         return handleRun(start, limit, limit, runIsRtl, null, consumer, x, 0, 0, 0, null,
-                needWidth);
+                needWidth, null, 0);
     }
 
 
@@ -908,14 +1022,16 @@
     }
 
     private float getRunAdvance(TextPaint wp, int start, int end, int contextStart, int contextEnd,
-            boolean runIsRtl, int offset) {
+            boolean runIsRtl, int offset, @Nullable float[] advances, int advancesIndex) {
         if (mCharsValid) {
-            return wp.getRunAdvance(mChars, start, end, contextStart, contextEnd, runIsRtl, offset);
+            return wp.getRunCharacterAdvance(mChars, start, end, contextStart, contextEnd,
+                    runIsRtl, offset, advances, advancesIndex);
         } else {
             final int delta = mStart;
-            if (mComputed == null) {
-                return wp.getRunAdvance(mText, delta + start, delta + end,
-                        delta + contextStart, delta + contextEnd, runIsRtl, delta + offset);
+            if (mComputed == null || advances != null) {
+                return wp.getRunCharacterAdvance(mText, delta + start, delta + end,
+                        delta + contextStart, delta + contextEnd, runIsRtl,
+                        delta + offset, advances, advancesIndex);
             } else {
                 return mComputed.getWidth(start + delta, end + delta);
             }
@@ -940,6 +1056,8 @@
      * @param needWidth true if the width of the run is needed
      * @param offset the offset for the purpose of measuring
      * @param decorations the list of locations and paremeters for drawing decorations
+     * @param advances receives the advance information about the requested run, can be null.
+     * @param advancesIndex the start index to fill in the advance information.
      * @return the signed width of the run based on the run direction; only
      * valid if needWidth is true
      */
@@ -947,7 +1065,8 @@
             int contextStart, int contextEnd, boolean runIsRtl,
             Canvas c, TextShaper.GlyphsConsumer consumer, float x, int top, int y, int bottom,
             FontMetricsInt fmi, boolean needWidth, int offset,
-            @Nullable ArrayList<DecorationInfo> decorations) {
+            @Nullable ArrayList<DecorationInfo> decorations,
+            @Nullable float[] advances, int advancesIndex) {
 
         if (mIsJustifying) {
             wp.setWordSpacing(mAddedWidthForJustify);
@@ -967,7 +1086,8 @@
         final int numDecorations = decorations == null ? 0 : decorations.size();
         if (needWidth || ((c != null || consumer != null) && (wp.bgColor != 0
                 || numDecorations != 0 || runIsRtl))) {
-            totalWidth = getRunAdvance(wp, start, end, contextStart, contextEnd, runIsRtl, offset);
+            totalWidth = getRunAdvance(wp, start, end, contextStart, contextEnd, runIsRtl, offset,
+                    advances, advancesIndex);
         }
 
         final float leftX, rightX;
@@ -1009,10 +1129,10 @@
 
                     final int decorationStart = Math.max(info.start, start);
                     final int decorationEnd = Math.min(info.end, offset);
-                    float decorationStartAdvance = getRunAdvance(
-                            wp, start, end, contextStart, contextEnd, runIsRtl, decorationStart);
-                    float decorationEndAdvance = getRunAdvance(
-                            wp, start, end, contextStart, contextEnd, runIsRtl, decorationEnd);
+                    float decorationStartAdvance = getRunAdvance(wp, start, end, contextStart,
+                            contextEnd, runIsRtl, decorationStart, null, 0);
+                    float decorationEndAdvance = getRunAdvance(wp, start, end, contextStart,
+                            contextEnd, runIsRtl, decorationEnd, null, 0);
                     final float decorationXLeft, decorationXRight;
                     if (runIsRtl) {
                         decorationXLeft = rightX - decorationEndAdvance;
@@ -1179,19 +1299,27 @@
      * @param bottom the bottom of the line
      * @param fmi receives metrics information, can be null
      * @param needWidth true if the width is required
+     * @param advances receives the advance information about the requested run, can be null.
+     * @param advancesIndex the start index to fill in the advance information.
      * @return the signed width of the run based on the run direction; only
      * valid if needWidth is true
      */
     private float handleRun(int start, int measureLimit,
             int limit, boolean runIsRtl, Canvas c,
             TextShaper.GlyphsConsumer consumer, float x, int top, int y,
-            int bottom, FontMetricsInt fmi, boolean needWidth) {
+            int bottom, FontMetricsInt fmi, boolean needWidth,
+            @Nullable float[] advances, int advancesIndex) {
 
         if (measureLimit < start || measureLimit > limit) {
             throw new IndexOutOfBoundsException("measureLimit (" + measureLimit + ") is out of "
                     + "start (" + start + ") and limit (" + limit + ") bounds");
         }
 
+        if (advances != null && advances.length - advancesIndex < measureLimit - start) {
+            throw new IndexOutOfBoundsException("advances doesn't have enough space to receive the "
+                    + "result");
+        }
+
         // Case of an empty line, make sure we update fmi according to mPaint
         if (start == measureLimit) {
             final TextPaint wp = mWorkPaint;
@@ -1218,7 +1346,7 @@
             wp.setStartHyphenEdit(adjustStartHyphenEdit(start, wp.getStartHyphenEdit()));
             wp.setEndHyphenEdit(adjustEndHyphenEdit(limit, wp.getEndHyphenEdit()));
             return handleText(wp, start, limit, start, limit, runIsRtl, c, consumer, x, top,
-                    y, bottom, fmi, needWidth, measureLimit, null);
+                    y, bottom, fmi, needWidth, measureLimit, null, advances, advancesIndex);
         }
 
         // Shaping needs to take into account context up to metric boundaries,
@@ -1257,8 +1385,16 @@
             }
 
             if (replacement != null) {
-                x += handleReplacement(replacement, wp, i, mlimit, runIsRtl, c, x, top, y,
-                        bottom, fmi, needWidth || mlimit < measureLimit);
+                final float width = handleReplacement(replacement, wp, i, mlimit, runIsRtl, c,
+                        x, top, y, bottom, fmi, needWidth || mlimit < measureLimit);
+                x += width;
+                if (advances != null) {
+                    // For replacement, the entire width is assigned to the first character.
+                    advances[advancesIndex + i - start] = runIsRtl ? -width : width;
+                    for (int j = i + 1; j < mlimit; ++j) {
+                        advances[advancesIndex + j - start] = 0.0f;
+                    }
+                }
                 continue;
             }
 
@@ -1300,7 +1436,8 @@
                             adjustEndHyphenEdit(activeEnd, mPaint.getEndHyphenEdit()));
                     x += handleText(activePaint, activeStart, activeEnd, i, inext, runIsRtl, c,
                             consumer, x, top, y, bottom, fmi, needWidth || activeEnd < measureLimit,
-                            Math.min(activeEnd, mlimit), mDecorations);
+                            Math.min(activeEnd, mlimit), mDecorations,
+                            advances, advancesIndex + activeStart - start);
 
                     activeStart = j;
                     activePaint.set(wp);
@@ -1327,7 +1464,8 @@
                     adjustEndHyphenEdit(activeEnd, mPaint.getEndHyphenEdit()));
             x += handleText(activePaint, activeStart, activeEnd, i, inext, runIsRtl, c, consumer, x,
                     top, y, bottom, fmi, needWidth || activeEnd < measureLimit,
-                    Math.min(activeEnd, mlimit), mDecorations);
+                    Math.min(activeEnd, mlimit), mDecorations,
+                    advances, advancesIndex + activeStart - start);
         }
 
         return x - originalX;
diff --git a/core/java/android/util/CharsetUtils.java b/core/java/android/util/CharsetUtils.java
index fa14667..3b08c3b 100644
--- a/core/java/android/util/CharsetUtils.java
+++ b/core/java/android/util/CharsetUtils.java
@@ -26,6 +26,12 @@
  * <p>
  * These methods purposefully accept only non-movable byte array addresses to
  * avoid extra JNI overhead.
+ * <p>
+ * Callers are cautioned that there is a long-standing ART bug that emits
+ * non-standard 4-byte sequences, as described by {@code kUtfUse4ByteSequence}
+ * in {@code art/runtime/jni/jni_internal.cc}. If precise modified UTF-8
+ * encoding is required, use {@link com.android.internal.util.ModifiedUtf8}
+ * instead.
  *
  * @hide
  */
@@ -33,6 +39,12 @@
     /**
      * Attempt to encode the given string as modified UTF-8 into the destination
      * byte array without making any new allocations.
+     * <p>
+     * Callers are cautioned that there is a long-standing ART bug that emits
+     * non-standard 4-byte sequences, as described by
+     * {@code kUtfUse4ByteSequence} in {@code art/runtime/jni/jni_internal.cc}.
+     * If precise modified UTF-8 encoding is required, use
+     * {@link com.android.internal.util.ModifiedUtf8} instead.
      *
      * @param src string value to be encoded
      * @param dest destination byte array to encode into
@@ -50,6 +62,12 @@
     /**
      * Attempt to encode the given string as modified UTF-8 into the destination
      * byte array without making any new allocations.
+     * <p>
+     * Callers are cautioned that there is a long-standing ART bug that emits
+     * non-standard 4-byte sequences, as described by
+     * {@code kUtfUse4ByteSequence} in {@code art/runtime/jni/jni_internal.cc}.
+     * If precise modified UTF-8 encoding is required, use
+     * {@link com.android.internal.util.ModifiedUtf8} instead.
      *
      * @param src string value to be encoded
      * @param srcLen exact length of string to be encoded
@@ -66,6 +84,12 @@
 
     /**
      * Attempt to decode a modified UTF-8 string from the source byte array.
+     * <p>
+     * Callers are cautioned that there is a long-standing ART bug that emits
+     * non-standard 4-byte sequences, as described by
+     * {@code kUtfUse4ByteSequence} in {@code art/runtime/jni/jni_internal.cc}.
+     * If precise modified UTF-8 encoding is required, use
+     * {@link com.android.internal.util.ModifiedUtf8} instead.
      *
      * @param src source byte array to decode from
      * @param srcOff offset into source where decoding should begin
diff --git a/core/java/android/util/TEST_MAPPING b/core/java/android/util/TEST_MAPPING
new file mode 100644
index 0000000..0ae1c15
--- /dev/null
+++ b/core/java/android/util/TEST_MAPPING
@@ -0,0 +1,28 @@
+{
+  "presubmit": [
+    {
+      "name": "FrameworksCoreTests",
+      "options": [
+        {
+          "include-filter": "android.util.CharsetUtilsTest"
+        },
+        {
+          "include-filter": "com.android.internal.util.FastDataTest"
+        }
+      ],
+      "file_patterns": ["CharsetUtils|FastData"]
+    },
+    {
+      "name": "FrameworksCoreTests",
+      "options": [
+        {
+          "include-filter": "android.util.XmlTest"
+        },
+        {
+          "include-filter": "android.util.BinaryXmlTest"
+        }
+      ],
+      "file_patterns": ["Xml"]
+    }
+  ]
+}
diff --git a/core/java/android/view/IDisplayWindowInsetsController.aidl b/core/java/android/view/IDisplayWindowInsetsController.aidl
index f4a0dfa..1940042 100644
--- a/core/java/android/view/IDisplayWindowInsetsController.aidl
+++ b/core/java/android/view/IDisplayWindowInsetsController.aidl
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import android.content.ComponentName;
 import android.view.InsetsSourceControl;
 import android.view.InsetsState;
 import android.view.InsetsVisibilities;
@@ -30,10 +31,11 @@
     /**
      * Called when top focused window changes to determine whether or not to take over insets
      * control. Won't be called if config_remoteInsetsControllerControlsSystemBars is false.
-     * @param packageName: Passes the top package name
+     * @param component: Passes the top application component in the focused window.
      * @param requestedVisibilities The insets visibilities requested by the focussed window.
      */
-    void topFocusedWindowChanged(String packageName, in InsetsVisibilities insetsVisibilities);
+    void topFocusedWindowChanged(in ComponentName component,
+            in InsetsVisibilities insetsVisibilities);
 
     /**
      * @see IWindow#insetsChanged
diff --git a/core/java/android/view/IRecentsAnimationController.aidl b/core/java/android/view/IRecentsAnimationController.aidl
index 61f524f..c4d3070 100644
--- a/core/java/android/view/IRecentsAnimationController.aidl
+++ b/core/java/android/view/IRecentsAnimationController.aidl
@@ -80,11 +80,6 @@
     void setAnimationTargetsBehindSystemBars(boolean behindSystemBars);
 
     /**
-     * Hides the current input method if one is showing.
-     */
-    void hideCurrentInputMethod();
-
-    /**
      * Clean up the screenshot of previous task which was created during recents animation that
      * was cancelled by a stack order change.
      *
diff --git a/core/java/android/view/InsetsFrameProvider.java b/core/java/android/view/InsetsFrameProvider.java
index 9e66f54..eb8687c 100644
--- a/core/java/android/view/InsetsFrameProvider.java
+++ b/core/java/android/view/InsetsFrameProvider.java
@@ -16,10 +16,14 @@
 
 package android.view;
 
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
+
 import android.graphics.Insets;
+import android.graphics.Rect;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.util.Arrays;
 import java.util.Objects;
 
 /**
@@ -52,7 +56,9 @@
     public static final int SOURCE_FRAME = 2;
 
     private static final int HAS_INSETS_SIZE = 1;
-    private static final int HAS_IME_INSETS_SIZE = 2;
+    private static final int HAS_INSETS_SIZE_OVERRIDE = 2;
+
+    private static Rect sTmpRect = new Rect();
 
     /**
      * The type of insets to provide.
@@ -77,29 +83,25 @@
     public Insets insetsSize = null;
 
     /**
-     * The provided frame based on the source frame. The result will be used as the insets
-     * size to IME window. Only one side should be set.
+     * If null, the size set in insetsSize will be applied to all window types. If it contains
+     * element of some types, the insets reported to the window with that types will be overridden.
      */
-    public Insets imeInsetsSize = null;
+    public InsetsSizeOverride[] insetsSizeOverrides = null;
 
     public InsetsFrameProvider(int type) {
         this(type, SOURCE_FRAME, null, null);
     }
 
     public InsetsFrameProvider(int type, Insets insetsSize) {
-        this(type, SOURCE_FRAME, insetsSize, insetsSize);
-    }
-
-    public InsetsFrameProvider(int type, Insets insetsSize, Insets imeInsetsSize) {
-        this(type, SOURCE_FRAME, insetsSize, imeInsetsSize);
+        this(type, SOURCE_FRAME, insetsSize, null);
     }
 
     public InsetsFrameProvider(int type, int source, Insets insetsSize,
-            Insets imeInsetsSize) {
+            InsetsSizeOverride[] insetsSizeOverride) {
         this.type = type;
         this.source = source;
         this.insetsSize = insetsSize;
-        this.imeInsetsSize = imeInsetsSize;
+        this.insetsSizeOverrides = insetsSizeOverride;
     }
 
     @Override
@@ -127,8 +129,8 @@
         if (insetsSize != null) {
             sb.append(", insetsSize=").append(insetsSize);
         }
-        if (imeInsetsSize != null) {
-            sb.append(", imeInsetsSize=").append(imeInsetsSize);
+        if (insetsSizeOverrides != null) {
+            sb.append(", insetsSizeOverrides=").append(Arrays.toString(insetsSizeOverrides));
         }
         sb.append("}");
         return sb.toString();
@@ -141,8 +143,8 @@
         if ((insetsSizeModified & HAS_INSETS_SIZE) != 0) {
             insetsSize = Insets.CREATOR.createFromParcel(in);
         }
-        if ((insetsSizeModified & HAS_IME_INSETS_SIZE) != 0) {
-            imeInsetsSize = Insets.CREATOR.createFromParcel(in);
+        if ((insetsSizeModified & HAS_INSETS_SIZE_OVERRIDE) != 0) {
+            insetsSizeOverrides = in.createTypedArray(InsetsSizeOverride.CREATOR);
         }
     }
 
@@ -152,8 +154,8 @@
         if (insetsSize != null) {
             insetsSizeModified |= HAS_INSETS_SIZE;
         }
-        if (imeInsetsSize != null) {
-            insetsSizeModified |= HAS_IME_INSETS_SIZE;
+        if (insetsSizeOverrides != null) {
+            insetsSizeModified |= HAS_INSETS_SIZE_OVERRIDE;
         }
         out.writeInt(insetsSizeModified);
         out.writeInt(type);
@@ -161,8 +163,8 @@
         if (insetsSize != null) {
             insetsSize.writeToParcel(out, flags);
         }
-        if (imeInsetsSize != null) {
-            imeInsetsSize.writeToParcel(out, flags);
+        if (insetsSizeOverrides != null) {
+            out.writeTypedArray(insetsSizeOverrides, flags);
         }
     }
 
@@ -177,16 +179,12 @@
         InsetsFrameProvider other = (InsetsFrameProvider) o;
         return type == other.type && source == other.source
                 && Objects.equals(insetsSize, other.insetsSize)
-                && Objects.equals(imeInsetsSize, other.imeInsetsSize);
+                && Arrays.equals(insetsSizeOverrides, other.insetsSizeOverrides);
     }
 
     @Override
     public int hashCode() {
-        int result = type;
-        result = 31 * result + source;
-        result = 31 * result + (insetsSize != null ? insetsSize.hashCode() : 0);
-        result = 31 * result + (imeInsetsSize != null ? imeInsetsSize.hashCode() : 0);
-        return result;
+        return Objects.hash(type, source, insetsSize, Arrays.hashCode(insetsSizeOverrides));
     }
 
     public static final @android.annotation.NonNull Parcelable.Creator<InsetsFrameProvider>
@@ -201,5 +199,96 @@
                     return new InsetsFrameProvider[size];
                 }
             };
+
+    public static void calculateInsetsFrame(Rect displayFrame, Rect containerBounds,
+            Rect displayCutoutSafe, Rect inOutFrame, int source, Insets insetsSize,
+            @WindowManager.LayoutParams.PrivateFlags int privateFlags) {
+        boolean extendByCutout = false;
+        if (source == InsetsFrameProvider.SOURCE_DISPLAY) {
+            inOutFrame.set(displayFrame);
+        } else if (source == InsetsFrameProvider.SOURCE_CONTAINER_BOUNDS) {
+            inOutFrame.set(containerBounds);
+        } else {
+            extendByCutout = (privateFlags & PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT) != 0;
+        }
+        if (insetsSize == null) {
+            return;
+        }
+        // Only one side of the provider shall be applied. Check in the order of left - top -
+        // right - bottom, only the first non-zero value will be applied.
+        if (insetsSize.left != 0) {
+            inOutFrame.right = inOutFrame.left + insetsSize.left;
+        } else if (insetsSize.top != 0) {
+            inOutFrame.bottom = inOutFrame.top + insetsSize.top;
+        } else if (insetsSize.right != 0) {
+            inOutFrame.left = inOutFrame.right - insetsSize.right;
+        } else if (insetsSize.bottom != 0) {
+            inOutFrame.top = inOutFrame.bottom - insetsSize.bottom;
+        } else {
+            inOutFrame.setEmpty();
+        }
+
+        if (extendByCutout) {
+            WindowLayout.extendFrameByCutout(displayCutoutSafe, displayFrame, inOutFrame, sTmpRect);
+        }
+    }
+
+    /**
+     * Class to describe the insets size to be provided to window with specific window type. If not
+     * used, same insets size will be sent as instructed in the insetsSize and source.
+     */
+    public static class InsetsSizeOverride implements Parcelable {
+        public final int windowType;
+        public Insets insetsSize;
+
+        protected InsetsSizeOverride(Parcel in) {
+            windowType = in.readInt();
+            insetsSize = in.readParcelable(null, android.graphics.Insets.class);
+        }
+
+        public InsetsSizeOverride(int type, Insets size) {
+            windowType = type;
+            insetsSize = size;
+        }
+
+        public static final Creator<InsetsSizeOverride> CREATOR =
+                new Creator<InsetsSizeOverride>() {
+            @Override
+            public InsetsSizeOverride createFromParcel(Parcel in) {
+                return new InsetsSizeOverride(in);
+            }
+
+            @Override
+            public InsetsSizeOverride[] newArray(int size) {
+                return new InsetsSizeOverride[size];
+            }
+        };
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            out.writeInt(windowType);
+            out.writeParcelable(insetsSize, flags);
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder(32);
+            sb.append("TypedInsetsSize: {");
+            sb.append("windowType=").append(windowType);
+            sb.append(", insetsSize=").append(insetsSize);
+            sb.append("}");
+            return sb.toString();
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(windowType, insetsSize);
+        }
+    }
 }
 
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index 11e02e0..6a0ec33 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -909,6 +909,11 @@
             if (source == null && otherSource == null) {
                 continue;
             }
+            if (excludeInvisibleImeFrames && i == ITYPE_IME
+                    && ((source == null && !otherSource.isVisible())
+                            || (otherSource == null && !source.isVisible()))) {
+                continue;
+            }
             if (source == null || otherSource == null) {
                 return false;
             }
diff --git a/core/java/android/view/RemoteAccessibilityController.java b/core/java/android/view/RemoteAccessibilityController.java
index 28b567d..b0911d7 100644
--- a/core/java/android/view/RemoteAccessibilityController.java
+++ b/core/java/android/view/RemoteAccessibilityController.java
@@ -24,6 +24,8 @@
 import android.util.Log;
 import android.view.accessibility.IAccessibilityEmbeddedConnection;
 
+import java.lang.ref.WeakReference;
+
 class RemoteAccessibilityController {
     private static final String TAG = "RemoteAccessibilityController";
     private int mHostId;
@@ -80,12 +82,17 @@
     /**
      * Wrapper of accessibility embedded connection for embedded view hierarchy.
      */
-    private final class RemoteAccessibilityEmbeddedConnection implements IBinder.DeathRecipient {
+    private static final class RemoteAccessibilityEmbeddedConnection
+            implements IBinder.DeathRecipient {
+        private final WeakReference<RemoteAccessibilityController> mController;
         private final IAccessibilityEmbeddedConnection mConnection;
         private final IBinder mLeashToken;
 
-        RemoteAccessibilityEmbeddedConnection(IAccessibilityEmbeddedConnection connection,
+        RemoteAccessibilityEmbeddedConnection(
+                RemoteAccessibilityController controller,
+                IAccessibilityEmbeddedConnection connection,
                 IBinder leashToken) {
+            mController = new WeakReference<>(controller);
             mConnection = connection;
             mLeashToken = leashToken;
         }
@@ -109,9 +116,13 @@
         @Override
         public void binderDied() {
             unlinkToDeath();
-            runOnUiThread(() -> {
-                if (mConnectionWrapper == this) {
-                    mConnectionWrapper = null;
+            RemoteAccessibilityController controller = mController.get();
+            if (controller == null) {
+                return;
+            }
+            controller.runOnUiThread(() -> {
+                if (controller.mConnectionWrapper == this) {
+                    controller.mConnectionWrapper = null;
                 }
             });
         }
@@ -128,7 +139,7 @@
             }
             if (connection != null && leashToken != null) {
                 mConnectionWrapper =
-                    new RemoteAccessibilityEmbeddedConnection(connection, leashToken);
+                    new RemoteAccessibilityEmbeddedConnection(this, connection, leashToken);
                 mConnectionWrapper.linkToDeath();
             }
         } catch (RemoteException e) {
diff --git a/core/java/android/view/ScrollCaptureConnection.java b/core/java/android/view/ScrollCaptureConnection.java
index d70de74..c50f70a 100644
--- a/core/java/android/view/ScrollCaptureConnection.java
+++ b/core/java/android/view/ScrollCaptureConnection.java
@@ -214,7 +214,7 @@
 
     @BinderThread
     @Override
-    public void close() {
+    public synchronized void close() {
         Trace.instantForTrack(TRACE_TAG_GRAPHICS, TRACE_TRACK, "close");
         if (mActive) {
             Log.w(TAG, "close(): capture session still active! Ending now.");
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 691452f..6b21bed 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -228,6 +228,19 @@
      */
     public static final int FRAME_RATE_COMPATIBILITY_EXACT = 100;
 
+    // From window.h. Keep these in sync.
+    /**
+     * This surface is ignored while choosing the refresh rate.
+     * @hide
+     */
+    public static final int FRAME_RATE_COMPATIBILITY_NO_VOTE = 101;
+
+    // From window.h. Keep these in sync.
+    /**
+     * This surface will vote for the minimum refresh rate.
+     * @hide
+     */
+    public static final int FRAME_RATE_COMPATIBILITY_MIN = 102;
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index ff1817a..07a04a8 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -249,6 +249,8 @@
 
     private static native void nativeSetFrameRate(long transactionObj, long nativeObject,
             float frameRate, int compatibility, int changeFrameRateStrategy);
+    private static native void nativeSetDefaultFrameRateCompatibility(long transactionObj,
+            long nativeObject, int compatibility);
     private static native long nativeGetHandle(long nativeObject);
 
     private static native void nativeSetFixedTransformHint(long transactionObj, long nativeObject,
@@ -3614,6 +3616,25 @@
         }
 
         /**
+         * Sets the default frame rate compatibility for the surface {@link SurfaceControl}
+         *
+         * @param sc The SurfaceControl to specify the frame rate of.
+         * @param compatibility The frame rate compatibility of this surface. The compatibility
+         *               value may influence the system's choice of display frame rate.
+         *
+         * @return This transaction object.
+         *
+         * @hide
+         */
+        @NonNull
+        public Transaction setDefaultFrameRateCompatibility(@NonNull SurfaceControl sc,
+                @Surface.FrameRateCompatibility int compatibility) {
+            checkPreconditions(sc);
+            nativeSetDefaultFrameRateCompatibility(mNativeObject, sc.mNativeObject, compatibility);
+            return this;
+        }
+
+        /**
          * Sets focus on the window identified by the input {@code token} if the window is focusable
          * otherwise the request is dropped.
          *
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 785735c..c97eb73 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -25,11 +25,11 @@
 import android.graphics.FrameInfo;
 import android.graphics.HardwareRenderer;
 import android.graphics.Picture;
-import android.graphics.Point;
 import android.graphics.RecordingCanvas;
 import android.graphics.Rect;
 import android.graphics.RenderNode;
 import android.os.Trace;
+import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.Surface.OutOfResourcesException;
 import android.view.View.AttachInfo;
@@ -596,11 +596,18 @@
      */
     void setLightCenter(AttachInfo attachInfo) {
         // Adjust light position for window offsets.
-        final Point displaySize = attachInfo.mPoint;
-        attachInfo.mDisplay.getRealSize(displaySize);
-        final float lightX = displaySize.x / 2f - attachInfo.mWindowLeft;
+        DisplayMetrics displayMetrics = new DisplayMetrics();
+        attachInfo.mDisplay.getRealMetrics(displayMetrics);
+        final float lightX = displayMetrics.widthPixels / 2f - attachInfo.mWindowLeft;
         final float lightY = mLightY - attachInfo.mWindowTop;
-        setLightSourceGeometry(lightX, lightY, mLightZ, mLightRadius);
+        // To prevent shadow distortion on larger screens, scale the z position of the light source
+        // relative to the smallest screen dimension.
+        final float zRatio = Math.min(displayMetrics.widthPixels, displayMetrics.heightPixels)
+                / (450f * displayMetrics.density);
+        final float zWeightedAdjustment = (zRatio + 2) / 3f;
+        final float lightZ = mLightZ * zWeightedAdjustment;
+
+        setLightSourceGeometry(lightX, lightY, lightZ, mLightRadius);
     }
 
     /**
@@ -849,12 +856,18 @@
         public void setLightCenter(final Display display,
                 final int windowLeft, final int windowTop) {
             // Adjust light position for window offsets.
-            final Point displaySize = new Point();
-            display.getRealSize(displaySize);
-            final float lightX = displaySize.x / 2f - windowLeft;
+            DisplayMetrics displayMetrics = new DisplayMetrics();
+            display.getRealMetrics(displayMetrics);
+            final float lightX = displayMetrics.widthPixels / 2f - windowLeft;
             final float lightY = mLightY - windowTop;
+            // To prevent shadow distortion on larger screens, scale the z position of the light
+            // source relative to the smallest screen dimension.
+            final float zRatio = Math.min(displayMetrics.widthPixels, displayMetrics.heightPixels)
+                    / (450f * displayMetrics.density);
+            final float zWeightedAdjustment = (zRatio + 2) / 3f;
+            final float lightZ = mLightZ * zWeightedAdjustment;
 
-            setLightSourceGeometry(lightX, lightY, mLightZ, mLightRadius);
+            setLightSourceGeometry(lightX, lightY, lightZ, mLightRadius);
         }
 
         public RenderNode getRootNode() {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 5457821..4893777 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -310,7 +310,7 @@
  *     </tr>
  *
  *     <tr>
- *         <td rowspan="4">Event processing</td>
+ *         <td rowspan="6">Event processing</td>
  *         <td><code>{@link #onKeyDown(int, KeyEvent)}</code></td>
  *         <td>Called when a new hardware key event occurs.
  *         </td>
@@ -330,6 +330,16 @@
  *         <td>Called when a touch screen motion event occurs.
  *         </td>
  *     </tr>
+ *     <tr>
+ *         <td><code>{@link #onGenericMotionEvent(MotionEvent)}</code></td>
+ *         <td>Called when a generic motion event occurs.
+ *         </td>
+ *     </tr>
+ *     <tr>
+ *         <td><code>{@link #onHoverEvent(MotionEvent)}</code></td>
+ *         <td>Called when a hover motion event occurs.
+ *         </td>
+ *     </tr>
  *
  *     <tr>
  *         <td rowspan="2">Focus</td>
@@ -13313,6 +13323,10 @@
 
     /**
      * Set if view is a heading for a section of content for accessibility purposes.
+     * <p>
+     * Users of some accessibility services can choose to navigate between headings
+     * instead of between paragraphs, words, etc. Apps that provide headings on
+     * sections of text can help the text navigation experience.
      *
      * @param isHeading {@code true} if the view is a heading, {@code false} otherwise.
      *
@@ -15077,6 +15091,8 @@
      *
      * @param event The motion event to be dispatched.
      * @return True if the event was handled by the view, false otherwise.
+     *
+     * @see #onTouchEvent(MotionEvent)
      */
     public boolean dispatchTouchEvent(MotionEvent event) {
         // If the event should be handled by accessibility focus first.
@@ -15171,6 +15187,8 @@
      *
      * @param event The motion event to be dispatched.
      * @return True if the event was handled by the view, false otherwise.
+     *
+     * @see #onTrackballEvent(MotionEvent)
      */
     public boolean dispatchTrackballEvent(MotionEvent event) {
         if (mInputEventConsistencyVerifier != null) {
@@ -15205,11 +15223,14 @@
      * Generic motion events with source class {@link InputDevice#SOURCE_CLASS_POINTER}
      * are delivered to the view under the pointer.  All other generic motion events are
      * delivered to the focused view.  Hover events are handled specially and are delivered
-     * to {@link #onHoverEvent(MotionEvent)}.
+     * to {@link #onHoverEvent(MotionEvent)} first.
      * </p>
      *
      * @param event The motion event to be dispatched.
      * @return True if the event was handled by the view, false otherwise.
+     *
+     * @see #onHoverEvent(MotionEvent)
+     * @see #onGenericMotionEvent(MotionEvent)
      */
     public boolean dispatchGenericMotionEvent(MotionEvent event) {
         if (mInputEventConsistencyVerifier != null) {
@@ -16040,13 +16061,15 @@
     }
 
     /**
-     * Implement this method to handle trackball motion events.  The
-     * <em>relative</em> movement of the trackball since the last event
+     * Implement this method to handle trackball motion events.
+     * <p>
+     * The <em>relative</em> movement of the trackball since the last event
      * can be retrieve with {@link MotionEvent#getX MotionEvent.getX()} and
      * {@link MotionEvent#getY MotionEvent.getY()}.  These are normalized so
      * that a movement of 1 corresponds to the user pressing one DPAD key (so
      * they will often be fractional values, representing the more fine-grained
      * movement information available from a trackball).
+     * </p>
      *
      * @param event The motion event.
      * @return True if the event was handled, false otherwise.
@@ -16058,9 +16081,10 @@
     /**
      * Implement this method to handle generic motion events.
      * <p>
-     * Generic motion events describe joystick movements, mouse hovers, track pad
-     * touches, scroll wheel movements and other input events.  The
-     * {@link MotionEvent#getSource() source} of the motion event specifies
+     * Generic motion events describe joystick movements, hover events from mouse or stylus
+     * devices, trackpad touches, scroll wheel movements and other motion events not handled
+     * by {@link #onTouchEvent(MotionEvent)} or {@link #onTrackballEvent(MotionEvent)}.
+     * The {@link MotionEvent#getSource() source} of the motion event specifies
      * the class of input that was received.  Implementations of this method
      * must examine the bits in the source before processing the event.
      * The following code example shows how this is done.
@@ -16079,7 +16103,7 @@
      *     if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
      *         switch (event.getAction()) {
      *             case MotionEvent.ACTION_HOVER_MOVE:
-     *                 // process the mouse hover movement...
+     *                 // process the hover movement...
      *                 return true;
      *             case MotionEvent.ACTION_SCROLL:
      *                 // process the scroll wheel movement...
@@ -31893,7 +31917,7 @@
 
         RemoteCallback remoteCallback = new RemoteCallback(result ->
                 executor.execute(() -> {
-                    DisplayHash displayHash = result.getParcelable(EXTRA_DISPLAY_HASH);
+                    DisplayHash displayHash = result.getParcelable(EXTRA_DISPLAY_HASH, android.view.displayhash.DisplayHash.class);
                     int errorCode = result.getInt(EXTRA_DISPLAY_HASH_ERROR_CODE,
                             DISPLAY_HASH_ERROR_UNKNOWN);
                     if (displayHash != null) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 8907420..fbfeac7 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -179,6 +179,7 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 import android.view.accessibility.AccessibilityNodeProvider;
+import android.view.accessibility.AccessibilityWindowAttributes;
 import android.view.accessibility.AccessibilityWindowInfo;
 import android.view.accessibility.IAccessibilityEmbeddedConnection;
 import android.view.accessibility.IAccessibilityInteractionConnection;
@@ -1362,6 +1363,7 @@
 
                 if (mAccessibilityManager.isEnabled()) {
                     mAccessibilityInteractionConnectionManager.ensureConnection();
+                    setAccessibilityWindowAttributesIfNeeded();
                 }
 
                 if (view.getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
@@ -1390,6 +1392,17 @@
         }
     }
 
+    private void setAccessibilityWindowAttributesIfNeeded() {
+        final boolean registered = mAttachInfo.mAccessibilityWindowId
+                != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
+        if (registered) {
+            final AccessibilityWindowAttributes attributes = new AccessibilityWindowAttributes(
+                    mWindowAttributes);
+            mAccessibilityManager.setAccessibilityWindowAttributes(getDisplayId(),
+                    mAttachInfo.mAccessibilityWindowId, attributes);
+        }
+    }
+
     /**
      * Register any kind of listeners if setView was success.
      */
@@ -1707,6 +1720,7 @@
 
             mWindowAttributesChanged = true;
             scheduleTraversals();
+            setAccessibilityWindowAttributesIfNeeded();
         }
     }
 
@@ -2805,6 +2819,7 @@
         if (viewVisibilityChanged) {
             mAttachInfo.mWindowVisibility = viewVisibility;
             host.dispatchWindowVisibilityChanged(viewVisibility);
+            mAttachInfo.mTreeObserver.dispatchOnWindowVisibilityChange(viewVisibility);
             if (viewUserVisibilityChanged) {
                 host.dispatchVisibilityAggregated(viewVisibility == View.VISIBLE);
             }
@@ -3023,6 +3038,12 @@
                     if (surfaceControlChanged && mDisplayDecorationCached) {
                         updateDisplayDecoration();
                     }
+                    if (surfaceControlChanged
+                            && mWindowAttributes.type
+                            == WindowManager.LayoutParams.TYPE_STATUS_BAR) {
+                        mTransaction.setDefaultFrameRateCompatibility(mSurfaceControl,
+                            Surface.FRAME_RATE_COMPATIBILITY_NO_VOTE).apply();
+                    }
                 }
 
                 if (DEBUG_LAYOUT) Log.v(mTag, "relayout: frame=" + frame.toShortString()
@@ -3063,7 +3084,6 @@
                 if (surfaceReplaced) {
                     mSurfaceSequenceId++;
                 }
-
                 if (alwaysConsumeSystemBarsChanged) {
                     mAttachInfo.mAlwaysConsumeSystemBars = mPendingAlwaysConsumeSystemBars;
                     dispatchApplyInsets = true;
@@ -3762,6 +3782,7 @@
             }
         }
         mFirstInputStage.onWindowFocusChanged(hasWindowFocus);
+        mOnBackInvokedDispatcher.onWindowFocusChanged(hasWindowFocus);
 
         // NOTE: there's no view visibility (appeared / disapparead) events when the windows focus
         // is lost, so we don't need to to force a flush - there might be other events such as
@@ -10288,6 +10309,7 @@
         public void onAccessibilityStateChanged(boolean enabled) {
             if (enabled) {
                 ensureConnection();
+                setAccessibilityWindowAttributesIfNeeded();
                 if (mAttachInfo.mHasWindowFocus && (mView != null)) {
                     mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
                     View focusedView = mView.findFocus();
diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java
index 5a99ab2..2c077c3 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -43,6 +43,7 @@
     // Recursive listeners use CopyOnWriteArrayList
     private CopyOnWriteArrayList<OnWindowFocusChangeListener> mOnWindowFocusListeners;
     private CopyOnWriteArrayList<OnWindowAttachListener> mOnWindowAttachListeners;
+    private CopyOnWriteArrayList<OnWindowVisibilityChangeListener> mOnWindowVisibilityListeners;
     private CopyOnWriteArrayList<OnGlobalFocusChangeListener> mOnGlobalFocusListeners;
     @UnsupportedAppUsage
     private CopyOnWriteArrayList<OnTouchModeChangeListener> mOnTouchModeChangeListeners;
@@ -106,6 +107,19 @@
     }
 
     /**
+     * Interface definition for a callback to be invoked when the view hierarchy's window
+     * visibility changes.
+     */
+    public interface OnWindowVisibilityChangeListener {
+        /**
+         * Callback method to be invoked when the window visibility changes in the view tree.
+         *
+         * @param visibility The new visibility of the window.
+         */
+        void onWindowVisibilityChanged(@View.Visibility int visibility);
+    }
+
+    /**
      * Interface definition for a callback to be invoked when the focus state within
      * the view tree changes.
      */
@@ -386,6 +400,14 @@
             }
         }
 
+        if (observer.mOnWindowVisibilityListeners != null) {
+            if (mOnWindowVisibilityListeners != null) {
+                mOnWindowVisibilityListeners.addAll(observer.mOnWindowVisibilityListeners);
+            } else {
+                mOnWindowVisibilityListeners = observer.mOnWindowVisibilityListeners;
+            }
+        }
+
         if (observer.mOnGlobalFocusListeners != null) {
             if (mOnGlobalFocusListeners != null) {
                 mOnGlobalFocusListeners.addAll(observer.mOnGlobalFocusListeners);
@@ -540,6 +562,45 @@
     }
 
     /**
+     * Register a callback to be invoked when the window visibility changes.
+     *
+     * @param listener The callback to add
+     *
+     * @throws IllegalStateException If {@link #isAlive()} returns false
+     */
+    public void addOnWindowVisibilityChangeListener(
+            @NonNull OnWindowVisibilityChangeListener listener) {
+        checkIsAlive();
+
+        if (mOnWindowVisibilityListeners == null) {
+            mOnWindowVisibilityListeners =
+                new CopyOnWriteArrayList<OnWindowVisibilityChangeListener>();
+        }
+
+        mOnWindowVisibilityListeners.add(listener);
+    }
+
+    /**
+     * Remove a previously installed window visibility callback.
+     *
+     * @param victim The callback to remove
+     *
+     * @throws IllegalStateException If {@link #isAlive()} returns false
+     *
+     * @see #addOnWindowVisibilityChangeListener(
+     * android.view.ViewTreeObserver.OnWindowVisibilityChangeListener)
+     */
+    public void removeOnWindowVisibilityChangeListener(
+            @NonNull OnWindowVisibilityChangeListener victim) {
+        checkIsAlive();
+        if (mOnWindowVisibilityListeners == null) {
+            return;
+        }
+
+        mOnWindowVisibilityListeners.remove(victim);
+    }
+
+    /*
      * Register a callback to be invoked when the focus state within the view tree changes.
      *
      * @param listener The callback to add
@@ -1026,6 +1087,23 @@
     }
 
     /**
+     * Notifies registered listeners that window visibility has changed.
+     */
+    void dispatchOnWindowVisibilityChange(int visibility) {
+        // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
+        // perform the dispatching. The iterator is a safe guard against listeners that
+        // could mutate the list by calling the various add/remove methods. This prevents
+        // the array from being modified while we iterate it.
+        final CopyOnWriteArrayList<OnWindowVisibilityChangeListener> listeners =
+                mOnWindowVisibilityListeners;
+        if (listeners != null && listeners.size() > 0) {
+            for (OnWindowVisibilityChangeListener listener : listeners) {
+                listener.onWindowVisibilityChanged(visibility);
+            }
+        }
+    }
+
+    /**
      * Notifies registered listeners that focus has changed.
      */
     @UnsupportedAppUsage
diff --git a/core/java/android/view/WindowInfo.java b/core/java/android/view/WindowInfo.java
index a5b8720..11d63c8 100644
--- a/core/java/android/view/WindowInfo.java
+++ b/core/java/android/view/WindowInfo.java
@@ -208,6 +208,8 @@
             mTransformMatrix[i] = 0;
         }
         mMagnificationSpec.clear();
+        title = null;
+        accessibilityIdOfAnchor = AccessibilityNodeInfo.UNDEFINED_NODE_ID;
     }
 
     public static final @android.annotation.NonNull Parcelable.Creator<WindowInfo> CREATOR =
diff --git a/core/java/android/view/WindowLayout.java b/core/java/android/view/WindowLayout.java
index 9b6b2b9..57a0330 100644
--- a/core/java/android/view/WindowLayout.java
+++ b/core/java/android/view/WindowLayout.java
@@ -16,8 +16,6 @@
 
 package android.view;
 
-import static android.view.Gravity.DISPLAY_CLIP_HORIZONTAL;
-import static android.view.Gravity.DISPLAY_CLIP_VERTICAL;
 import static android.view.InsetsState.ITYPE_IME;
 import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.ITYPE_STATUS_BAR;
@@ -275,17 +273,9 @@
             Gravity.applyDisplay(attrs.gravity, outDisplayFrame, outFrame);
         }
 
-        if (extendedByCutout && !displayCutoutSafe.contains(outFrame)) {
-            mTempRect.set(outFrame);
-
-            // Move the frame into displayCutoutSafe.
-            final int clipFlags = DISPLAY_CLIP_VERTICAL | DISPLAY_CLIP_HORIZONTAL;
-            Gravity.applyDisplay(attrs.gravity & ~clipFlags, displayCutoutSafe,
+        if (extendedByCutout) {
+            extendFrameByCutout(displayCutoutSafe, outDisplayFrame, outFrame,
                     mTempRect);
-
-            if (mTempRect.intersect(outDisplayFrame)) {
-                outFrame.union(mTempRect);
-            }
         }
 
         if (DEBUG) Log.d(TAG, "computeFrames " + attrs.getTitle()
@@ -301,6 +291,21 @@
                 + " requestedVisibilities=" + requestedVisibilities);
     }
 
+    public static void extendFrameByCutout(Rect displayCutoutSafe,
+            Rect displayFrame, Rect inOutFrame, Rect tempRect) {
+        if (displayCutoutSafe.contains(inOutFrame)) {
+            return;
+        }
+        tempRect.set(inOutFrame);
+
+        // Move the frame into displayCutoutSafe.
+        Gravity.applyDisplay(0 /* gravity */, displayCutoutSafe, tempRect);
+
+        if (tempRect.intersect(displayFrame)) {
+            inOutFrame.union(tempRect);
+        }
+    }
+
     public static void computeSurfaceSize(WindowManager.LayoutParams attrs, Rect maxBounds,
             int requestedWidth, int requestedHeight, Rect winFrame, boolean dragResizing,
             Point outSurfaceSize) {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 13ea7af..b8808ee 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -820,6 +820,33 @@
     public static final String PARCEL_KEY_SHORTCUTS_ARRAY = "shortcuts_array";
 
     /**
+     * Application level {@link android.content.pm.PackageManager.Property} tag for developers to
+     * provide consent for their app to allow OEMs to manually provide ActivityEmbedding split
+     * rule configuration on behalf of the app.
+     *
+     * <p>If {@code true}, the system CAN override the windowing behaviors for the app, such as
+     * showing some activities side-by-side. In this case, it will report that ActivityEmbedding
+     * APIs are disabled for the app to avoid conflict.
+     *
+     * <p>If {@code false}, the system MUST NOT override the window behavior for the app. It should
+     * be used if the app wants to provide their own ActivityEmbedding split rules, or if the app
+     * wants to opt-out of system overrides for any other reason.
+     *
+     * <p>Default is {@code false}.
+     *
+     * <p>Example usage:
+     * <pre>
+     * &lt;application&gt;
+     *   &lt;property
+     *     android:name="android.window.PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE"
+     *     android:value="true|false"/&gt;
+     * &lt;/application&gt;
+     * </pre>
+     */
+    String PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE =
+            "android.window.PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE";
+
+    /**
      * Request for keyboard shortcuts to be retrieved asynchronously.
      *
      * @param receiver The callback to be triggered when the result is ready.
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 25445ab..d377565 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -404,9 +404,10 @@
             try {
                 root.setView(view, wparams, panelParentView, userId);
             } catch (RuntimeException e) {
+                final int viewIndex = (index >= 0) ? index : (mViews.size() - 1);
                 // BadTokenException or InvalidDisplayException, clean up.
-                if (index >= 0) {
-                    removeViewLocked(index, true);
+                if (viewIndex >= 0) {
+                    removeViewLocked(viewIndex, true);
                 }
                 throw e;
             }
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 20cdad4..dc4ccba 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -213,7 +213,7 @@
             @Override
             public void send(int resultCode, Bundle resultData) throws RemoteException {
                 List<KeyboardShortcutGroup> result =
-                        resultData.getParcelableArrayList(PARCEL_KEY_SHORTCUTS_ARRAY);
+                        resultData.getParcelableArrayList(PARCEL_KEY_SHORTCUTS_ARRAY, android.view.KeyboardShortcutGroup.class);
                 receiver.onKeyboardShortcutsReceived(result);
             }
         };
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index c6cd2e8..9e3195a 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -1832,6 +1832,32 @@
         }
     }
 
+
+    /**
+     * Sets the {@link AccessibilityWindowAttributes} to the window associated with the given
+     * window id.
+     *
+     * @param displayId The display id of the window.
+     * @param windowId  The id of the window.
+     * @param attributes The accessibility window attributes.
+     * @hide
+     */
+    public void setAccessibilityWindowAttributes(int displayId, int windowId,
+            AccessibilityWindowAttributes attributes) {
+        final IAccessibilityManager service;
+        synchronized (mLock) {
+            service = getServiceLocked();
+            if (service == null) {
+                return;
+            }
+        }
+        try {
+            service.setAccessibilityWindowAttributes(displayId, windowId, mUserId, attributes);
+        } catch (RemoteException re) {
+            re.rethrowFromSystemServer();
+        }
+    }
+
     private IAccessibilityManager getServiceLocked() {
         if (mService == null) {
             tryConnectToServiceLocked(null);
diff --git a/core/java/android/view/accessibility/AccessibilityWindowAttributes.aidl b/core/java/android/view/accessibility/AccessibilityWindowAttributes.aidl
new file mode 100644
index 0000000..0917458
--- /dev/null
+++ b/core/java/android/view/accessibility/AccessibilityWindowAttributes.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2022, 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.view.accessibility;
+
+parcelable AccessibilityWindowAttributes;
diff --git a/core/java/android/view/accessibility/AccessibilityWindowAttributes.java b/core/java/android/view/accessibility/AccessibilityWindowAttributes.java
new file mode 100644
index 0000000..562300c
--- /dev/null
+++ b/core/java/android/view/accessibility/AccessibilityWindowAttributes.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2022 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.view.accessibility;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.view.WindowManager;
+
+/**
+ * This class represents the attributes of a window needed for {@link AccessibilityWindowInfo}.
+ *
+ * @hide
+ */
+public final class AccessibilityWindowAttributes implements Parcelable {
+
+    private final CharSequence mWindowTitle;
+
+    public AccessibilityWindowAttributes(@NonNull WindowManager.LayoutParams layoutParams) {
+        mWindowTitle = populateWindowTitle(layoutParams);
+    }
+
+    private AccessibilityWindowAttributes(Parcel in) {
+        mWindowTitle = in.readCharSequence();
+    }
+
+    public CharSequence getWindowTitle() {
+        return mWindowTitle;
+    }
+
+    private CharSequence populateWindowTitle(@NonNull WindowManager.LayoutParams layoutParams) {
+        CharSequence windowTitle = layoutParams.accessibilityTitle;
+        // Panel windows have no public way to set the a11y title directly. Use the
+        // regular title as a fallback.
+        final boolean isPanelWindow =
+                (layoutParams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW)
+                        && (layoutParams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW);
+        // Accessibility overlays should have titles that work for accessibility, and can't set
+        // the a11y title themselves.
+        final boolean isAccessibilityOverlay =
+                layoutParams.type == WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
+
+        if (TextUtils.isEmpty(windowTitle) && (isPanelWindow
+                || isAccessibilityOverlay)) {
+            windowTitle = TextUtils.isEmpty(layoutParams.getTitle()) ? null
+                    : layoutParams.getTitle();
+        }
+        return  windowTitle;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof AccessibilityWindowAttributes)) return false;
+
+        AccessibilityWindowAttributes that = (AccessibilityWindowAttributes) o;
+
+        return TextUtils.equals(mWindowTitle, that.mWindowTitle);
+    }
+
+    @Override
+    public int hashCode() {
+        return mWindowTitle.hashCode();
+    }
+
+    public static final Creator<AccessibilityWindowAttributes> CREATOR =
+            new Creator<AccessibilityWindowAttributes>() {
+                @Override
+                public AccessibilityWindowAttributes createFromParcel(Parcel in) {
+                    return new AccessibilityWindowAttributes(in);
+                }
+
+                @Override
+                public AccessibilityWindowAttributes[] newArray(int size) {
+                    return new AccessibilityWindowAttributes[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeCharSequence(mWindowTitle);
+    }
+
+    @Override
+    public String toString() {
+        return "AccessibilityWindowAttributes{"
+                + "mAccessibilityWindowTitle=" + mWindowTitle
+                + '}';
+    }
+}
diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl
index 4fc9a07..1e06098 100644
--- a/core/java/android/view/accessibility/IAccessibilityManager.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl
@@ -25,6 +25,7 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.IAccessibilityInteractionConnection;
 import android.view.accessibility.IAccessibilityManagerClient;
+import android.view.accessibility.AccessibilityWindowAttributes;
 import android.view.accessibility.IWindowMagnificationConnection;
 import android.view.IWindow;
 
@@ -105,4 +106,6 @@
 
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.SET_SYSTEM_AUDIO_CAPTION)")
     void setSystemAudioCaptioningUiEnabled(boolean isEnabled, int userId);
+
+    oneway void setAccessibilityWindowAttributes(int displayId, int windowId, int userId, in AccessibilityWindowAttributes attributes);
 }
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 6a27eb5..dbefcfb 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -944,7 +944,7 @@
             return;
         }
         synchronized (mLock) {
-            mLastAutofilledData = savedInstanceState.getParcelable(LAST_AUTOFILLED_DATA_TAG);
+            mLastAutofilledData = savedInstanceState.getParcelable(LAST_AUTOFILLED_DATA_TAG, android.view.autofill.ParcelableMap.class);
 
             if (isActiveLocked()) {
                 Log.w(TAG, "New session was started before onCreate()");
diff --git a/core/java/android/view/inputmethod/IInputMethodManagerInvoker.java b/core/java/android/view/inputmethod/IInputMethodManagerInvoker.java
index 4b472ed..fc1ede0 100644
--- a/core/java/android/view/inputmethod/IInputMethodManagerInvoker.java
+++ b/core/java/android/view/inputmethod/IInputMethodManagerInvoker.java
@@ -18,10 +18,13 @@
 
 import android.annotation.AnyThread;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
 import android.window.ImeOnBackInvokedDispatcher;
 
 import com.android.internal.inputmethod.DirectBootAwareness;
@@ -54,8 +57,8 @@
     }
 
     @AnyThread
-    void addClient(IInputMethodClient client, IRemoteInputConnection fallbackInputConnection,
-            int untrustedDisplayId) {
+    void addClient(@NonNull IInputMethodClient client,
+            @NonNull IRemoteInputConnection fallbackInputConnection, int untrustedDisplayId) {
         try {
             mTarget.addClient(client, fallbackInputConnection, untrustedDisplayId);
         } catch (RemoteException e) {
@@ -64,25 +67,18 @@
     }
 
     @AnyThread
-    List<InputMethodInfo> getInputMethodList(@UserIdInt int userId) {
-        try {
-            return mTarget.getInputMethodList(userId);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    @AnyThread
-    List<InputMethodInfo> getAwareLockedInputMethodList(@UserIdInt int userId,
+    @NonNull
+    List<InputMethodInfo> getInputMethodList(@UserIdInt int userId,
             @DirectBootAwareness int directBootAwareness) {
         try {
-            return mTarget.getAwareLockedInputMethodList(userId, directBootAwareness);
+            return mTarget.getInputMethodList(userId, directBootAwareness);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
     @AnyThread
+    @NonNull
     List<InputMethodInfo> getEnabledInputMethodList(@UserIdInt int userId) {
         try {
             return mTarget.getEnabledInputMethodList(userId);
@@ -92,7 +88,8 @@
     }
 
     @AnyThread
-    List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String imiId,
+    @NonNull
+    List<InputMethodSubtype> getEnabledInputMethodSubtypeList(@Nullable String imiId,
             boolean allowsImplicitlySelectedSubtypes) {
         try {
             return mTarget.getEnabledInputMethodSubtypeList(imiId,
@@ -103,6 +100,7 @@
     }
 
     @AnyThread
+    @Nullable
     InputMethodSubtype getLastInputMethodSubtype() {
         try {
             return mTarget.getLastInputMethodSubtype();
@@ -112,8 +110,9 @@
     }
 
     @AnyThread
-    boolean showSoftInput(IInputMethodClient client, IBinder windowToken,
-            int flags, ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {
+    boolean showSoftInput(@NonNull IInputMethodClient client, @Nullable IBinder windowToken,
+            int flags, @Nullable ResultReceiver resultReceiver,
+            @SoftInputShowHideReason int reason) {
         try {
             return mTarget.showSoftInput(client, windowToken, flags, resultReceiver, reason);
         } catch (RemoteException e) {
@@ -122,8 +121,9 @@
     }
 
     @AnyThread
-    boolean hideSoftInput(IInputMethodClient client, IBinder windowToken,
-            int flags, ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {
+    boolean hideSoftInput(@NonNull IInputMethodClient client, @Nullable IBinder windowToken,
+            int flags, @Nullable ResultReceiver resultReceiver,
+            @SoftInputShowHideReason int reason) {
         try {
             return mTarget.hideSoftInput(client, windowToken, flags, resultReceiver, reason);
         } catch (RemoteException e) {
@@ -132,13 +132,14 @@
     }
 
     @AnyThread
+    @NonNull
     InputBindResult startInputOrWindowGainedFocus(@StartInputReason int startInputReason,
-            IInputMethodClient client, IBinder windowToken,
-            @StartInputFlags int startInputFlags,
-            @android.view.WindowManager.LayoutParams.SoftInputModeFlags int softInputMode,
-            int windowFlags, EditorInfo editorInfo, IRemoteInputConnection remoteInputConnection,
-            IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
-            int unverifiedTargetSdkVersion, ImeOnBackInvokedDispatcher imeDispatcher) {
+            @NonNull IInputMethodClient client, @Nullable IBinder windowToken,
+            @StartInputFlags int startInputFlags, @SoftInputModeFlags int softInputMode,
+            @WindowManager.LayoutParams.Flags int windowFlags, @Nullable EditorInfo editorInfo,
+            @Nullable IRemoteInputConnection remoteInputConnection,
+            @Nullable IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
+            int unverifiedTargetSdkVersion, @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
         try {
             return mTarget.startInputOrWindowGainedFocus(startInputReason, client, windowToken,
                     startInputFlags, softInputMode, windowFlags, editorInfo, remoteInputConnection,
@@ -149,7 +150,8 @@
     }
 
     @AnyThread
-    void showInputMethodPickerFromClient(IInputMethodClient client, int auxiliarySubtypeMode) {
+    void showInputMethodPickerFromClient(@NonNull IInputMethodClient client,
+            int auxiliarySubtypeMode) {
         try {
             mTarget.showInputMethodPickerFromClient(client, auxiliarySubtypeMode);
         } catch (RemoteException e) {
@@ -158,8 +160,8 @@
     }
 
     @AnyThread
-    void showInputMethodPickerFromSystem(IInputMethodClient client, int auxiliarySubtypeMode,
-            int displayId) {
+    void showInputMethodPickerFromSystem(@NonNull IInputMethodClient client,
+            int auxiliarySubtypeMode, int displayId) {
         try {
             mTarget.showInputMethodPickerFromSystem(client, auxiliarySubtypeMode, displayId);
         } catch (RemoteException e) {
@@ -168,15 +170,6 @@
     }
 
     @AnyThread
-    void showInputMethodAndSubtypeEnablerFromClient(IInputMethodClient client, String imeId) {
-        try {
-            mTarget.showInputMethodAndSubtypeEnablerFromClient(client, imeId);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    @AnyThread
     boolean isInputMethodPickerShownForTest() {
         try {
             return mTarget.isInputMethodPickerShownForTest();
@@ -186,6 +179,7 @@
     }
 
     @AnyThread
+    @Nullable
     InputMethodSubtype getCurrentInputMethodSubtype() {
         try {
             return mTarget.getCurrentInputMethodSubtype();
@@ -195,7 +189,8 @@
     }
 
     @AnyThread
-    void setAdditionalInputMethodSubtypes(String imeId, InputMethodSubtype[] subtypes) {
+    void setAdditionalInputMethodSubtypes(@NonNull String imeId,
+            @NonNull InputMethodSubtype[] subtypes) {
         try {
             mTarget.setAdditionalInputMethodSubtypes(imeId, subtypes);
         } catch (RemoteException e) {
@@ -204,7 +199,7 @@
     }
 
     @AnyThread
-    int getInputMethodWindowVisibleHeight(IInputMethodClient client) {
+    int getInputMethodWindowVisibleHeight(@NonNull IInputMethodClient client) {
         try {
             return mTarget.getInputMethodWindowVisibleHeight(client);
         } catch (RemoteException e) {
@@ -213,8 +208,8 @@
     }
 
     @AnyThread
-    void reportVirtualDisplayGeometryAsync(IInputMethodClient client, int childDisplayId,
-            float[] matrixValues) {
+    void reportVirtualDisplayGeometryAsync(@NonNull IInputMethodClient client, int childDisplayId,
+            @Nullable float[] matrixValues) {
         try {
             mTarget.reportVirtualDisplayGeometryAsync(client, childDisplayId, matrixValues);
         } catch (RemoteException e) {
@@ -223,7 +218,7 @@
     }
 
     @AnyThread
-    void reportPerceptibleAsync(IBinder windowToken, boolean perceptible) {
+    void reportPerceptibleAsync(@NonNull IBinder windowToken, boolean perceptible) {
         try {
             mTarget.reportPerceptibleAsync(windowToken, perceptible);
         } catch (RemoteException e) {
@@ -232,7 +227,7 @@
     }
 
     @AnyThread
-    void removeImeSurfaceFromWindowAsync(IBinder windowToken) {
+    void removeImeSurfaceFromWindowAsync(@NonNull IBinder windowToken) {
         try {
             mTarget.removeImeSurfaceFromWindowAsync(windowToken);
         } catch (RemoteException e) {
@@ -241,7 +236,7 @@
     }
 
     @AnyThread
-    void startStylusHandwriting(IInputMethodClient client) {
+    void startStylusHandwriting(@NonNull IInputMethodClient client) {
         try {
             mTarget.startStylusHandwriting(client);
         } catch (RemoteException e) {
@@ -257,4 +252,13 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    @AnyThread
+    void addVirtualStylusIdForTestSession(IInputMethodClient client) {
+        try {
+            mTarget.addVirtualStylusIdForTestSession(client);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 59d3314..654713b 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -53,9 +53,11 @@
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.graphics.Matrix;
 import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
 import android.inputmethodservice.InputMethodService;
 import android.os.Binder;
 import android.os.Build;
@@ -71,6 +73,7 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.text.TextUtils;
 import android.text.style.SuggestionSpan;
 import android.util.Log;
 import android.util.Pools.Pool;
@@ -266,10 +269,10 @@
 @SystemService(Context.INPUT_METHOD_SERVICE)
 @RequiresFeature(PackageManager.FEATURE_INPUT_METHODS)
 public final class InputMethodManager {
-    static final boolean DEBUG = false;
-    static final String TAG = "InputMethodManager";
+    private static final boolean DEBUG = false;
+    private static final String TAG = "InputMethodManager";
 
-    static final String PENDING_EVENT_COUNTER = "aq:imm";
+    private static final String PENDING_EVENT_COUNTER = "aq:imm";
 
     private static final int NOT_A_SUBTYPE_ID = -1;
 
@@ -361,7 +364,7 @@
     /**
      * Timeout in milliseconds for delivering a key to an IME.
      */
-    static final long INPUT_METHOD_NOT_RESPONDING_TIMEOUT = 2500;
+    private static final long INPUT_METHOD_NOT_RESPONDING_TIMEOUT = 2500;
 
     /** @hide */
     public static final int DISPATCH_IN_PROGRESS = -1;
@@ -400,7 +403,7 @@
     @Deprecated
     @UnsupportedAppUsage
     final IInputMethodManager mService;
-    final Looper mMainLooper;
+    private final Looper mMainLooper;
 
     @NonNull
     private final IInputMethodManagerInvoker mServiceInvoker;
@@ -422,7 +425,7 @@
     /**
      * True if this input method client is active, initially false.
      */
-    boolean mActive = false;
+    private boolean mActive = false;
 
     /**
      * {@code true} if next {@link ImeFocusController#onPostWindowFocus} needs to
@@ -433,7 +436,7 @@
     /**
      * As reported by IME through InputConnection.
      */
-    boolean mFullscreenMode;
+    private boolean mFullscreenMode;
 
     // -----------------------------------------------------------
 
@@ -447,33 +450,33 @@
      * This is set when we are in the process of connecting, to determine
      * when we have actually finished.
      */
-    boolean mServedConnecting;
+    private boolean mServedConnecting;
     /**
      * This is non-null when we have connected the served view; it holds
      * the attributes that were last retrieved from the served view and given
      * to the input connection.
      */
-    EditorInfo mCurrentEditorInfo;
+    private EditorInfo mCurrentEditorInfo;
     /**
      * The InputConnection that was last retrieved from the served view.
      */
-    RemoteInputConnectionImpl mServedInputConnection;
+    private RemoteInputConnectionImpl mServedInputConnection;
     /**
      * The completions that were last provided by the served view.
      */
-    CompletionInfo[] mCompletions;
+    private CompletionInfo[] mCompletions;
 
     // Cursor position on the screen.
     @UnsupportedAppUsage
     Rect mTmpCursorRect = new Rect();
     @UnsupportedAppUsage
     Rect mCursorRect = new Rect();
-    int mCursorSelStart;
-    int mCursorSelEnd;
-    int mCursorCandStart;
-    int mCursorCandEnd;
-    int mInitialSelStart;
-    int mInitialSelEnd;
+    private int mCursorSelStart;
+    private int mCursorSelEnd;
+    private int mCursorCandStart;
+    private int mCursorCandEnd;
+    private int mInitialSelStart;
+    private int mInitialSelEnd;
 
     /**
      * Handler for {@link RemoteInputConnectionImpl#getInputConnection()}.
@@ -500,11 +503,6 @@
     // -----------------------------------------------------------
 
     /**
-     * Sequence number of this binding, as returned by the server.
-     */
-    int mBindSequence = -1;
-
-    /**
      * ID of the method we are bound to.
      *
      * @deprecated New code should use {@code mCurBindState.mImeId}.
@@ -539,8 +537,8 @@
     private final SparseArray<IAccessibilityInputMethodSessionInvoker>
             mAccessibilityInputMethodSession = new SparseArray<>();
 
-    InputChannel mCurChannel;
-    ImeInputEventSender mCurSender;
+    private InputChannel mCurChannel;
+    private ImeInputEventSender mCurSender;
 
     private static final int REQUEST_UPDATE_CURSOR_ANCHOR_INFO_NONE = 0x0;
 
@@ -556,25 +554,25 @@
      */
     private ImeInsetsSourceConsumer mImeInsetsConsumer;
 
-    final Pool<PendingEvent> mPendingEventPool = new SimplePool<>(20);
-    final SparseArray<PendingEvent> mPendingEvents = new SparseArray<>(20);
+    private final Pool<PendingEvent> mPendingEventPool = new SimplePool<>(20);
+    private final SparseArray<PendingEvent> mPendingEvents = new SparseArray<>(20);
 
-    final DelegateImpl mDelegate = new DelegateImpl();
+    private final DelegateImpl mDelegate = new DelegateImpl();
 
     // -----------------------------------------------------------
 
-    static final int MSG_DUMP = 1;
-    static final int MSG_BIND = 2;
-    static final int MSG_UNBIND = 3;
-    static final int MSG_SET_ACTIVE = 4;
-    static final int MSG_SEND_INPUT_EVENT = 5;
-    static final int MSG_TIMEOUT_INPUT_EVENT = 6;
-    static final int MSG_FLUSH_INPUT_EVENT = 7;
-    static final int MSG_REPORT_FULLSCREEN_MODE = 10;
-    static final int MSG_BIND_ACCESSIBILITY_SERVICE = 11;
-    static final int MSG_UNBIND_ACCESSIBILITY_SERVICE = 12;
-    static final int MSG_UPDATE_VIRTUAL_DISPLAY_TO_SCREEN_MATRIX = 30;
-    static final int MSG_ON_SHOW_REQUESTED = 31;
+    private static final int MSG_DUMP = 1;
+    private static final int MSG_BIND = 2;
+    private static final int MSG_UNBIND = 3;
+    private static final int MSG_SET_ACTIVE = 4;
+    private static final int MSG_SEND_INPUT_EVENT = 5;
+    private static final int MSG_TIMEOUT_INPUT_EVENT = 6;
+    private static final int MSG_FLUSH_INPUT_EVENT = 7;
+    private static final int MSG_REPORT_FULLSCREEN_MODE = 10;
+    private static final int MSG_BIND_ACCESSIBILITY_SERVICE = 11;
+    private static final int MSG_UNBIND_ACCESSIBILITY_SERVICE = 12;
+    private static final int MSG_UPDATE_VIRTUAL_DISPLAY_TO_SCREEN_MATRIX = 30;
+    private static final int MSG_ON_SHOW_REQUESTED = 31;
 
     private static boolean isAutofillUIShowing(View servedView) {
         AutofillManager afm = servedView.getContext().getSystemService(AutofillManager.class);
@@ -642,7 +640,7 @@
      * {@link android.view.WindowInsetsController}.
      * @hide
      */
-    public void reportPerceptible(IBinder windowToken, boolean perceptible) {
+    public void reportPerceptible(@NonNull IBinder windowToken, boolean perceptible) {
         mServiceInvoker.reportPerceptibleAsync(windowToken, perceptible);
     }
 
@@ -913,8 +911,9 @@
                         Log.i(TAG, "handleMessage: MSG_BIND " + res.sequence + "," + res.id);
                     }
                     synchronized (mH) {
-                        if (mBindSequence < 0 || mBindSequence != res.sequence) {
-                            Log.w(TAG, "Ignoring onBind: cur seq=" + mBindSequence
+                        final int curBindSequence = getBindSequenceLocked();
+                        if (curBindSequence < 0 || curBindSequence != res.sequence) {
+                            Log.w(TAG, "Ignoring onBind: cur seq=" + curBindSequence
                                     + ", given seq=" + res.sequence);
                             if (res.channel != null && res.channel != mCurChannel) {
                                 res.channel.dispose();
@@ -925,11 +924,10 @@
                         mRequestUpdateCursorAnchorInfoMonitorMode =
                                 REQUEST_UPDATE_CURSOR_ANCHOR_INFO_NONE;
 
-                        setInputChannelLocked(res.channel);
+                        updateInputChannelLocked(res.channel);
                         mCurMethod = res.method; // for @UnsupportedAppUsage
                         mCurBindState = new BindState(res);
                         mCurId = res.id; // for @UnsupportedAppUsage
-                        mBindSequence = res.sequence;
                         mVirtualDisplayToScreenMatrix = res.getVirtualDisplayToScreenMatrix();
                     }
                     startInputInner(StartInputReason.BOUND_TO_IMMS, null, 0, 0, 0);
@@ -945,7 +943,7 @@
                     }
                     final boolean startInput;
                     synchronized (mH) {
-                        if (mBindSequence != sequence) {
+                        if (getBindSequenceLocked() != sequence) {
                             return;
                         }
                         clearAllAccessibilityBindingLocked();
@@ -972,8 +970,9 @@
                                 + "," + res.id);
                     }
                     synchronized (mH) {
-                        if (mBindSequence < 0 || mBindSequence != res.sequence) {
-                            Log.w(TAG, "Ignoring onBind: cur seq=" + mBindSequence
+                        final int curBindSequence = getBindSequenceLocked();
+                        if (curBindSequence < 0 || curBindSequence != res.sequence) {
+                            Log.w(TAG, "Ignoring onBind: cur seq=" + curBindSequence
                                     + ", given seq=" + res.sequence);
                             if (res.channel != null && res.channel != mCurChannel) {
                                 res.channel.dispose();
@@ -1004,7 +1003,6 @@
                                 }
                             }
                         }
-                        mBindSequence = res.sequence;
                     }
                     startInputInner(StartInputReason.BOUND_ACCESSIBILITY_SESSION_TO_IMMS, null,
                             0, 0, 0);
@@ -1018,10 +1016,10 @@
                                 + sequence + " id=" + id);
                     }
                     synchronized (mH) {
-                        if (mBindSequence != sequence) {
+                        if (getBindSequenceLocked() != sequence) {
                             if (DEBUG) {
-                                Log.i(TAG, "mBindSequence =" + mBindSequence + " sequence ="
-                                        + sequence + " id=" + id);
+                                Log.i(TAG, "current BindSequence =" + getBindSequenceLocked()
+                                        + " sequence =" + sequence + " id=" + id);
                             }
                             return;
                         }
@@ -1102,7 +1100,7 @@
                     final float[] matrixValues = (float[]) msg.obj;
                     final int bindSequence = msg.arg1;
                     synchronized (mH) {
-                        if (mBindSequence != bindSequence) {
+                        if (getBindSequenceLocked() != bindSequence) {
                             return;
                         }
                         if (matrixValues == null || mVirtualDisplayToScreenMatrix == null) {
@@ -1147,7 +1145,7 @@
         }
     }
 
-    final IInputMethodClient.Stub mClient = new IInputMethodClient.Stub() {
+    private final IInputMethodClient.Stub mClient = new IInputMethodClient.Stub() {
         @Override
         protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
             // No need to check for dump permission, since we only give this
@@ -1401,11 +1399,12 @@
      *
      * @return {@link List} of {@link InputMethodInfo}.
      */
+    @NonNull
     public List<InputMethodInfo> getInputMethodList() {
         // We intentionally do not use UserHandle.getCallingUserId() here because for system
         // services InputMethodManagerInternal.getInputMethodListAsUser() should be used
         // instead.
-        return mServiceInvoker.getInputMethodList(UserHandle.myUserId());
+        return mServiceInvoker.getInputMethodList(UserHandle.myUserId(), DirectBootAwareness.AUTO);
     }
 
     /**
@@ -1453,7 +1452,7 @@
     @RequiresPermission(INTERACT_ACROSS_USERS_FULL)
     @NonNull
     public List<InputMethodInfo> getInputMethodListAsUser(@UserIdInt int userId) {
-        return mServiceInvoker.getInputMethodList(userId);
+        return mServiceInvoker.getInputMethodList(userId, DirectBootAwareness.AUTO);
     }
 
     /**
@@ -1469,7 +1468,7 @@
     @NonNull
     public List<InputMethodInfo> getInputMethodListAsUser(@UserIdInt int userId,
             @DirectBootAwareness int directBootAwareness) {
-        return mServiceInvoker.getAwareLockedInputMethodList(userId, directBootAwareness);
+        return mServiceInvoker.getInputMethodList(userId, directBootAwareness);
     }
 
     /**
@@ -1479,6 +1478,7 @@
      *
      * @return {@link List} of {@link InputMethodInfo}.
      */
+    @NonNull
     public List<InputMethodInfo> getEnabledInputMethodList() {
         // We intentionally do not use UserHandle.getCallingUserId() here because for system
         // services InputMethodManagerInternal.getEnabledInputMethodListAsUser() should be used
@@ -1503,12 +1503,14 @@
      *
      * <p>On multi user environment, this API returns a result for the calling process user.</p>
      *
-     * @param imi An input method info whose subtypes list will be returned.
+     * @param imi The {@link InputMethodInfo} whose subtypes list will be returned. If {@code null},
+     * returns enabled subtypes for the currently selected {@link InputMethodInfo}.
      * @param allowsImplicitlySelectedSubtypes A boolean flag to allow to return the implicitly
      * selected subtypes. If an input method info doesn't have enabled subtypes, the framework
      * will implicitly enable subtypes according to the current system language.
      */
-    public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(InputMethodInfo imi,
+    @NonNull
+    public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(@Nullable InputMethodInfo imi,
             boolean allowsImplicitlySelectedSubtypes) {
         return mServiceInvoker.getEnabledInputMethodSubtypeList(
                 imi == null ? null : imi.getId(),
@@ -1625,14 +1627,13 @@
      * Reset all of the state associated with being bound to an input method.
      */
     @GuardedBy("mH")
-    void clearBindingLocked() {
+    private void clearBindingLocked() {
         if (DEBUG) Log.v(TAG, "Clearing binding!");
         clearConnectionLocked();
-        setInputChannelLocked(null);
-        // We only reset sequence number for input method, but not accessibility.
-        mBindSequence = -1;
+        updateInputChannelLocked(null);
         mCurId = null; // for @UnsupportedAppUsage
         mCurMethod = null; // for @UnsupportedAppUsage
+        // We only reset sequence number for input method, but not accessibility.
         mCurBindState = null;
     }
 
@@ -1640,47 +1641,57 @@
      * Reset all of the state associated with being bound to an accessibility service.
      */
     @GuardedBy("mH")
-    void clearAccessibilityBindingLocked(int id) {
+    private void clearAccessibilityBindingLocked(int id) {
         if (DEBUG) Log.v(TAG, "Clearing accessibility binding " + id);
         mAccessibilityInputMethodSession.remove(id);
     }
 
     /**
-     * Reset all of the state associated with being bound to all ccessibility services.
+     * Reset all of the state associated with being bound to all accessibility services.
      */
     @GuardedBy("mH")
-    void clearAllAccessibilityBindingLocked() {
+    private void clearAllAccessibilityBindingLocked() {
         if (DEBUG) Log.v(TAG, "Clearing all accessibility bindings");
         mAccessibilityInputMethodSession.clear();
     }
 
-    void setInputChannelLocked(InputChannel channel) {
-        if (mCurChannel == channel) {
+    @GuardedBy("mH")
+    private void updateInputChannelLocked(InputChannel channel) {
+        if (areSameInputChannel(mCurChannel, channel)) {
             return;
         }
-        if (mCurChannel != null && channel != null
-                && mCurChannel.getToken() == channel.getToken()) {
-            // channel is a dupe of 'mCurChannel', because they have the same token, and represent
-            // the same connection. Ignore the incoming channel and keep using 'mCurChannel' to
-            // avoid confusing the InputEventReceiver.
-            return;
-        }
+        // TODO(b/238720598) : Requirements when design a new protocol for InputChannel
+        // channel is a dupe of 'mCurChannel', because they have the same token, and represent
+        // the same connection. Ignore the incoming channel and keep using 'mCurChannel' to
+        // avoid confusing the InputEventReceiver.
         if (mCurSender != null) {
             flushPendingEventsLocked();
             mCurSender.dispose();
             mCurSender = null;
         }
+
         if (mCurChannel != null) {
             mCurChannel.dispose();
         }
         mCurChannel = channel;
     }
 
+    private static boolean areSameInputChannel(@Nullable InputChannel lhs,
+            @Nullable InputChannel rhs) {
+        if (lhs == rhs) {
+            return true;
+        }
+        if (lhs == null || rhs == null) {
+            return false;
+        }
+        return lhs.getToken() == rhs.getToken();
+    }
+
     /**
      * Reset all of the state associated with a served view being connected
      * to an input method
      */
-    void clearConnectionLocked() {
+    private void clearConnectionLocked() {
         mCurrentEditorInfo = null;
         if (mServedInputConnection != null) {
             mServedInputConnection.deactivate();
@@ -2230,7 +2241,7 @@
      * Note that this method should *NOT* be called inside of {@code mH} lock to prevent start input
      * background thread may blocked by other methods which already inside {@code mH} lock.
      */
-    boolean startInputInner(@StartInputReason int startInputReason,
+    private boolean startInputInner(@StartInputReason int startInputReason,
             @Nullable IBinder windowGainingFocus, @StartInputFlags int startInputFlags,
             @SoftInputModeFlags int softInputMode, int windowFlags) {
         final View view;
@@ -2390,8 +2401,7 @@
             }
             mVirtualDisplayToScreenMatrix = res.getVirtualDisplayToScreenMatrix();
             if (res.id != null) {
-                setInputChannelLocked(res.channel);
-                mBindSequence = res.sequence;
+                updateInputChannelLocked(res.channel);
                 mCurMethod = res.method; // for @UnsupportedAppUsage
                 mCurBindState = new BindState(res);
                 mAccessibilityInputMethodSession.clear();
@@ -2444,6 +2454,17 @@
     }
 
     /**
+     *
+     * @hide
+     */
+    @TestApi
+    public void addVirtualStylusIdForTestSession() {
+        synchronized (mH) {
+            mServiceInvoker.addVirtualStylusIdForTestSession(mClient);
+        }
+    }
+
+    /**
      * An empty method only to avoid crashes of apps that call this method via reflection and do not
      * handle {@link NoSuchMethodException} in a graceful manner.
      *
@@ -2592,7 +2613,7 @@
      * @param windowToken The client window token that requests the IME to remove its surface.
      * @hide
      */
-    public void removeImeSurface(IBinder windowToken) {
+    public void removeImeSurface(@NonNull IBinder windowToken) {
         synchronized (mH) {
             mServiceInvoker.removeImeSurfaceFromWindowAsync(windowToken);
         }
@@ -3061,7 +3082,7 @@
     }
 
     // Must be called on the main looper
-    void sendInputEventAndReportResultOnMainLooper(PendingEvent p) {
+    private void sendInputEventAndReportResultOnMainLooper(PendingEvent p) {
         final boolean handled;
         synchronized (mH) {
             int result = sendInputEventOnMainLooperLocked(p);
@@ -3076,7 +3097,7 @@
     }
 
     // Must be called on the main looper
-    int sendInputEventOnMainLooperLocked(PendingEvent p) {
+    private int sendInputEventOnMainLooperLocked(PendingEvent p) {
         if (mCurChannel != null) {
             if (mCurSender == null) {
                 mCurSender = new ImeInputEventSender(mCurChannel, mH.getLooper());
@@ -3101,7 +3122,7 @@
         return DISPATCH_NOT_HANDLED;
     }
 
-    void finishedInputEvent(int seq, boolean handled, boolean timeout) {
+    private void finishedInputEvent(int seq, boolean handled, boolean timeout) {
         final PendingEvent p;
         synchronized (mH) {
             int index = mPendingEvents.indexOfKey(seq);
@@ -3125,7 +3146,7 @@
     }
 
     // Assumes the event has already been removed from the queue.
-    void invokeFinishedInputEventCallback(PendingEvent p, boolean handled) {
+    private void invokeFinishedInputEventCallback(PendingEvent p, boolean handled) {
         p.mHandled = handled;
         if (p.mHandler.getLooper().isCurrentThread()) {
             // Already running on the callback handler thread so we can send the
@@ -3224,8 +3245,27 @@
      * @param imiId An input method, whose subtypes settings will be shown. If imiId is null,
      * subtypes of all input methods will be shown.
      */
-    public void showInputMethodAndSubtypeEnabler(String imiId) {
-        mServiceInvoker.showInputMethodAndSubtypeEnablerFromClient(mClient, imiId);
+    public void showInputMethodAndSubtypeEnabler(@Nullable String imiId) {
+        Context context = null;
+        synchronized (mH) {
+            if (mCurRootView != null) {
+                context = mCurRootView.mContext;
+            }
+        }
+        if (context == null) {
+            final Context appContext = ActivityThread.currentApplication();
+            final DisplayManager displayManager = appContext.getSystemService(DisplayManager.class);
+            context = appContext.createDisplayContext(displayManager.getDisplay(mDisplayId));
+        }
+
+        final Intent intent = new Intent(Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
+                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        if (!TextUtils.isEmpty(imiId)) {
+            intent.putExtra(Settings.EXTRA_INPUT_METHOD_ID, imiId);
+        }
+        context.startActivity(intent);
     }
 
     /**
@@ -3233,6 +3273,7 @@
      * the current input method. This method returns null when the current input method doesn't
      * have any input method subtype.
      */
+    @Nullable
     public InputMethodSubtype getCurrentInputMethodSubtype() {
         return mServiceInvoker.getCurrentInputMethodSubtype();
     }
@@ -3467,10 +3508,12 @@
      *             of "Additional Subtype" may be completely dropped in a future version of Android.
      */
     @Deprecated
-    public void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) {
+    public void setAdditionalInputMethodSubtypes(@NonNull String imiId,
+            @NonNull InputMethodSubtype[] subtypes) {
         mServiceInvoker.setAdditionalInputMethodSubtypes(imiId, subtypes);
     }
 
+    @Nullable
     public InputMethodSubtype getLastInputMethodSubtype() {
         return mServiceInvoker.getLastInputMethodSubtype();
     }
@@ -3485,7 +3528,7 @@
         return mDisplayId;
     }
 
-    void doDump(FileDescriptor fd, PrintWriter fout, String[] args) {
+    private void doDump(FileDescriptor fd, PrintWriter fout, String[] args) {
         if (processDump(fd, args)) {
             return;
         }
@@ -3495,7 +3538,7 @@
         p.println("  mFallbackInputConnection=" + mFallbackInputConnection);
         p.println("  mActive=" + mActive
                 + " mRestartOnNextWindowFocus=" + mRestartOnNextWindowFocus
-                + " mBindSequence=" + mBindSequence
+                + " mBindSequence=" + getBindSequenceLocked()
                 + " mCurImeId=" + getImeIdLocked());
         p.println("  mFullscreenMode=" + mFullscreenMode);
         if (isImeSessionAvailableLocked()) {
@@ -3594,11 +3637,17 @@
         @Nullable
         final String mImeId;
 
+        /**
+         * Sequence number of this binding, as returned by the server.
+         */
+        final int mBindSequence;
+
         BindState(@NonNull InputBindResult inputBindResult) {
             mImeSession = IInputMethodSessionInvoker.createOrNull(inputBindResult.method);
             mIsInputMethodSuppressingSpellChecker =
                     inputBindResult.isInputMethodSuppressingSpellChecker;
             mImeId = inputBindResult.id;
+            mBindSequence = inputBindResult.sequence;
         }
     }
 
@@ -3612,6 +3661,11 @@
         return mCurBindState != null ? mCurBindState.mImeId : null;
     }
 
+    @GuardedBy("mH")
+    private int getBindSequenceLocked() {
+        return mCurBindState != null ? mCurBindState.mBindSequence : -1;
+    }
+
     private static String dumpViewInfo(@Nullable final View view) {
         if (view == null) {
             return "null";
diff --git a/core/java/android/view/selectiontoolbar/ShowInfo.java b/core/java/android/view/selectiontoolbar/ShowInfo.java
index 594b6bc..d9adef2 100644
--- a/core/java/android/view/selectiontoolbar/ShowInfo.java
+++ b/core/java/android/view/selectiontoolbar/ShowInfo.java
@@ -284,7 +284,7 @@
         boolean layoutRequired = (flg & 0x2) != 0;
         long widgetToken = in.readLong();
         List<ToolbarMenuItem> menuItems = new java.util.ArrayList<>();
-        in.readParcelableList(menuItems, ToolbarMenuItem.class.getClassLoader());
+        in.readParcelableList(menuItems, ToolbarMenuItem.class.getClassLoader(), android.view.selectiontoolbar.ToolbarMenuItem.class);
         Rect contentRect = (Rect) in.readTypedObject(Rect.CREATOR);
         int suggestedWidth = in.readInt();
         Rect viewPortOnScreen = (Rect) in.readTypedObject(Rect.CREATOR);
diff --git a/core/java/android/view/textclassifier/ExtrasUtils.java b/core/java/android/view/textclassifier/ExtrasUtils.java
index 9e2b642..ecb838c 100644
--- a/core/java/android/view/textclassifier/ExtrasUtils.java
+++ b/core/java/android/view/textclassifier/ExtrasUtils.java
@@ -58,7 +58,7 @@
      */
     @Nullable
     public static Intent getActionIntent(Bundle container) {
-        return container.getParcelable(ACTION_INTENT);
+        return container.getParcelable(ACTION_INTENT, android.content.Intent.class);
     }
 
     /**
@@ -69,7 +69,7 @@
         if (classification == null) {
             return null;
         }
-        return classification.getExtras().getParcelableArrayList(ACTIONS_INTENTS);
+        return classification.getExtras().getParcelableArrayList(ACTIONS_INTENTS, android.content.Intent.class);
     }
 
     /**
diff --git a/core/java/android/view/translation/TranslationManager.java b/core/java/android/view/translation/TranslationManager.java
index db1c606..55c0726 100644
--- a/core/java/android/view/translation/TranslationManager.java
+++ b/core/java/android/view/translation/TranslationManager.java
@@ -246,7 +246,7 @@
                 return Collections.emptySet();
             }
             ParceledListSlice<TranslationCapability> listSlice =
-                    result.bundle.getParcelable(EXTRA_CAPABILITIES);
+                    result.bundle.getParcelable(EXTRA_CAPABILITIES, android.content.pm.ParceledListSlice.class);
             ArraySet<TranslationCapability> capabilities =
                     new ArraySet<>(listSlice == null ? null : listSlice.getList());
             return capabilities;
@@ -466,7 +466,7 @@
 
         private void onTranslationCapabilityUpdate(Bundle bundle) {
             TranslationCapability capability =
-                    (TranslationCapability) bundle.getParcelable(EXTRA_CAPABILITIES);
+                    (TranslationCapability) bundle.getParcelable(EXTRA_CAPABILITIES, android.view.translation.TranslationCapability.class);
             mListener.accept(capability);
         }
     }
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index 872e65a..07dfce7 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -61,22 +61,32 @@
 import com.android.internal.R;
 
 /**
- * A Switch is a two-state toggle switch widget that can select between two
- * options. The user may drag the "thumb" back and forth to choose the selected option,
- * or simply tap to toggle as if it were a checkbox. The {@link #setText(CharSequence) text}
- * property controls the text displayed in the label for the switch, whereas the
- * {@link #setTextOff(CharSequence) off} and {@link #setTextOn(CharSequence) on} text
- * controls the text on the thumb. Similarly, the
- * {@link #setTextAppearance(android.content.Context, int) textAppearance} and the related
- * setTypeface() methods control the typeface and style of label text, whereas the
- * {@link #setSwitchTextAppearance(android.content.Context, int) switchTextAppearance} and
- * the related setSwitchTypeface() methods control that of the thumb.
+ * A Switch is a two-state toggle widget. Users can drag the switch "thumb" back
+ * and forth to select either of two options or simply tap the switch to toggle
+ * between options.
  *
- * <p>{@link androidx.recyclerview.widget.RecyclerView} is a version of
- * the Switch widget which runs on devices back to API 7.</p>
+ * <p>The {@link #setText(CharSequence) text} property controls
+ * the text of the switch label. The {@link #setTextOn(CharSequence) textOn} and
+ * {@link #setTextOff(CharSequence) textOff} properties control the text of the
+ * thumb. The {@link #setTextAppearance(int) textAppearance} property and the
+ * related {@link #setTypeface(android.graphics.Typeface) setTypeface()} methods
+ * control the typeface and style of the switch label. The
+ * {@link #setSwitchTextAppearance(android.content.Context, int)
+ * switchTextAppearance} property and the related
+ * {@link #setSwitchTypeface(android.graphics.Typeface) setSwitchTypeface()}
+ * methods control the typeface and style of the thumb text.</p>
  *
- * <p>See the <a href="{@docRoot}guide/topics/ui/controls/togglebutton.html">Toggle Buttons</a>
- * guide.</p>
+ * <p class="note"><b>Note:</b> The thumb text is displayed only if the
+ * <a href="{@docRoot}reference/android/widget/Switch#attr_android:showText">
+ * <code>showText</code></a> attribute is set to {@code true}. See also
+ * {@link #setShowText(boolean)} and {@link #getShowText()}.</p>
+ *
+ * <p>{@link androidx.appcompat.widget.SwitchCompat} provides backward
+ * compatibility down to Android 4.0 (API level 14).</p>
+ *
+ * <p>For more information, see the
+ * <a href="{@docRoot}guide/topics/ui/controls/togglebutton.html">
+ * Toggle Buttons</a> guide.</p>
  *
  * @attr ref android.R.styleable#Switch_textOn
  * @attr ref android.R.styleable#Switch_textOff
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 83d7717..b7bb091 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -6456,9 +6456,8 @@
     public void setText(CharSequence text, BufferType type) {
         setText(text, type, true, 0);
 
-        if (mCharWrapper != null) {
-            mCharWrapper.mChars = null;
-        }
+        // drop any potential mCharWrappper leaks
+        mCharWrapper = null;
     }
 
     @UnsupportedAppUsage
@@ -6672,11 +6671,14 @@
      * since the TextView has no way to know that the text
      * has changed and that it needs to invalidate and re-layout.
      *
+     * @throws NullPointerException if text is null
+     * @throws IndexOutOfBoundsException if start or start+len are not in 0 to text.length
+     *
      * @param text char array to be displayed
      * @param start start index in the char array
      * @param len length of char count after {@code start}
      */
-    public final void setText(char[] text, int start, int len) {
+    public final void setText(@NonNull char[] text, int start, int len) {
         int oldlen = 0;
 
         if (start < 0 || len < 0 || start + len > text.length) {
@@ -13942,16 +13944,17 @@
     }
 
     private static class CharWrapper implements CharSequence, GetChars, GraphicsOperations {
+        @NonNull
         private char[] mChars;
         private int mStart, mLength;
 
-        public CharWrapper(char[] chars, int start, int len) {
+        CharWrapper(@NonNull char[] chars, int start, int len) {
             mChars = chars;
             mStart = start;
             mLength = len;
         }
 
-        /* package */ void set(char[] chars, int start, int len) {
+        /* package */ void set(@NonNull char[] chars, int start, int len) {
             mChars = chars;
             mStart = start;
             mLength = len;
diff --git a/core/java/android/window/ImeOnBackInvokedDispatcher.java b/core/java/android/window/ImeOnBackInvokedDispatcher.java
index 5924844..f1a052b 100644
--- a/core/java/android/window/ImeOnBackInvokedDispatcher.java
+++ b/core/java/android/window/ImeOnBackInvokedDispatcher.java
@@ -81,8 +81,10 @@
             @OnBackInvokedDispatcher.Priority int priority,
             @NonNull OnBackInvokedCallback callback) {
         final Bundle bundle = new Bundle();
+        // Always invoke back for ime without checking the window focus.
         final IOnBackInvokedCallback iCallback =
-                new WindowOnBackInvokedDispatcher.OnBackInvokedCallbackWrapper(callback);
+                new WindowOnBackInvokedDispatcher.OnBackInvokedCallbackWrapper(callback,
+                        () -> true);
         bundle.putBinder(RESULT_KEY_CALLBACK, iCallback.asBinder());
         bundle.putInt(RESULT_KEY_PRIORITY, priority);
         bundle.putInt(RESULT_KEY_ID, callback.hashCode());
diff --git a/core/java/android/window/TaskFragmentOrganizer.java b/core/java/android/window/TaskFragmentOrganizer.java
index 2ef49c3..68c934f 100644
--- a/core/java/android/window/TaskFragmentOrganizer.java
+++ b/core/java/android/window/TaskFragmentOrganizer.java
@@ -220,7 +220,7 @@
                 @NonNull IBinder errorCallbackToken, @NonNull Bundle exceptionBundle) {
             mExecutor.execute(() -> TaskFragmentOrganizer.this.onTaskFragmentError(
                     errorCallbackToken,
-                    (Throwable) exceptionBundle.getSerializable(KEY_ERROR_CALLBACK_EXCEPTION)));
+                    (Throwable) exceptionBundle.getSerializable(KEY_ERROR_CALLBACK_EXCEPTION, java.lang.Throwable.class)));
         }
 
         @Override
diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java
index c81184f..1f3841a 100644
--- a/core/java/android/window/TransitionInfo.java
+++ b/core/java/android/window/TransitionInfo.java
@@ -110,8 +110,11 @@
     /** The container is an input-method window. */
     public static final int FLAG_IS_INPUT_METHOD = 1 << 8;
 
+    /** The container is ActivityEmbedding embedded. */
+    public static final int FLAG_IS_EMBEDDED = 1 << 9;
+
     /** The first unused bit. This can be used by remotes to attach custom flags to this change. */
-    public static final int FLAG_FIRST_CUSTOM = 1 << 9;
+    public static final int FLAG_FIRST_CUSTOM = 1 << 10;
 
     /** @hide */
     @IntDef(prefix = { "FLAG_" }, value = {
@@ -125,6 +128,7 @@
             FLAG_OCCLUDES_KEYGUARD,
             FLAG_DISPLAY_HAS_ALERT_WINDOWS,
             FLAG_IS_INPUT_METHOD,
+            FLAG_IS_EMBEDDED,
             FLAG_FIRST_CUSTOM
     })
     public @interface ChangeFlags {}
@@ -325,6 +329,9 @@
         if ((flags & FLAG_DISPLAY_HAS_ALERT_WINDOWS) != 0) {
             sb.append((sb.length() == 0 ? "" : "|") + "DISPLAY_HAS_ALERT_WINDOWS");
         }
+        if ((flags & FLAG_IS_EMBEDDED) != 0) {
+            sb.append((sb.length() == 0 ? "" : "|") + "IS_EMBEDDED");
+        }
         if ((flags & FLAG_FIRST_CUSTOM) != 0) {
             sb.append((sb.length() == 0 ? "" : "|") + "FIRST_CUSTOM");
         }
diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java
index 633d879..5a0d11d 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -348,8 +348,10 @@
      * @param currentParent of the tasks to perform the operation no.
      *                      {@code null} will perform the operation on the display.
      * @param newParent for the tasks. {@code null} will perform the operation on the display.
-     * @param windowingModes of the tasks to reparent.
-     * @param activityTypes of the tasks to reparent.
+     * @param windowingModes of the tasks to reparent. {@code null} ignore this attribute when
+     *                       perform the operation.
+     * @param activityTypes of the tasks to reparent.  {@code null} ignore this attribute when
+     *                      perform the operation.
      * @param onTop When {@code true}, the child goes to the top of parent; otherwise it goes to
      *              the bottom.
      */
diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java
index d147524d..02c5ebc 100644
--- a/core/java/android/window/WindowOnBackInvokedDispatcher.java
+++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java
@@ -32,6 +32,7 @@
 import java.util.HashMap;
 import java.util.Objects;
 import java.util.TreeMap;
+import java.util.function.Supplier;
 
 /**
  * Provides window based implementation of {@link OnBackInvokedDispatcher}.
@@ -64,6 +65,7 @@
     private final TreeMap<Integer, ArrayList<OnBackInvokedCallback>>
             mOnBackInvokedCallbacks = new TreeMap<>();
     private final Checker mChecker;
+    private boolean mHasFocus;
 
     public WindowOnBackInvokedDispatcher(boolean applicationCallBackEnabled) {
         mChecker = new Checker(applicationCallBackEnabled);
@@ -189,7 +191,7 @@
                                     .ImeOnBackInvokedCallback
                                 ? ((ImeOnBackInvokedDispatcher.ImeOnBackInvokedCallback)
                                         callback).getIOnBackInvokedCallback()
-                                : new OnBackInvokedCallbackWrapper(callback);
+                                : new OnBackInvokedCallbackWrapper(callback, this::hasFocus);
                 callbackInfo = new OnBackInvokedCallbackInfo(iCallback, priority);
             }
             mWindowSession.setOnBackInvokedCallbackInfo(mWindow, callbackInfo);
@@ -198,6 +200,17 @@
         }
     }
 
+    /**
+     * Called when window focus changed.
+     */
+    public void onWindowFocusChanged(boolean hasFocus) {
+        mHasFocus = hasFocus;
+    }
+
+    private boolean hasFocus() {
+        return mHasFocus;
+    }
+
     public OnBackInvokedCallback getTopCallback() {
         if (mAllCallbacks.isEmpty()) {
             return null;
@@ -221,9 +234,11 @@
 
     static class OnBackInvokedCallbackWrapper extends IOnBackInvokedCallback.Stub {
         private final WeakReference<OnBackInvokedCallback> mCallback;
-
-        OnBackInvokedCallbackWrapper(@NonNull OnBackInvokedCallback callback) {
+        private final Supplier<Boolean> mHasFocus;
+        OnBackInvokedCallbackWrapper(@NonNull OnBackInvokedCallback callback,
+                @NonNull Supplier<Boolean> hasFocus) {
             mCallback = new WeakReference<>(callback);
+            mHasFocus = hasFocus;
         }
 
         @Override
@@ -263,7 +278,10 @@
                 if (callback == null) {
                     return;
                 }
-
+                if (!mHasFocus.get()) {
+                    Log.w(TAG, "Skip back invoke due to current focus has lost.");
+                    return;
+                }
                 callback.onBackInvoked();
             });
         }
diff --git a/core/java/com/android/internal/app/BlockedAppStreamingActivity.java b/core/java/com/android/internal/app/BlockedAppStreamingActivity.java
index ca111a4..d35f665 100644
--- a/core/java/com/android/internal/app/BlockedAppStreamingActivity.java
+++ b/core/java/com/android/internal/app/BlockedAppStreamingActivity.java
@@ -44,7 +44,7 @@
 
         Intent intent = getIntent();
         CharSequence appLabel = null;
-        ActivityInfo activityInfo = intent.getParcelableExtra(EXTRA_BLOCKED_ACTIVITY_INFO);
+        ActivityInfo activityInfo = intent.getParcelableExtra(EXTRA_BLOCKED_ACTIVITY_INFO, android.content.pm.ActivityInfo.class);
         if (activityInfo != null) {
             appLabel = activityInfo.loadLabel(getPackageManager());
         }
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 819a8c5..ff1afdd 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -30,6 +30,7 @@
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.ActivityManager;
+import android.app.ActivityOptions;
 import android.app.SharedElementCallback;
 import android.app.prediction.AppPredictionContext;
 import android.app.prediction.AppPredictionManager;
@@ -101,7 +102,10 @@
 import android.view.ViewTreeObserver;
 import android.view.WindowInsets;
 import android.view.animation.AccelerateInterpolator;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
 import android.view.animation.DecelerateInterpolator;
+import android.view.animation.LinearInterpolator;
 import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.Space;
@@ -197,6 +201,8 @@
     private static final String PLURALS_COUNT = "count";
     private static final String PLURALS_FILE_NAME = "file_name";
 
+    private static final String IMAGE_EDITOR_SHARED_ELEMENT = "screenshot_preview_image";
+
     private boolean mIsAppPredictorComponentAvailable;
     private Map<ChooserTarget, AppTarget> mDirectShareAppTargetCache;
     private Map<ChooserTarget, ShortcutInfo> mDirectShareShortcutInfoCache;
@@ -250,6 +256,11 @@
 
     private static final int DEFAULT_LIST_VIEW_UPDATE_DELAY_MS = 125;
 
+    private static final int URI_PERMISSION_INTENT_FLAGS = Intent.FLAG_GRANT_READ_URI_PERMISSION
+            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+            | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
+            | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION;
+
     @VisibleForTesting
     int mListViewUpdateDelayMs = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
             SystemUiDeviceConfigFlags.SHARESHEET_LIST_VIEW_UPDATE_DELAY,
@@ -305,6 +316,8 @@
 
     private boolean mRemoveSharedElements = false;
 
+    private View mContentView = null;
+
     private class ContentPreviewCoordinator {
         private static final int IMAGE_FADE_IN_MILLIS = 150;
         private static final int IMAGE_LOAD_TIMEOUT = 1;
@@ -607,9 +620,9 @@
         mReferrerFillInIntent = new Intent().putExtra(Intent.EXTRA_REFERRER, getReferrer());
 
         mChosenComponentSender = intent.getParcelableExtra(
-                Intent.EXTRA_CHOSEN_COMPONENT_INTENT_SENDER);
+                Intent.EXTRA_CHOSEN_COMPONENT_INTENT_SENDER, android.content.IntentSender.class);
         mRefinementIntentSender = intent.getParcelableExtra(
-                Intent.EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER);
+                Intent.EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER, android.content.IntentSender.class);
         setSafeForwardingMode(true);
 
         mPinnedSharedPrefs = getPinnedSharedPrefs(this);
@@ -943,7 +956,7 @@
             ClipData clipData = null;
             if (Intent.ACTION_SEND.equals(action)) {
                 String extraText = targetIntent.getStringExtra(Intent.EXTRA_TEXT);
-                Uri extraStream = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM);
+                Uri extraStream = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM, android.net.Uri.class);
 
                 if (extraText != null) {
                     clipData = ClipData.newPlainText(null, extraText);
@@ -955,7 +968,7 @@
                 }
             } else if (Intent.ACTION_SEND_MULTIPLE.equals(action)) {
                 final ArrayList<Uri> streams = targetIntent.getParcelableArrayListExtra(
-                        Intent.EXTRA_STREAM);
+                        Intent.EXTRA_STREAM, android.net.Uri.class);
                 clipData = ClipData.newUri(getContentResolver(), null, streams.get(0));
                 for (int i = 1; i < streams.size(); i++) {
                     clipData.addItem(getContentResolver(), new ClipData.Item(streams.get(i)));
@@ -990,6 +1003,7 @@
     protected void onResume() {
         super.onResume();
         Log.d(TAG, "onResume: " + getComponentName().flattenToShortString());
+        maybeCancelFinishAnimation();
     }
 
     @Override
@@ -1085,12 +1099,16 @@
         final ComponentName cn = getEditSharingComponent();
 
         final Intent resolveIntent = new Intent(originalIntent);
+        // Retain only URI permission grant flags if present. Other flags may prevent the scene
+        // transition animation from running (i.e FLAG_ACTIVITY_NO_ANIMATION,
+        // FLAG_ACTIVITY_NEW_TASK, FLAG_ACTIVITY_NEW_DOCUMENT) but also not needed.
+        resolveIntent.setFlags(originalIntent.getFlags() & URI_PERMISSION_INTENT_FLAGS);
         resolveIntent.setComponent(cn);
         resolveIntent.setAction(Intent.ACTION_EDIT);
         String originalAction = originalIntent.getAction();
         if (Intent.ACTION_SEND.equals(originalAction)) {
             if (resolveIntent.getData() == null) {
-                Uri uri = resolveIntent.getParcelableExtra(Intent.EXTRA_STREAM);
+                Uri uri = resolveIntent.getParcelableExtra(Intent.EXTRA_STREAM, android.net.Uri.class);
                 if (uri != null) {
                     String mimeType = getContentResolver().getType(uri);
                     resolveIntent.setDataAndType(uri, mimeType);
@@ -1114,7 +1132,6 @@
         return dri;
     }
 
-
     @VisibleForTesting
     protected TargetInfo getNearbySharingTarget(Intent originalIntent) {
         final ComponentName cn = getNearbySharingComponent();
@@ -1217,15 +1234,30 @@
                             "",
                             -1,
                             false);
+                    View firstImgView = getFirstVisibleImgPreviewView();
                     // Action bar is user-independent, always start as primary
-                    safelyStartActivityAsUser(ti, getPersonalProfileUserHandle());
-                    finish();
+                    if (firstImgView == null) {
+                        safelyStartActivityAsUser(ti, getPersonalProfileUserHandle());
+                        finish();
+                    } else {
+                        ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(
+                                this, firstImgView, IMAGE_EDITOR_SHARED_ELEMENT);
+                        safelyStartActivityAsUser(
+                                ti, getPersonalProfileUserHandle(), options.toBundle());
+                        startFinishAnimation();
+                    }
                 }
         );
         b.setId(R.id.chooser_edit_button);
         return b;
     }
 
+    @Nullable
+    private View getFirstVisibleImgPreviewView() {
+        View firstImage = findViewById(R.id.content_preview_image_1_large);
+        return firstImage != null && firstImage.isVisibleToUser() ? firstImage : null;
+    }
+
     private void addActionButton(ViewGroup parent, Button b) {
         if (b == null) return;
         final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(
@@ -1335,14 +1367,14 @@
 
         String action = targetIntent.getAction();
         if (Intent.ACTION_SEND.equals(action)) {
-            Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM);
+            Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM, android.net.Uri.class);
             imagePreview.findViewById(R.id.content_preview_image_1_large)
                     .setTransitionName(ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME);
             mPreviewCoord.loadUriIntoView(R.id.content_preview_image_1_large, uri, 0);
         } else {
             ContentResolver resolver = getContentResolver();
 
-            List<Uri> uris = targetIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
+            List<Uri> uris = targetIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM, android.net.Uri.class);
             List<Uri> imageUris = new ArrayList<>();
             for (Uri uri : uris) {
                 if (isImageType(resolver.getType(uri))) {
@@ -1454,10 +1486,10 @@
 
         String action = targetIntent.getAction();
         if (Intent.ACTION_SEND.equals(action)) {
-            Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM);
+            Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM, android.net.Uri.class);
             loadFileUriIntoView(uri, contentPreviewLayout);
         } else {
-            List<Uri> uris = targetIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
+            List<Uri> uris = targetIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM, android.net.Uri.class);
             int uriCount = uris.size();
 
             if (uriCount == 0) {
@@ -1541,10 +1573,10 @@
     private int findPreferredContentPreview(Intent targetIntent, ContentResolver resolver) {
         String action = targetIntent.getAction();
         if (Intent.ACTION_SEND.equals(action)) {
-            Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM);
+            Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM, android.net.Uri.class);
             return findPreferredContentPreview(uri, resolver);
         } else if (Intent.ACTION_SEND_MULTIPLE.equals(action)) {
-            List<Uri> uris = targetIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
+            List<Uri> uris = targetIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM, android.net.Uri.class);
             if (uris == null || uris.isEmpty()) {
                 return CONTENT_PREVIEW_TEXT;
             }
@@ -1573,6 +1605,14 @@
     }
 
     @Override
+    protected void onStop() {
+        super.onStop();
+        if (maybeCancelFinishAnimation()) {
+            finish();
+        }
+    }
+
+    @Override
     protected void onDestroy() {
         super.onDestroy();
 
@@ -1914,12 +1954,12 @@
             IntentFilter intentFilter = new IntentFilter(intent.getAction(), intent.getType());
             List<Uri> contentUris = new ArrayList<>();
             if (Intent.ACTION_SEND.equals(intent.getAction())) {
-                Uri uri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
+                Uri uri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM, android.net.Uri.class);
                 if (uri != null) {
                     contentUris.add(uri);
                 }
             } else {
-                List<Uri> uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
+                List<Uri> uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM, android.net.Uri.class);
                 if (uris != null) {
                     contentUris.addAll(uris);
                 }
@@ -2900,6 +2940,30 @@
                 .setSubtype(previewType));
     }
 
+    private void startFinishAnimation() {
+        View rootView = findRootView();
+        rootView.startAnimation(new FinishAnimation(this, rootView));
+    }
+
+    private boolean maybeCancelFinishAnimation() {
+        View rootView = findRootView();
+        Animation animation = rootView.getAnimation();
+        if (animation instanceof FinishAnimation) {
+            boolean hasEnded = animation.hasEnded();
+            animation.cancel();
+            rootView.clearAnimation();
+            return !hasEnded;
+        }
+        return false;
+    }
+
+    private View findRootView() {
+        if (mContentView == null) {
+            mContentView = findViewById(android.R.id.content);
+        }
+        return mContentView;
+    }
+
     abstract static class ViewHolderBase extends RecyclerView.ViewHolder {
         private int mViewType;
 
@@ -4000,6 +4064,66 @@
         }
     }
 
+    /**
+     * Used in combination with the scene transition when launching the image editor
+     */
+    private static class FinishAnimation extends AlphaAnimation implements
+            Animation.AnimationListener {
+        private Activity mActivity;
+        private View mRootView;
+        private final float mFromAlpha;
+
+        FinishAnimation(Activity activity, View rootView) {
+            super(rootView.getAlpha(), 0.0f);
+            mActivity = activity;
+            mRootView = rootView;
+            mFromAlpha = rootView.getAlpha();
+            setInterpolator(new LinearInterpolator());
+            long duration = activity.getWindow().getTransitionBackgroundFadeDuration();
+            setDuration(duration);
+            // The scene transition animation looks better when it's not overlapped with this
+            // fade-out animation thus the delay.
+            // It is most likely that the image editor will cause this activity to stop and this
+            // animation will be cancelled in the background without running (i.e. we'll animate
+            // only when this activity remains partially visible after the image editor launch).
+            setStartOffset(duration);
+            super.setAnimationListener(this);
+        }
+
+        @Override
+        public void setAnimationListener(AnimationListener listener) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void cancel() {
+            mRootView.setAlpha(mFromAlpha);
+            cleanup();
+            super.cancel();
+        }
+
+        @Override
+        public void onAnimationStart(Animation animation) {
+        }
+
+        @Override
+        public void onAnimationEnd(Animation animation) {
+            if (mActivity != null) {
+                mActivity.finish();
+                cleanup();
+            }
+        }
+
+        @Override
+        public void onAnimationRepeat(Animation animation) {
+        }
+
+        private void cleanup() {
+            mActivity = null;
+            mRootView = null;
+        }
+    }
+
     @Override
     protected void maybeLogProfileChange() {
         getChooserActivityLogger().logShareheetProfileChanged();
diff --git a/core/java/com/android/internal/app/ConfirmUserCreationActivity.java b/core/java/com/android/internal/app/ConfirmUserCreationActivity.java
index ee4d46d..8833512 100644
--- a/core/java/com/android/internal/app/ConfirmUserCreationActivity.java
+++ b/core/java/com/android/internal/app/ConfirmUserCreationActivity.java
@@ -62,7 +62,7 @@
         mAccountName = intent.getStringExtra(UserManager.EXTRA_USER_ACCOUNT_NAME);
         mAccountType = intent.getStringExtra(UserManager.EXTRA_USER_ACCOUNT_TYPE);
         mAccountOptions = (PersistableBundle)
-                intent.getParcelableExtra(UserManager.EXTRA_USER_ACCOUNT_OPTIONS);
+                intent.getParcelableExtra(UserManager.EXTRA_USER_ACCOUNT_OPTIONS, android.os.PersistableBundle.class);
 
         mUserManager = getSystemService(UserManager.class);
 
diff --git a/core/java/com/android/internal/app/HarmfulAppWarningActivity.java b/core/java/com/android/internal/app/HarmfulAppWarningActivity.java
index 33209e1..c19196f 100644
--- a/core/java/com/android/internal/app/HarmfulAppWarningActivity.java
+++ b/core/java/com/android/internal/app/HarmfulAppWarningActivity.java
@@ -54,7 +54,7 @@
         getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
         final Intent intent = getIntent();
         mPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
-        mTarget = intent.getParcelableExtra(Intent.EXTRA_INTENT);
+        mTarget = intent.getParcelableExtra(Intent.EXTRA_INTENT, android.content.IntentSender.class);
         mHarmfulAppWarning = intent.getStringExtra(EXTRA_HARMFUL_APP_WARNING);
 
         if (mPackageName == null || mTarget == null || mHarmfulAppWarning == null) {
@@ -107,7 +107,7 @@
             case DialogInterface.BUTTON_NEGATIVE:
                 getPackageManager().setHarmfulAppWarning(mPackageName, null /*warning*/);
 
-                final IntentSender target = getIntent().getParcelableExtra(Intent.EXTRA_INTENT);
+                final IntentSender target = getIntent().getParcelableExtra(Intent.EXTRA_INTENT, android.content.IntentSender.class);
                 try {
                     startIntentSenderForResult(target, -1 /*requestCode*/, null /*fillInIntent*/,
                             0 /*flagsMask*/, 0 /*flagsValue*/, 0 /*extraFlags*/);
diff --git a/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java b/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java
index 0152387..801c934 100644
--- a/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java
+++ b/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java
@@ -66,7 +66,7 @@
         
         requestWindowFeature(Window.FEATURE_NO_TITLE);
         
-        mStartIntent = (IntentSender)getIntent().getParcelableExtra(KEY_INTENT);
+        mStartIntent = (IntentSender)getIntent().getParcelableExtra(KEY_INTENT, android.content.IntentSender.class);
         mHasResult = getIntent().getBooleanExtra(KEY_HAS_RESULT, false);
         mCurApp = getIntent().getStringExtra(KEY_CUR_APP);
         mCurTask = getIntent().getIntExtra(KEY_CUR_TASK, 0);
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index 681693b..4b01357 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -129,6 +129,7 @@
      * @param activityToken optional token of activity that needs to be on top
      * @RequiresPermission Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE
      */
+    @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
     boolean showSessionForActiveService(in Bundle args, int sourceFlags,
             IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken);
 
@@ -136,6 +137,7 @@
      * Hides the session from the active service, if it is showing.
      * @RequiresPermission Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE
      */
+    @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
     void hideCurrentSession();
 
     /**
@@ -143,12 +145,14 @@
      * be called if {@link #activeServiceSupportsLaunchFromKeyguard()} returns true.
      * @RequiresPermission Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE
      */
+    @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
     void launchVoiceAssistFromKeyguard();
 
     /**
      * Indicates whether there is a voice session running (but not necessarily showing).
      * @RequiresPermission Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE
      */
+    @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
     boolean isSessionRunning();
 
     /**
@@ -156,6 +160,7 @@
      * assist gesture.
      * @RequiresPermission Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE
      */
+    @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
     boolean activeServiceSupportsAssist();
 
     /**
@@ -163,18 +168,21 @@
      * from the lockscreen.
      * @RequiresPermission Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE
      */
+    @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
     boolean activeServiceSupportsLaunchFromKeyguard();
 
     /**
      * Called when the lockscreen got shown.
      * @RequiresPermission Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE
      */
+    @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
     void onLockscreenShown();
 
     /**
      * Register a voice interaction listener.
      * @RequiresPermission Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE
      */
+    @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
     void registerVoiceInteractionSessionListener(IVoiceInteractionSessionListener listener);
 
     /**
@@ -182,6 +190,7 @@
      * Returns all supported voice actions.
      * @RequiresPermission Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE
      */
+    @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
     void getActiveServiceSupportedActions(in List<String> voiceActions,
      in IVoiceActionCheckCallback callback);
 
@@ -214,6 +223,7 @@
      * NOTE: it's only effective when the service itself is available / enabled in the device, so
      * calling setDisable(false) would be a no-op when it isn't.
      */
+    @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
     void setDisabled(boolean disabled);
 
     /**
@@ -244,6 +254,7 @@
      * @param callback Use this to report {@link HotwordDetectionService} status.
      * @param detectorType Indicate which detector is used.
      */
+    @EnforcePermission("MANAGE_HOTWORD_DETECTION")
     void updateState(
             in Identity originatorIdentity,
             in PersistableBundle options,
@@ -256,6 +267,7 @@
      */
     void shutdownHotwordDetectionService();
 
+    @EnforcePermission(allOf={"RECORD_AUDIO", "CAPTURE_AUDIO_HOTWORD"})
     void startListeningFromMic(
         in AudioFormat audioFormat,
         in IMicrophoneHotwordDetectionVoiceInteractionCallback callback);
@@ -271,6 +283,7 @@
     /**
      * Test API to simulate to trigger hardware recognition event for test.
      */
+    @EnforcePermission(allOf={"RECORD_AUDIO", "CAPTURE_AUDIO_HOTWORD"})
     void triggerHardwareRecognitionEventForTest(
             in SoundTrigger.KeyphraseRecognitionEvent event,
             in IHotwordRecognitionStatusCallback callback);
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 070d8ff..47b83be 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -224,7 +224,7 @@
         int selectedProfile = findSelectedProfile(className);
         sanitizeIntent(intentReceived);
         intentReceived.putExtra(EXTRA_SELECTED_PROFILE, selectedProfile);
-        Intent innerIntent = intentReceived.getParcelableExtra(Intent.EXTRA_INTENT);
+        Intent innerIntent = intentReceived.getParcelableExtra(Intent.EXTRA_INTENT, android.content.Intent.class);
         if (innerIntent == null) {
             Slog.wtf(TAG, "Cannot start a chooser intent with no extra " + Intent.EXTRA_INTENT);
             return;
diff --git a/core/java/com/android/internal/app/LaunchAfterAuthenticationActivity.java b/core/java/com/android/internal/app/LaunchAfterAuthenticationActivity.java
index 20a025a..c14d958 100644
--- a/core/java/com/android/internal/app/LaunchAfterAuthenticationActivity.java
+++ b/core/java/com/android/internal/app/LaunchAfterAuthenticationActivity.java
@@ -54,7 +54,7 @@
         super.onCreate(icicle);
 
         final IntentSender onSuccessIntent = getIntent().getParcelableExtra(
-                EXTRA_ON_SUCCESS_INTENT);
+                EXTRA_ON_SUCCESS_INTENT, android.content.IntentSender.class);
         requestDismissKeyguardIfNeeded(onSuccessIntent);
     }
 
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 40429c6..f67e785 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -500,7 +500,7 @@
         // this happens, we check for it here and set the current profile's tab.
         int selectedProfile = getCurrentProfile();
         UserHandle intentUser = getIntent().hasExtra(EXTRA_CALLING_USER)
-                ? getIntent().getParcelableExtra(EXTRA_CALLING_USER)
+                ? getIntent().getParcelableExtra(EXTRA_CALLING_USER, android.os.UserHandle.class)
                 : getUser();
         if (!getUser().equals(intentUser)) {
             if (getPersonalProfileUserHandle().equals(intentUser)) {
@@ -1314,7 +1314,7 @@
         StrictMode.disableDeathOnFileUriExposure();
         try {
             UserHandle currentUserHandle = mMultiProfilePagerAdapter.getCurrentUserHandle();
-            safelyStartActivityInternal(cti, currentUserHandle);
+            safelyStartActivityInternal(cti, currentUserHandle, null);
         } finally {
             StrictMode.enableDeathOnFileUriExposure();
         }
@@ -1327,18 +1327,23 @@
      */
     @VisibleForTesting
     public void safelyStartActivityAsUser(TargetInfo cti, UserHandle user) {
+        safelyStartActivityAsUser(cti, user, null);
+    }
+
+    protected void safelyStartActivityAsUser(
+            TargetInfo cti, UserHandle user, @Nullable Bundle options) {
         // We're dispatching intents that might be coming from legacy apps, so
         // don't kill ourselves.
         StrictMode.disableDeathOnFileUriExposure();
         try {
-            safelyStartActivityInternal(cti, user);
+            safelyStartActivityInternal(cti, user, options);
         } finally {
             StrictMode.enableDeathOnFileUriExposure();
         }
     }
 
-
-    private void safelyStartActivityInternal(TargetInfo cti, UserHandle user) {
+    private void safelyStartActivityInternal(
+            TargetInfo cti, UserHandle user, @Nullable Bundle options) {
         // If the target is suspended, the activity will not be successfully launched.
         // Do not unregister from package manager updates in this case
         if (!cti.isSuspended() && mRegistered) {
@@ -1356,14 +1361,14 @@
             Toast.makeText(this, mProfileSwitchMessage, Toast.LENGTH_LONG).show();
         }
         if (!mSafeForwardingMode) {
-            if (cti.startAsUser(this, null, user)) {
+            if (cti.startAsUser(this, options, user)) {
                 onActivityStarted(cti);
                 maybeLogCrossProfileTargetLaunch(cti, user);
             }
             return;
         }
         try {
-            if (cti.startAsCaller(this, null, user.getIdentifier())) {
+            if (cti.startAsCaller(this, options, user.getIdentifier())) {
                 onActivityStarted(cti);
                 maybeLogCrossProfileTargetLaunch(cti, user);
             }
diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java
index 2ed0f98..b32afb4 100644
--- a/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -265,6 +265,7 @@
             return mResolverListController.getResolversForIntent(
                             /* shouldGetResolvedFilter= */ true,
                             mResolverListCommunicator.shouldGetActivityMetadata(),
+                            mResolverListCommunicator.shouldGetOnlyDefaultActivities(),
                             mIntents);
         }
     }
@@ -416,8 +417,9 @@
                     if (ii == null) {
                         continue;
                     }
-                    ActivityInfo ai = ii.resolveActivityInfo(
-                            mPm, 0);
+                    // Because of AIDL bug, resolveActivityInfo can't accept subclasses of Intent.
+                    final Intent rii = (ii.getClass() == Intent.class) ? ii : new Intent(ii);
+                    ActivityInfo ai = rii.resolveActivityInfo(mPm, 0);
                     if (ai == null) {
                         Log.w(TAG, "No activity found for " + ii);
                         continue;
@@ -727,6 +729,7 @@
     protected List<ResolvedComponentInfo> getResolversForUser(UserHandle userHandle) {
         return mResolverListController.getResolversForIntentAsUser(true,
                 mResolverListCommunicator.shouldGetActivityMetadata(),
+                mResolverListCommunicator.shouldGetOnlyDefaultActivities(),
                 mIntents, userHandle);
     }
 
@@ -820,6 +823,12 @@
 
         boolean shouldGetActivityMetadata();
 
+        /**
+         * @return true to filter only apps that can handle
+         *     {@link android.content.Intent#CATEGORY_DEFAULT} intents
+         */
+        default boolean shouldGetOnlyDefaultActivities() { return true; };
+
         Intent getTargetIntent();
 
         void onHandlePackagesChanged(ResolverListAdapter listAdapter);
diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java
index 2757363..01dcf962 100644
--- a/core/java/com/android/internal/app/ResolverListController.java
+++ b/core/java/com/android/internal/app/ResolverListController.java
@@ -110,17 +110,19 @@
     public List<ResolverActivity.ResolvedComponentInfo> getResolversForIntent(
             boolean shouldGetResolvedFilter,
             boolean shouldGetActivityMetadata,
+            boolean shouldGetOnlyDefaultActivities,
             List<Intent> intents) {
         return getResolversForIntentAsUser(shouldGetResolvedFilter, shouldGetActivityMetadata,
-                intents, mUserHandle);
+                shouldGetOnlyDefaultActivities, intents, mUserHandle);
     }
 
     public List<ResolverActivity.ResolvedComponentInfo> getResolversForIntentAsUser(
             boolean shouldGetResolvedFilter,
             boolean shouldGetActivityMetadata,
+            boolean shouldGetOnlyDefaultActivities,
             List<Intent> intents,
             UserHandle userHandle) {
-        int baseFlags = PackageManager.MATCH_DEFAULT_ONLY
+        int baseFlags = (shouldGetOnlyDefaultActivities ? PackageManager.MATCH_DEFAULT_ONLY : 0)
                 | PackageManager.MATCH_DIRECT_BOOT_AWARE
                 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
                 | (shouldGetResolvedFilter ? PackageManager.GET_RESOLVED_FILTER : 0)
@@ -134,12 +136,15 @@
             int baseFlags) {
         List<ResolverActivity.ResolvedComponentInfo> resolvedComponents = null;
         for (int i = 0, N = intents.size(); i < N; i++) {
-            final Intent intent = intents.get(i);
+            Intent intent = intents.get(i);
             int flags = baseFlags;
             if (intent.isWebIntent()
                         || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) {
                 flags |= PackageManager.MATCH_INSTANT;
             }
+            // Because of AIDL bug, queryIntentActivitiesAsUser can't accept subclasses of Intent.
+            intent = (intent.getClass() == Intent.class) ? intent : new Intent(
+                    intent);
             final List<ResolveInfo> infos = mpm.queryIntentActivitiesAsUser(intent, flags,
                     userHandle);
             if (infos != null) {
diff --git a/core/java/com/android/internal/app/SuspendedAppActivity.java b/core/java/com/android/internal/app/SuspendedAppActivity.java
index ec224e5..0288137 100644
--- a/core/java/com/android/internal/app/SuspendedAppActivity.java
+++ b/core/java/com/android/internal/app/SuspendedAppActivity.java
@@ -219,8 +219,8 @@
         }
         mSuspendedPackage = intent.getStringExtra(EXTRA_SUSPENDED_PACKAGE);
         mSuspendingPackage = intent.getStringExtra(EXTRA_SUSPENDING_PACKAGE);
-        mSuppliedDialogInfo = intent.getParcelableExtra(EXTRA_DIALOG_INFO);
-        mOnUnsuspend = intent.getParcelableExtra(EXTRA_UNSUSPEND_INTENT);
+        mSuppliedDialogInfo = intent.getParcelableExtra(EXTRA_DIALOG_INFO, android.content.pm.SuspendDialogInfo.class);
+        mOnUnsuspend = intent.getParcelableExtra(EXTRA_UNSUSPEND_INTENT, android.content.IntentSender.class);
         if (mSuppliedDialogInfo != null) {
             try {
                 mSuspendingAppResources = createContextAsUser(
diff --git a/core/java/com/android/internal/app/UnlaunchableAppActivity.java b/core/java/com/android/internal/app/UnlaunchableAppActivity.java
index e56d92b..0776572 100644
--- a/core/java/com/android/internal/app/UnlaunchableAppActivity.java
+++ b/core/java/com/android/internal/app/UnlaunchableAppActivity.java
@@ -62,7 +62,7 @@
         Intent intent = getIntent();
         mReason = intent.getIntExtra(EXTRA_UNLAUNCHABLE_REASON, -1);
         mUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
-        mTarget = intent.getParcelableExtra(Intent.EXTRA_INTENT);
+        mTarget = intent.getParcelableExtra(Intent.EXTRA_INTENT, android.content.IntentSender.class);
 
         if (mUserId == UserHandle.USER_NULL) {
             Log.wtf(TAG, "Invalid user id: " + mUserId + ". Stopping.");
diff --git a/core/java/com/android/internal/graphics/fonts/IFontManager.aidl b/core/java/com/android/internal/graphics/fonts/IFontManager.aidl
index 87df5eb..512ace6 100644
--- a/core/java/com/android/internal/graphics/fonts/IFontManager.aidl
+++ b/core/java/com/android/internal/graphics/fonts/IFontManager.aidl
@@ -28,6 +28,7 @@
  * @hide
  */
 interface IFontManager {
+    @EnforcePermission("UPDATE_FONTS")
     FontConfig getFontConfig();
 
     int updateFontFamily(in List<FontUpdateRequest> request, int baseVersion);
diff --git a/core/java/com/android/internal/inputmethod/InputBindResult.java b/core/java/com/android/internal/inputmethod/InputBindResult.java
index 74c61d1..f1014971 100644
--- a/core/java/com/android/internal/inputmethod/InputBindResult.java
+++ b/core/java/com/android/internal/inputmethod/InputBindResult.java
@@ -184,7 +184,7 @@
     /**
      * The accessibility services.
      */
-    public SparseArray<IAccessibilityInputMethodSession> accessibilitySessions;
+    public final SparseArray<IAccessibilityInputMethodSession> accessibilitySessions;
 
     /**
      * The input channel used to send input events to this IME.
diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java
index 825b486..dbfa4d3 100644
--- a/core/java/com/android/internal/jank/FrameTracker.java
+++ b/core/java/com/android/internal/jank/FrameTracker.java
@@ -26,10 +26,12 @@
 
 import static com.android.internal.jank.InteractionJankMonitor.ACTION_SESSION_CANCEL;
 import static com.android.internal.jank.InteractionJankMonitor.ACTION_SESSION_END;
+import static com.android.internal.jank.InteractionJankMonitor.EXECUTOR_TASK_TIMEOUT;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UiThread;
 import android.graphics.HardwareRendererObserver;
 import android.os.Handler;
 import android.os.Trace;
@@ -85,8 +87,9 @@
     public @interface Reasons {
     }
 
+    @VisibleForTesting
+    public final InteractionJankMonitor mMonitor;
     private final HardwareRendererObserver mObserver;
-    private SurfaceControl mSurfaceControl;
     private final int mTraceThresholdMissedFrames;
     private final int mTraceThresholdFrameTimeMillis;
     private final ThreadedRendererWrapper mRendererWrapper;
@@ -99,17 +102,17 @@
     private final Handler mHandler;
     private final ChoreographerWrapper mChoreographer;
     private final StatsLogWrapper mStatsLog;
-    private final Object mLock = InteractionJankMonitor.getInstance().getLock();
     private final boolean mDeferMonitoring;
+    private final FrameTrackerListener mListener;
 
     @VisibleForTesting
     public final boolean mSurfaceOnly;
 
+    private SurfaceControl mSurfaceControl;
     private long mBeginVsyncId = INVALID_ID;
     private long mEndVsyncId = INVALID_ID;
     private boolean mMetricsFinalized;
     private boolean mCancelled = false;
-    private FrameTrackerListener mListener;
     private boolean mTracingStarted = false;
     private Runnable mWaitForFinishTimedOut;
 
@@ -142,16 +145,52 @@
             this.jankType = jankType;
             this.isFirstFrame = isFirstFrame;
         }
+
+        @Override
+        public String toString() {
+            StringBuilder str = new StringBuilder();
+            switch (jankType) {
+                case JANK_NONE:
+                    str.append("JANK_NONE");
+                    break;
+                case JANK_APP_DEADLINE_MISSED:
+                    str.append("JANK_APP_DEADLINE_MISSED");
+                    break;
+                case JANK_SURFACEFLINGER_DEADLINE_MISSED:
+                    str.append("JANK_SURFACEFLINGER_DEADLINE_MISSED");
+                    break;
+                case JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED:
+                    str.append("JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED");
+                    break;
+                case DISPLAY_HAL:
+                    str.append("DISPLAY_HAL");
+                    break;
+                case PREDICTION_ERROR:
+                    str.append("PREDICTION_ERROR");
+                    break;
+                case SURFACE_FLINGER_SCHEDULING:
+                    str.append("SURFACE_FLINGER_SCHEDULING");
+                    break;
+                default:
+                    str.append("UNKNOWN: ").append(jankType);
+                    break;
+            }
+            str.append(", ").append(frameVsyncId);
+            str.append(", ").append(totalDurationNanos);
+            return str.toString();
+        }
     }
 
-    public FrameTracker(@NonNull Session session, @NonNull Handler handler,
-            @Nullable ThreadedRendererWrapper renderer, @Nullable ViewRootWrapper viewRootWrapper,
+    public FrameTracker(@NonNull InteractionJankMonitor monitor, @NonNull Session session,
+            @NonNull Handler handler, @Nullable ThreadedRendererWrapper renderer,
+            @Nullable ViewRootWrapper viewRootWrapper,
             @NonNull SurfaceControlWrapper surfaceControlWrapper,
             @NonNull ChoreographerWrapper choreographer,
             @Nullable FrameMetricsWrapper metrics,
             @NonNull StatsLogWrapper statsLog,
             int traceThresholdMissedFrames, int traceThresholdFrameTimeMillis,
             @Nullable FrameTrackerListener listener, @NonNull Configuration config) {
+        mMonitor = monitor;
         mSurfaceOnly = config.isSurfaceOnly();
         mSession = session;
         mHandler = handler;
@@ -186,17 +225,15 @@
             mSurfaceChangedCallback = new ViewRootImpl.SurfaceChangedCallback() {
                 @Override
                 public void surfaceCreated(SurfaceControl.Transaction t) {
-                    synchronized (mLock) {
+                    getHandler().runWithScissors(() -> {
                         if (mSurfaceControl == null) {
                             mSurfaceControl = mViewRoot.getSurfaceControl();
                             if (mBeginVsyncId != INVALID_ID) {
-                                mSurfaceControlWrapper.addJankStatsListener(
-                                        FrameTracker.this, mSurfaceControl);
-                                markEvent("FT#deferMonitoring");
-                                postTraceStartMarker();
+                                // Previous begin invocation is not successfully, begin it again.
+                                begin();
                             }
                         }
-                    }
+                    }, EXECUTOR_TASK_TIMEOUT);
                 }
 
                 @Override
@@ -208,18 +245,16 @@
 
                     // Wait a while to give the system a chance for the remaining
                     // frames to arrive, then force finish the session.
-                    mHandler.postDelayed(() -> {
-                        synchronized (mLock) {
-                            if (DEBUG) {
-                                Log.d(TAG, "surfaceDestroyed: " + mSession.getName()
-                                        + ", finalized=" + mMetricsFinalized
-                                        + ", info=" + mJankInfos.size()
-                                        + ", vsync=" + mBeginVsyncId);
-                            }
-                            if (!mMetricsFinalized) {
-                                end(REASON_END_SURFACE_DESTROYED);
-                                finish();
-                            }
+                    getHandler().postDelayed(() -> {
+                        if (DEBUG) {
+                            Log.d(TAG, "surfaceDestroyed: " + mSession.getName()
+                                    + ", finalized=" + mMetricsFinalized
+                                    + ", info=" + mJankInfos.size()
+                                    + ", vsync=" + mBeginVsyncId);
+                        }
+                        if (!mMetricsFinalized) {
+                            end(REASON_END_SURFACE_DESTROYED);
+                            finish();
                         }
                     }, 50);
                 }
@@ -230,35 +265,42 @@
         }
     }
 
+    @VisibleForTesting
+    public Handler getHandler() {
+        return mHandler;
+    }
+
     /**
      * Begin a trace session of the CUJ.
      */
+    @UiThread
     public void begin() {
-        synchronized (mLock) {
-            final long currentVsync = mChoreographer.getVsyncId();
-            // In normal case, we should begin at the next frame,
-            // the id of the next frame is not simply increased by 1,
-            // but we can exclude the current frame at least.
+        final long currentVsync = mChoreographer.getVsyncId();
+        // In normal case, we should begin at the next frame,
+        // the id of the next frame is not simply increased by 1,
+        // but we can exclude the current frame at least.
+        if (mBeginVsyncId == INVALID_ID) {
             mBeginVsyncId = mDeferMonitoring ? currentVsync + 1 : currentVsync;
+        }
+        if (mSurfaceControl != null) {
             if (DEBUG) {
                 Log.d(TAG, "begin: " + mSession.getName() + ", begin=" + mBeginVsyncId
-                        + ", defer=" + mDeferMonitoring);
+                        + ", defer=" + mDeferMonitoring + ", current=" + currentVsync);
             }
-            if (mSurfaceControl != null) {
-                if (mDeferMonitoring) {
-                    markEvent("FT#deferMonitoring");
-                    // Normal case, we begin the instrument from the very beginning,
-                    // will exclude the first frame.
-                    postTraceStartMarker();
-                } else {
-                    // If we don't begin the instrument from the very beginning,
-                    // there is no need to skip the frame where the begin invocation happens.
-                    beginInternal();
-                }
-                mSurfaceControlWrapper.addJankStatsListener(this, mSurfaceControl);
+            if (mDeferMonitoring && currentVsync < mBeginVsyncId) {
+                markEvent("FT#deferMonitoring");
+                // Normal case, we begin the instrument from the very beginning,
+                // will exclude the first frame.
+                postTraceStartMarker(this::beginInternal);
+            } else {
+                // If we don't begin the instrument from the very beginning,
+                // there is no need to skip the frame where the begin invocation happens.
+                beginInternal();
             }
-            if (!mSurfaceOnly) {
-                mRendererWrapper.addObserver(mObserver);
+        } else {
+            if (DEBUG) {
+                Log.d(TAG, "begin: defer beginning since the surface is not ready for CUJ="
+                        + mSession.getName());
             }
         }
     }
@@ -267,89 +309,89 @@
      * Start trace section at appropriate time.
      */
     @VisibleForTesting
-    public void postTraceStartMarker() {
-        mChoreographer.mChoreographer.postCallback(
-                Choreographer.CALLBACK_INPUT, this::beginInternal, null);
+    public void postTraceStartMarker(Runnable action) {
+        mChoreographer.mChoreographer.postCallback(Choreographer.CALLBACK_INPUT, action, null);
     }
 
+    @UiThread
     private void beginInternal() {
-        synchronized (mLock) {
-            if (mCancelled || mEndVsyncId != INVALID_ID) {
-                return;
-            }
-            mTracingStarted = true;
-            markEvent("FT#begin");
-            Trace.beginAsyncSection(mSession.getName(), (int) mBeginVsyncId);
+        if (mCancelled || mEndVsyncId != INVALID_ID) {
+            return;
+        }
+        mTracingStarted = true;
+        markEvent("FT#begin");
+        Trace.beginAsyncSection(mSession.getName(), (int) mBeginVsyncId);
+        mSurfaceControlWrapper.addJankStatsListener(this, mSurfaceControl);
+        if (!mSurfaceOnly) {
+            mRendererWrapper.addObserver(mObserver);
         }
     }
 
     /**
      * End the trace session of the CUJ.
      */
+    @UiThread
     public boolean end(@Reasons int reason) {
-        synchronized (mLock) {
-            if (mCancelled || mEndVsyncId != INVALID_ID) return false;
-            mEndVsyncId = mChoreographer.getVsyncId();
-            // Cancel the session if:
-            // 1. The session begins and ends at the same vsync id.
-            // 2. The session never begun.
-            if (mBeginVsyncId == INVALID_ID) {
-                return cancel(REASON_CANCEL_NOT_BEGUN);
-            } else if (mEndVsyncId <= mBeginVsyncId) {
-                return cancel(REASON_CANCEL_SAME_VSYNC);
-            } else {
-                if (DEBUG) {
-                    Log.d(TAG, "end: " + mSession.getName()
-                            + ", end=" + mEndVsyncId + ", reason=" + reason);
-                }
-                markEvent("FT#end#" + reason);
-                Trace.endAsyncSection(mSession.getName(), (int) mBeginVsyncId);
-                mSession.setReason(reason);
-
-                // We don't remove observer here,
-                // will remove it when all the frame metrics in this duration are called back.
-                // See onFrameMetricsAvailable for the logic of removing the observer.
-                // Waiting at most 10 seconds for all callbacks to finish.
-                mWaitForFinishTimedOut = () -> {
-                    Log.e(TAG, "force finish cuj because of time out:" + mSession.getName());
-                    finish();
-                };
-                mHandler.postDelayed(mWaitForFinishTimedOut, TimeUnit.SECONDS.toMillis(10));
-                notifyCujEvent(ACTION_SESSION_END);
-                return true;
+        if (mCancelled || mEndVsyncId != INVALID_ID) return false;
+        mEndVsyncId = mChoreographer.getVsyncId();
+        // Cancel the session if:
+        // 1. The session begins and ends at the same vsync id.
+        // 2. The session never begun.
+        if (mBeginVsyncId == INVALID_ID) {
+            return cancel(REASON_CANCEL_NOT_BEGUN);
+        } else if (mEndVsyncId <= mBeginVsyncId) {
+            return cancel(REASON_CANCEL_SAME_VSYNC);
+        } else {
+            if (DEBUG) {
+                Log.d(TAG, "end: " + mSession.getName()
+                        + ", end=" + mEndVsyncId + ", reason=" + reason);
             }
+            markEvent("FT#end#" + reason);
+            Trace.endAsyncSection(mSession.getName(), (int) mBeginVsyncId);
+            mSession.setReason(reason);
+
+            // We don't remove observer here,
+            // will remove it when all the frame metrics in this duration are called back.
+            // See onFrameMetricsAvailable for the logic of removing the observer.
+            // Waiting at most 10 seconds for all callbacks to finish.
+            mWaitForFinishTimedOut = () -> {
+                Log.e(TAG, "force finish cuj because of time out:" + mSession.getName());
+                finish();
+            };
+            getHandler().postDelayed(mWaitForFinishTimedOut, TimeUnit.SECONDS.toMillis(10));
+            notifyCujEvent(ACTION_SESSION_END);
+            return true;
         }
     }
 
     /**
      * Cancel the trace session of the CUJ.
      */
+    @UiThread
     public boolean cancel(@Reasons int reason) {
-        synchronized (mLock) {
-            final boolean cancelFromEnd =
-                    reason == REASON_CANCEL_NOT_BEGUN || reason == REASON_CANCEL_SAME_VSYNC;
-            if (mCancelled || (mEndVsyncId != INVALID_ID && !cancelFromEnd)) return false;
-            mCancelled = true;
-            markEvent("FT#cancel#" + reason);
-            // We don't need to end the trace section if it never begun.
-            if (mTracingStarted) {
-                Trace.endAsyncSection(mSession.getName(), (int) mBeginVsyncId);
-            }
-
-            // Always remove the observers in cancel call to avoid leakage.
-            removeObservers();
-
-            if (DEBUG) {
-                Log.d(TAG, "cancel: " + mSession.getName() + ", begin=" + mBeginVsyncId
-                        + ", end=" + mEndVsyncId + ", reason=" + reason);
-            }
-
-            mSession.setReason(reason);
-            // Notify the listener the session has been cancelled.
-            // We don't notify the listeners if the session never begun.
-            notifyCujEvent(ACTION_SESSION_CANCEL);
-            return true;
+        final boolean cancelFromEnd =
+                reason == REASON_CANCEL_NOT_BEGUN || reason == REASON_CANCEL_SAME_VSYNC;
+        if (mCancelled || (mEndVsyncId != INVALID_ID && !cancelFromEnd)) return false;
+        mCancelled = true;
+        markEvent("FT#cancel#" + reason);
+        // We don't need to end the trace section if it has never begun.
+        if (mTracingStarted) {
+            Trace.endAsyncSection(mSession.getName(), (int) mBeginVsyncId);
         }
+
+        // Always remove the observers in cancel call to avoid leakage.
+        removeObservers();
+
+        if (DEBUG) {
+            Log.d(TAG, "cancel: " + mSession.getName() + ", begin=" + mBeginVsyncId
+                    + ", end=" + mEndVsyncId + ", reason=" + reason);
+        }
+
+        mSession.setReason(reason);
+        // Notify the listener the session has been cancelled.
+        // We don't notify the listeners if the session never begun.
+        notifyCujEvent(ACTION_SESSION_CANCEL);
+        return true;
     }
 
     private void markEvent(String desc) {
@@ -364,8 +406,8 @@
 
     @Override
     public void onJankDataAvailable(SurfaceControl.JankData[] jankData) {
-        synchronized (mLock) {
-            if (mCancelled) {
+        postCallback(() -> {
+            if (mCancelled || mMetricsFinalized) {
                 return;
             }
 
@@ -384,10 +426,19 @@
                 }
             }
             processJankInfos();
-        }
+        });
     }
 
-    private @Nullable JankInfo findJankInfo(long frameVsyncId) {
+    /**
+     * For easier argument capture.
+     */
+    @VisibleForTesting
+    public void postCallback(Runnable callback) {
+        getHandler().post(callback);
+    }
+
+    @Nullable
+    private JankInfo findJankInfo(long frameVsyncId) {
         return mJankInfos.get((int) frameVsyncId);
     }
 
@@ -400,8 +451,8 @@
 
     @Override
     public void onFrameMetricsAvailable(int dropCountSinceLastInvocation) {
-        synchronized (mLock) {
-            if (mCancelled) {
+        postCallback(() -> {
+            if (mCancelled || mMetricsFinalized) {
                 return;
             }
 
@@ -426,9 +477,10 @@
                         frameVsyncId, totalDurationNanos, isFirstFrame));
             }
             processJankInfos();
-        }
+        });
     }
 
+    @UiThread
     private boolean hasReceivedCallbacksAfterEnd() {
         if (mEndVsyncId == INVALID_ID) {
             return false;
@@ -451,6 +503,7 @@
         return false;
     }
 
+    @UiThread
     private void processJankInfos() {
         if (mMetricsFinalized) {
             return;
@@ -467,9 +520,12 @@
                 : info.hwuiCallbackFired && info.surfaceControlCallbackFired;
     }
 
+    @UiThread
     private void finish() {
-        mHandler.removeCallbacks(mWaitForFinishTimedOut);
+        getHandler().removeCallbacks(mWaitForFinishTimedOut);
         mWaitForFinishTimedOut = null;
+        if (mMetricsFinalized || mCancelled) return;
+        markEvent("FT#finish#" + mJankInfos.size());
         mMetricsFinalized = true;
 
         // The tracing has been ended, remove the observer, see if need to trigger perfetto.
@@ -496,7 +552,7 @@
                 totalFramesCount++;
                 boolean missedFrame = false;
                 if ((info.jankType & JANK_APP_DEADLINE_MISSED) != 0) {
-                    Log.w(TAG, "Missed App frame:" + info.jankType);
+                    Log.w(TAG, "Missed App frame:" + info + ", CUJ=" + mSession.getName());
                     missedAppFramesCount++;
                     missedFrame = true;
                 }
@@ -505,7 +561,7 @@
                         || (info.jankType & JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED) != 0
                         || (info.jankType & SURFACE_FLINGER_SCHEDULING) != 0
                         || (info.jankType & PREDICTION_ERROR) != 0) {
-                    Log.w(TAG, "Missed SF frame:" + info.jankType);
+                    Log.w(TAG, "Missed SF frame:" + info + ", CUJ=" + mSession.getName());
                     missedSfFramesCount++;
                     missedFrame = true;
                 }
@@ -520,13 +576,15 @@
                 // TODO (b/174755489): Early latch currently gets fired way too often, so we have
                 // to ignore it for now.
                 if (!mSurfaceOnly && !info.hwuiCallbackFired) {
-                    Log.w(TAG, "Missing HWUI jank callback for vsyncId: " + info.frameVsyncId);
+                    Log.w(TAG, "Missing HWUI jank callback for vsyncId: " + info.frameVsyncId
+                            + ", CUJ=" + mSession.getName());
                 }
             }
             if (!mSurfaceOnly && info.hwuiCallbackFired) {
                 maxFrameTimeNanos = Math.max(info.totalDurationNanos, maxFrameTimeNanos);
                 if (!info.surfaceControlCallbackFired) {
-                    Log.w(TAG, "Missing SF jank callback for vsyncId: " + info.frameVsyncId);
+                    Log.w(TAG, "Missing SF jank callback for vsyncId: " + info.frameVsyncId
+                            + ", CUJ=" + mSession.getName());
                 }
             }
         }
@@ -586,6 +644,7 @@
      * Remove all the registered listeners, observers and callbacks.
      */
     @VisibleForTesting
+    @UiThread
     public void removeObservers() {
         mSurfaceControlWrapper.removeJankStatsListener(this);
         if (!mSurfaceOnly) {
@@ -601,7 +660,7 @@
      * Trigger the prefetto daemon.
      */
     public void triggerPerfetto() {
-        InteractionJankMonitor.getInstance().trigger(mSession);
+        mMonitor.trigger(mSession);
     }
 
     /**
@@ -666,10 +725,18 @@
             mViewRoot = viewRoot;
         }
 
+        /**
+         * {@link ViewRootImpl#addSurfaceChangedCallback(ViewRootImpl.SurfaceChangedCallback)}
+         * @param callback {@link ViewRootImpl.SurfaceChangedCallback}
+         */
         public void addSurfaceChangedCallback(ViewRootImpl.SurfaceChangedCallback callback) {
             mViewRoot.addSurfaceChangedCallback(callback);
         }
 
+        /**
+         * {@link ViewRootImpl#removeSurfaceChangedCallback(ViewRootImpl.SurfaceChangedCallback)}
+         * @param callback {@link ViewRootImpl.SurfaceChangedCallback}
+         */
         public void removeSurfaceChangedCallback(ViewRootImpl.SurfaceChangedCallback callback) {
             mViewRoot.removeSurfaceChangedCallback(callback);
         }
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index 22340c6..8f10a5e 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -53,6 +53,7 @@
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_QS_TILE;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_CLEAR_ALL;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_DIALOG_OPEN;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_EXPAND_COLLAPSE_LOCK;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_HEADS_UP_APPEAR;
@@ -85,8 +86,11 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.UiThread;
+import android.annotation.WorkerThread;
 import android.content.Context;
 import android.os.Build;
+import android.os.Handler;
 import android.os.HandlerExecutor;
 import android.os.HandlerThread;
 import android.provider.DeviceConfig;
@@ -97,6 +101,7 @@
 import android.view.SurfaceControl;
 import android.view.View;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.jank.FrameTracker.ChoreographerWrapper;
 import com.android.internal.jank.FrameTracker.FrameMetricsWrapper;
@@ -130,6 +135,7 @@
 
     private static final String DEFAULT_WORKER_NAME = TAG + "-Worker";
     private static final long DEFAULT_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(2L);
+    static final long EXECUTOR_TASK_TIMEOUT = 500;
     private static final String SETTINGS_ENABLED_KEY = "enabled";
     private static final String SETTINGS_SAMPLING_INTERVAL_KEY = "sampling_interval";
     private static final String SETTINGS_THRESHOLD_MISSED_FRAMES_KEY =
@@ -210,6 +216,7 @@
     public static final int CUJ_USER_DIALOG_OPEN = 59;
     public static final int CUJ_TASKBAR_EXPAND = 60;
     public static final int CUJ_TASKBAR_COLLAPSE = 61;
+    public static final int CUJ_SHADE_CLEAR_ALL = 62;
 
     private static final int NO_STATSD_LOGGING = -1;
 
@@ -280,6 +287,7 @@
             UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__USER_DIALOG_OPEN,
             UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TASKBAR_EXPAND,
             UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TASKBAR_COLLAPSE,
+            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_CLEAR_ALL,
     };
 
     private static volatile InteractionJankMonitor sInstance;
@@ -287,13 +295,14 @@
     private final DeviceConfig.OnPropertiesChangedListener mPropertiesChangedListener =
             this::updateProperties;
 
-    private final FrameMetricsWrapper mMetrics;
+    @GuardedBy("mLock")
     private final SparseArray<FrameTracker> mRunningTrackers;
+    @GuardedBy("mLock")
     private final SparseArray<Runnable> mTimeoutActions;
     private final HandlerThread mWorker;
     private final Object mLock = new Object();
 
-    private boolean mEnabled = DEFAULT_ENABLED;
+    private volatile boolean mEnabled = DEFAULT_ENABLED;
     private int mSamplingInterval = DEFAULT_SAMPLING_INTERVAL;
     private int mTraceThresholdMissedFrames = DEFAULT_TRACE_THRESHOLD_MISSED_FRAMES;
     private int mTraceThresholdFrameTimeMillis = DEFAULT_TRACE_THRESHOLD_FRAME_TIME_MILLIS;
@@ -361,7 +370,8 @@
             CUJ_SHADE_DIALOG_OPEN,
             CUJ_USER_DIALOG_OPEN,
             CUJ_TASKBAR_EXPAND,
-            CUJ_TASKBAR_COLLAPSE
+            CUJ_TASKBAR_COLLAPSE,
+            CUJ_SHADE_CLEAR_ALL
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface CujType {
@@ -394,9 +404,7 @@
         mRunningTrackers = new SparseArray<>();
         mTimeoutActions = new SparseArray<>();
         mWorker = worker;
-        mMetrics = new FrameMetricsWrapper();
         mWorker.start();
-        mEnabled = DEFAULT_ENABLED;
         mSamplingInterval = DEFAULT_SAMPLING_INTERVAL;
 
         // Post initialization to the background in case we're running on the main
@@ -409,10 +417,7 @@
                 DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR,
                 new HandlerExecutor(mWorker.getThreadHandler()),
                 mPropertiesChangedListener);
-    }
-
-    Object getLock() {
-        return mLock;
+        mEnabled = DEFAULT_ENABLED;
     }
 
     /**
@@ -429,27 +434,27 @@
                 view == null ? null : new ThreadedRendererWrapper(view.getThreadedRenderer());
         final ViewRootWrapper viewRoot =
                 view == null ? null : new ViewRootWrapper(view.getViewRootImpl());
-
         final SurfaceControlWrapper surfaceControl = new SurfaceControlWrapper();
         final ChoreographerWrapper choreographer =
                 new ChoreographerWrapper(Choreographer.getInstance());
+        final FrameTrackerListener eventsListener = (s, act) -> handleCujEvents(act, s);
+        final FrameMetricsWrapper frameMetrics = new FrameMetricsWrapper();
 
-        synchronized (mLock) {
-            FrameTrackerListener eventsListener = (s, act) -> handleCujEvents(act, s);
-            return new FrameTracker(session, mWorker.getThreadHandler(),
-                    threadedRenderer, viewRoot, surfaceControl, choreographer,
-                    mMetrics, new FrameTracker.StatsLogWrapper(),
-                    mTraceThresholdMissedFrames, mTraceThresholdFrameTimeMillis,
-                    eventsListener, config);
-        }
+        return new FrameTracker(this, session, config.getHandler(), threadedRenderer, viewRoot,
+                surfaceControl, choreographer, frameMetrics, new FrameTracker.StatsLogWrapper(),
+                mTraceThresholdMissedFrames, mTraceThresholdFrameTimeMillis,
+                eventsListener, config);
     }
 
+    @UiThread
     private void handleCujEvents(String action, Session session) {
         // Clear the running and timeout tasks if the end / cancel was fired within the tracker.
         // Or we might have memory leaks.
         if (needRemoveTasks(action, session)) {
-            removeTimeout(session.getCuj());
-            removeTracker(session.getCuj());
+            getTracker(session.getCuj()).getHandler().runWithScissors(() -> {
+                removeTimeout(session.getCuj());
+                removeTracker(session.getCuj());
+            }, EXECUTOR_TASK_TIMEOUT);
         }
     }
 
@@ -466,7 +471,7 @@
         synchronized (mLock) {
             Runnable timeout = mTimeoutActions.get(cujType);
             if (timeout != null) {
-                mWorker.getThreadHandler().removeCallbacks(timeout);
+                getTracker(cujType).getHandler().removeCallbacks(timeout);
                 mTimeoutActions.remove(cujType);
             }
         }
@@ -491,9 +496,7 @@
      */
     public boolean begin(View v, @CujType int cujType) {
         try {
-            return beginInternal(
-                    Configuration.Builder.withView(cujType, v)
-                            .build());
+            return begin(Configuration.Builder.withView(cujType, v));
         } catch (IllegalArgumentException ex) {
             Log.d(TAG, "Build configuration failed!", ex);
             return false;
@@ -504,35 +507,42 @@
      * Begins a trace session.
      *
      * @param builder the builder of the configurations for instrumenting the CUJ.
-     * @return boolean true if the tracker is started successfully, false otherwise.
+     * @return boolean true if the tracker is begun successfully, false otherwise.
      */
     public boolean begin(@NonNull Configuration.Builder builder) {
         try {
-            return beginInternal(builder.build());
+            final Configuration config = builder.build();
+            final TrackerResult result = new TrackerResult();
+            final boolean success = config.getHandler().runWithScissors(
+                    () -> result.mResult = beginInternal(config), EXECUTOR_TASK_TIMEOUT);
+            if (!success) {
+                Log.d(TAG, "begin failed due to timeout, CUJ=" + getNameOfCuj(config.mCujType));
+                return false;
+            }
+            return result.mResult;
         } catch (IllegalArgumentException ex) {
             Log.d(TAG, "Build configuration failed!", ex);
             return false;
         }
     }
 
+    @UiThread
     private boolean beginInternal(@NonNull Configuration conf) {
-        synchronized (mLock) {
-            int cujType = conf.mCujType;
-            if (!shouldMonitor(cujType)) return false;
-            FrameTracker tracker = getTracker(cujType);
-            // Skip subsequent calls if we already have an ongoing tracing.
-            if (tracker != null) return false;
+        int cujType = conf.mCujType;
+        if (!shouldMonitor(cujType)) return false;
+        FrameTracker tracker = getTracker(cujType);
+        // Skip subsequent calls if we already have an ongoing tracing.
+        if (tracker != null) return false;
 
-            // begin a new trace session.
-            tracker = createFrameTracker(conf, new Session(cujType, conf.mTag));
-            mRunningTrackers.put(cujType, tracker);
-            tracker.begin();
+        // begin a new trace session.
+        tracker = createFrameTracker(conf, new Session(cujType, conf.mTag));
+        putTracker(cujType, tracker);
+        tracker.begin();
 
-            // Cancel the trace if we don't get an end() call in specified duration.
-            scheduleTimeoutAction(
-                    cujType, conf.mTimeout, () -> cancel(cujType, REASON_CANCEL_TIMEOUT));
-            return true;
-        }
+        // Cancel the trace if we don't get an end() call in specified duration.
+        scheduleTimeoutAction(
+                cujType, conf.mTimeout, () -> cancel(cujType, REASON_CANCEL_TIMEOUT));
+        return true;
     }
 
     /**
@@ -561,8 +571,10 @@
      */
     @VisibleForTesting
     public void scheduleTimeoutAction(@CujType int cuj, long timeout, Runnable action) {
-        mTimeoutActions.put(cuj, action);
-        mWorker.getThreadHandler().postDelayed(action, timeout);
+        synchronized (mLock) {
+            mTimeoutActions.put(cuj, action);
+            getTracker(cuj).getHandler().postDelayed(action, timeout);
+        }
     }
 
     /**
@@ -572,20 +584,37 @@
      * @return boolean true if the tracker is ended successfully, false otherwise.
      */
     public boolean end(@CujType int cujType) {
-        synchronized (mLock) {
-            // remove the timeout action first.
-            removeTimeout(cujType);
-            FrameTracker tracker = getTracker(cujType);
-            // Skip this call since we haven't started a trace yet.
-            if (tracker == null) return false;
-            // if the end call doesn't return true, another thread is handling end of the cuj.
-            if (tracker.end(REASON_END_NORMAL)) {
-                removeTracker(cujType);
+        FrameTracker tracker = getTracker(cujType);
+        // Skip this call since we haven't started a trace yet.
+        if (tracker == null) return false;
+        try {
+            final TrackerResult result = new TrackerResult();
+            final boolean success = tracker.getHandler().runWithScissors(
+                    () -> result.mResult = endInternal(cujType), EXECUTOR_TASK_TIMEOUT);
+            if (!success) {
+                Log.d(TAG, "end failed due to timeout, CUJ=" + getNameOfCuj(cujType));
+                return false;
             }
-            return true;
+            return result.mResult;
+        } catch (IllegalArgumentException ex) {
+            Log.d(TAG, "Execute end task failed!", ex);
+            return false;
         }
     }
 
+    @UiThread
+    private boolean endInternal(@CujType int cujType) {
+        // remove the timeout action first.
+        removeTimeout(cujType);
+        FrameTracker tracker = getTracker(cujType);
+        if (tracker == null) return false;
+        // if the end call doesn't return true, another thread is handling end of the cuj.
+        if (tracker.end(REASON_END_NORMAL)) {
+            removeTracker(cujType);
+        }
+        return true;
+    }
+
     /**
      * Cancels the trace session.
      *
@@ -602,39 +631,66 @@
      */
     @VisibleForTesting
     public boolean cancel(@CujType int cujType, @Reasons int reason) {
-        synchronized (mLock) {
-            // remove the timeout action first.
-            removeTimeout(cujType);
-            FrameTracker tracker = getTracker(cujType);
-            // Skip this call since we haven't started a trace yet.
-            if (tracker == null) return false;
-            // if the cancel call doesn't return true, another thread is handling cancel of the cuj.
-            if (tracker.cancel(reason)) {
-                removeTracker(cujType);
+        FrameTracker tracker = getTracker(cujType);
+        // Skip this call since we haven't started a trace yet.
+        if (tracker == null) return false;
+        try {
+            final TrackerResult result = new TrackerResult();
+            final boolean success = tracker.getHandler().runWithScissors(
+                    () -> result.mResult = cancelInternal(cujType, reason), EXECUTOR_TASK_TIMEOUT);
+            if (!success) {
+                Log.d(TAG, "cancel failed due to timeout, CUJ=" + getNameOfCuj(cujType));
+                return false;
             }
-            return true;
+            return result.mResult;
+        } catch (IllegalArgumentException ex) {
+            Log.d(TAG, "Execute cancel task failed!", ex);
+            return false;
+        }
+    }
+
+    @UiThread
+    private boolean cancelInternal(@CujType int cujType, @Reasons int reason) {
+        // remove the timeout action first.
+        removeTimeout(cujType);
+        FrameTracker tracker = getTracker(cujType);
+        if (tracker == null) return false;
+        // if the cancel call doesn't return true, another thread is handling cancel of the cuj.
+        if (tracker.cancel(reason)) {
+            removeTracker(cujType);
+        }
+        return true;
+    }
+
+    private void putTracker(@CujType int cuj, @NonNull FrameTracker tracker) {
+        synchronized (mLock) {
+            mRunningTrackers.put(cuj, tracker);
         }
     }
 
     private FrameTracker getTracker(@CujType int cuj) {
-        return mRunningTrackers.get(cuj);
+        synchronized (mLock) {
+            return mRunningTrackers.get(cuj);
+        }
     }
 
     private void removeTracker(@CujType int cuj) {
-        mRunningTrackers.remove(cuj);
+        synchronized (mLock) {
+            mRunningTrackers.remove(cuj);
+        }
     }
 
+    @WorkerThread
     private void updateProperties(DeviceConfig.Properties properties) {
-        synchronized (mLock) {
-            mSamplingInterval = properties.getInt(SETTINGS_SAMPLING_INTERVAL_KEY,
-                    DEFAULT_SAMPLING_INTERVAL);
-            mEnabled = properties.getBoolean(SETTINGS_ENABLED_KEY, DEFAULT_ENABLED);
-            mTraceThresholdMissedFrames = properties.getInt(SETTINGS_THRESHOLD_MISSED_FRAMES_KEY,
-                    DEFAULT_TRACE_THRESHOLD_MISSED_FRAMES);
-            mTraceThresholdFrameTimeMillis = properties.getInt(
-                    SETTINGS_THRESHOLD_FRAME_TIME_MILLIS_KEY,
-                    DEFAULT_TRACE_THRESHOLD_FRAME_TIME_MILLIS);
-        }
+        mSamplingInterval = properties.getInt(SETTINGS_SAMPLING_INTERVAL_KEY,
+                DEFAULT_SAMPLING_INTERVAL);
+        mTraceThresholdMissedFrames = properties.getInt(SETTINGS_THRESHOLD_MISSED_FRAMES_KEY,
+                DEFAULT_TRACE_THRESHOLD_MISSED_FRAMES);
+        mTraceThresholdFrameTimeMillis = properties.getInt(
+                SETTINGS_THRESHOLD_FRAME_TIME_MILLIS_KEY,
+                DEFAULT_TRACE_THRESHOLD_FRAME_TIME_MILLIS);
+        // The memory visibility is powered by the volatile field, mEnabled.
+        mEnabled = properties.getBoolean(SETTINGS_ENABLED_KEY, DEFAULT_ENABLED);
     }
 
     @VisibleForTesting
@@ -804,10 +860,16 @@
                 return "TASKBAR_EXPAND";
             case CUJ_TASKBAR_COLLAPSE:
                 return "TASKBAR_COLLAPSE";
+            case CUJ_SHADE_CLEAR_ALL:
+                return "SHADE_CLEAR_ALL";
         }
         return "UNKNOWN";
     }
 
+    private static class TrackerResult {
+        private boolean mResult;
+    }
+
     /**
      * Configurations used while instrumenting the CUJ. <br/>
      * <b>It may refer to an attached view, don't use static reference for any purpose.</b>
@@ -821,6 +883,7 @@
         private final SurfaceControl mSurfaceControl;
         private final @CujType int mCujType;
         private final boolean mDeferMonitor;
+        private final Handler mHandler;
 
         /**
          * A builder for building Configuration. {@link #setView(View)} is essential
@@ -964,6 +1027,7 @@
             mSurfaceControl = surfaceControl;
             mDeferMonitor = deferMonitor;
             validate();
+            mHandler = mSurfaceOnly ? mContext.getMainThreadHandler() : mView.getHandler();
         }
 
         private void validate() {
@@ -1012,20 +1076,25 @@
             return mSurfaceControl;
         }
 
-        View getView() {
+        @VisibleForTesting
+        /**
+         * @return a view which is attached to the view tree.
+         */
+        public View getView() {
             return mView;
         }
 
-        Context getContext() {
-            return mContext;
-        }
-
         /**
          * @return true if the monitoring should be deferred to the next frame, false otherwise.
          */
         public boolean shouldDeferMonitor() {
             return mDeferMonitor;
         }
+
+        @VisibleForTesting
+        public Handler getHandler() {
+            return mHandler;
+        }
     }
 
     /**
@@ -1078,7 +1147,8 @@
             mReason = reason;
         }
 
-        public @Reasons int getReason() {
+        @Reasons
+        public int getReason() {
             return mReason;
         }
     }
diff --git a/core/java/com/android/internal/net/VpnProfile.java b/core/java/com/android/internal/net/VpnProfile.java
index b334e91..396da5b 100644
--- a/core/java/com/android/internal/net/VpnProfile.java
+++ b/core/java/com/android/internal/net/VpnProfile.java
@@ -204,7 +204,7 @@
         excludeLocalRoutes = in.readBoolean();
         requiresInternetValidation = in.readBoolean();
         final PersistableBundle bundle =
-                in.readParcelable(PersistableBundle.class.getClassLoader());
+                in.readParcelable(PersistableBundle.class.getClassLoader(), android.os.PersistableBundle.class);
         ikeTunConnParams = (bundle == null) ? null
                 : TunnelConnectionParamsUtils.fromPersistableBundle(bundle);
     }
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 13bf643..a352063 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -1440,8 +1440,9 @@
             int size, boolean verticalBar, boolean seascape, int sideMargin, boolean animate,
             boolean force, WindowInsetsController controller) {
         state.present = state.attributes.isPresent(
-                        controller.isRequestedVisible(state.attributes.insetsType),
-                        mWindow.getAttributes().flags, force);
+                (controller.isRequestedVisible(state.attributes.insetsType)
+                        || mLastShouldAlwaysConsumeSystemBars),
+                mWindow.getAttributes().flags, force);
         boolean show = state.attributes.isVisible(state.present, color,
                 mWindow.getAttributes().flags, force);
         boolean showView = show && !isResizing() && !mHasCaption && size > 0;
diff --git a/core/java/com/android/internal/util/BinaryXmlPullParser.java b/core/java/com/android/internal/util/BinaryXmlPullParser.java
index 57552f3..d3abac9 100644
--- a/core/java/com/android/internal/util/BinaryXmlPullParser.java
+++ b/core/java/com/android/internal/util/BinaryXmlPullParser.java
@@ -73,12 +73,6 @@
  * </ul>
  */
 public final class BinaryXmlPullParser implements TypedXmlPullParser {
-    /**
-     * Default buffer size, which matches {@code FastXmlSerializer}. This should
-     * be kept in sync with {@link BinaryXmlPullParser}.
-     */
-    private static final int BUFFER_SIZE = 32_768;
-
     private FastDataInput mIn;
 
     private int mCurrentToken = START_DOCUMENT;
@@ -100,7 +94,12 @@
             throw new UnsupportedOperationException();
         }
 
-        mIn = new FastDataInput(is, BUFFER_SIZE);
+        if (mIn != null) {
+            mIn.release();
+            mIn = null;
+        }
+
+        mIn = FastDataInput.obtainUsing4ByteSequences(is);
 
         mCurrentToken = START_DOCUMENT;
         mCurrentDepth = 0;
diff --git a/core/java/com/android/internal/util/BinaryXmlSerializer.java b/core/java/com/android/internal/util/BinaryXmlSerializer.java
index f0ca1edb..485430a 100644
--- a/core/java/com/android/internal/util/BinaryXmlSerializer.java
+++ b/core/java/com/android/internal/util/BinaryXmlSerializer.java
@@ -91,12 +91,6 @@
     static final int TYPE_BOOLEAN_TRUE = 12 << 4;
     static final int TYPE_BOOLEAN_FALSE = 13 << 4;
 
-    /**
-     * Default buffer size, which matches {@code FastXmlSerializer}. This should
-     * be kept in sync with {@link BinaryXmlPullParser}.
-     */
-    private static final int BUFFER_SIZE = 32_768;
-
     private FastDataOutput mOut;
 
     /**
@@ -124,7 +118,7 @@
             throw new UnsupportedOperationException();
         }
 
-        mOut = FastDataOutput.obtain(os);
+        mOut = FastDataOutput.obtainUsing4ByteSequences(os);
         mOut.write(PROTOCOL_MAGIC_VERSION_0);
 
         mTagCount = 0;
diff --git a/core/java/com/android/internal/util/FastDataInput.java b/core/java/com/android/internal/util/FastDataInput.java
index f8d241b..5117034 100644
--- a/core/java/com/android/internal/util/FastDataInput.java
+++ b/core/java/com/android/internal/util/FastDataInput.java
@@ -30,6 +30,7 @@
 import java.io.InputStream;
 import java.util.Arrays;
 import java.util.Objects;
+import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * Optimized implementation of {@link DataInput} which buffers data in memory
@@ -41,13 +42,18 @@
 public class FastDataInput implements DataInput, Closeable {
     private static final int MAX_UNSIGNED_SHORT = 65_535;
 
+    private static final int DEFAULT_BUFFER_SIZE = 32_768;
+
+    private static AtomicReference<FastDataInput> sInCache = new AtomicReference<>();
+
     private final VMRuntime mRuntime;
-    private final InputStream mIn;
 
     private final byte[] mBuffer;
     private final long mBufferPtr;
     private final int mBufferCap;
+    private final boolean mUse4ByteSequence;
 
+    private InputStream mIn;
     private int mBufferPos;
     private int mBufferLim;
 
@@ -57,7 +63,18 @@
     private int mStringRefCount = 0;
     private String[] mStringRefs = new String[32];
 
+    /**
+     * @deprecated callers must specify {@code use4ByteSequence} so they make a
+     *             clear choice about working around a long-standing ART bug, as
+     *             described by the {@code kUtfUse4ByteSequence} comments in
+     *             {@code art/runtime/jni/jni_internal.cc}.
+     */
+    @Deprecated
     public FastDataInput(@NonNull InputStream in, int bufferSize) {
+        this(in, bufferSize, true /* use4ByteSequence */);
+    }
+
+    public FastDataInput(@NonNull InputStream in, int bufferSize, boolean use4ByteSequence) {
         mRuntime = VMRuntime.getRuntime();
         mIn = Objects.requireNonNull(in);
         if (bufferSize < 8) {
@@ -67,6 +84,64 @@
         mBuffer = (byte[]) mRuntime.newNonMovableArray(byte.class, bufferSize);
         mBufferPtr = mRuntime.addressOf(mBuffer);
         mBufferCap = mBuffer.length;
+        mUse4ByteSequence = use4ByteSequence;
+    }
+
+    /**
+     * Obtain a {@link FastDataInput} configured with the given
+     * {@link InputStream} and which encodes large code-points using 3-byte
+     * sequences.
+     * <p>
+     * This <em>is</em> compatible with the {@link DataInput} API contract,
+     * which specifies that large code-points must be encoded with 3-byte
+     * sequences.
+     */
+    public static FastDataInput obtainUsing3ByteSequences(@NonNull InputStream in) {
+        return new FastDataInput(in, DEFAULT_BUFFER_SIZE, false /* use4ByteSequence */);
+    }
+
+    /**
+     * Obtain a {@link FastDataInput} configured with the given
+     * {@link InputStream} and which decodes large code-points using 4-byte
+     * sequences.
+     * <p>
+     * This <em>is not</em> compatible with the {@link DataInput} API contract,
+     * which specifies that large code-points must be encoded with 3-byte
+     * sequences.
+     */
+    public static FastDataInput obtainUsing4ByteSequences(@NonNull InputStream in) {
+        FastDataInput instance = sInCache.getAndSet(null);
+        if (instance != null) {
+            instance.setInput(in);
+            return instance;
+        }
+        return new FastDataInput(in, DEFAULT_BUFFER_SIZE, true /* use4ByteSequence */);
+    }
+
+    /**
+     * Release a {@link FastDataInput} to potentially be recycled. You must not
+     * interact with the object after releasing it.
+     */
+    public void release() {
+        mIn = null;
+        mBufferPos = 0;
+        mBufferLim = 0;
+        mStringRefCount = 0;
+
+        if (mBufferCap == DEFAULT_BUFFER_SIZE && mUse4ByteSequence) {
+            // Try to return to the cache.
+            sInCache.compareAndSet(null, this);
+        }
+    }
+
+    /**
+     * Re-initializes the object for the new input.
+     */
+    private void setInput(@NonNull InputStream in) {
+        mIn = Objects.requireNonNull(in);
+        mBufferPos = 0;
+        mBufferLim = 0;
+        mStringRefCount = 0;
     }
 
     private void fill(int need) throws IOException {
@@ -90,6 +165,7 @@
     @Override
     public void close() throws IOException {
         mIn.close();
+        release();
     }
 
     @Override
@@ -126,6 +202,14 @@
 
     @Override
     public String readUTF() throws IOException {
+        if (mUse4ByteSequence) {
+            return readUTFUsing4ByteSequences();
+        } else {
+            return readUTFUsing3ByteSequences();
+        }
+    }
+
+    private String readUTFUsing4ByteSequences() throws IOException {
         // Attempt to read directly from buffer space if there's enough room,
         // otherwise fall back to chunking into place
         final int len = readUnsignedShort();
@@ -141,6 +225,22 @@
         }
     }
 
+    private String readUTFUsing3ByteSequences() throws IOException {
+        // Attempt to read directly from buffer space if there's enough room,
+        // otherwise fall back to chunking into place
+        final int len = readUnsignedShort();
+        if (mBufferCap > len) {
+            if (mBufferLim - mBufferPos < len) fill(len);
+            final String res = ModifiedUtf8.decode(mBuffer, new char[len], mBufferPos, len);
+            mBufferPos += len;
+            return res;
+        } else {
+            final byte[] tmp = (byte[]) mRuntime.newNonMovableArray(byte.class, len + 1);
+            readFully(tmp, 0, len);
+            return ModifiedUtf8.decode(tmp, new char[len], 0, len);
+        }
+    }
+
     /**
      * Read a {@link String} value with the additional signal that the given
      * value is a candidate for being canonicalized, similar to
diff --git a/core/java/com/android/internal/util/FastDataOutput.java b/core/java/com/android/internal/util/FastDataOutput.java
index bc8496b..c9e8f8f 100644
--- a/core/java/com/android/internal/util/FastDataOutput.java
+++ b/core/java/com/android/internal/util/FastDataOutput.java
@@ -42,7 +42,7 @@
 public class FastDataOutput implements DataOutput, Flushable, Closeable {
     private static final int MAX_UNSIGNED_SHORT = 65_535;
 
-    private static final int BUFFER_SIZE = 32_768;
+    private static final int DEFAULT_BUFFER_SIZE = 32_768;
 
     private static AtomicReference<FastDataOutput> sOutCache = new AtomicReference<>();
 
@@ -51,6 +51,7 @@
     private final byte[] mBuffer;
     private final long mBufferPtr;
     private final int mBufferCap;
+    private final boolean mUse4ByteSequence;
 
     private OutputStream mOut;
     private int mBufferPos;
@@ -60,7 +61,18 @@
      */
     private final HashMap<String, Short> mStringRefs = new HashMap<>();
 
+    /**
+     * @deprecated callers must specify {@code use4ByteSequence} so they make a
+     *             clear choice about working around a long-standing ART bug, as
+     *             described by the {@code kUtfUse4ByteSequence} comments in
+     *             {@code art/runtime/jni/jni_internal.cc}.
+     */
+    @Deprecated
     public FastDataOutput(@NonNull OutputStream out, int bufferSize) {
+        this(out, bufferSize, true /* use4ByteSequence */);
+    }
+
+    public FastDataOutput(@NonNull OutputStream out, int bufferSize, boolean use4ByteSequence) {
         mRuntime = VMRuntime.getRuntime();
         if (bufferSize < 8) {
             throw new IllegalArgumentException();
@@ -69,25 +81,45 @@
         mBuffer = (byte[]) mRuntime.newNonMovableArray(byte.class, bufferSize);
         mBufferPtr = mRuntime.addressOf(mBuffer);
         mBufferCap = mBuffer.length;
+        mUse4ByteSequence = use4ByteSequence;
 
         setOutput(out);
     }
 
     /**
-     * Create a new FastDataOutput object or retrieve one from cache.
+     * Obtain a {@link FastDataOutput} configured with the given
+     * {@link OutputStream} and which encodes large code-points using 3-byte
+     * sequences.
+     * <p>
+     * This <em>is</em> compatible with the {@link DataOutput} API contract,
+     * which specifies that large code-points must be encoded with 3-byte
+     * sequences.
      */
-    public static FastDataOutput obtain(@NonNull OutputStream out) {
+    public static FastDataOutput obtainUsing3ByteSequences(@NonNull OutputStream out) {
+        return new FastDataOutput(out, DEFAULT_BUFFER_SIZE, false /* use4ByteSequence */);
+    }
+
+    /**
+     * Obtain a {@link FastDataOutput} configured with the given
+     * {@link OutputStream} and which encodes large code-points using 4-byte
+     * sequences.
+     * <p>
+     * This <em>is not</em> compatible with the {@link DataOutput} API contract,
+     * which specifies that large code-points must be encoded with 3-byte
+     * sequences.
+     */
+    public static FastDataOutput obtainUsing4ByteSequences(@NonNull OutputStream out) {
         FastDataOutput instance = sOutCache.getAndSet(null);
         if (instance != null) {
             instance.setOutput(out);
             return instance;
         }
-        return new FastDataOutput(out, BUFFER_SIZE);
+        return new FastDataOutput(out, DEFAULT_BUFFER_SIZE, true /* use4ByteSequence */);
     }
 
     /**
-     * Put a FastDataOutput object back into the cache.
-     * You must not touch the object after this call.
+     * Release a {@link FastDataOutput} to potentially be recycled. You must not
+     * interact with the object after releasing it.
      */
     public void release() {
         if (mBufferPos > 0) {
@@ -98,7 +130,7 @@
         mBufferPos = 0;
         mStringRefs.clear();
 
-        if (mBufferCap == BUFFER_SIZE) {
+        if (mBufferCap == DEFAULT_BUFFER_SIZE && mUse4ByteSequence) {
             // Try to return to the cache.
             sOutCache.compareAndSet(null, this);
         }
@@ -156,6 +188,14 @@
 
     @Override
     public void writeUTF(String s) throws IOException {
+        if (mUse4ByteSequence) {
+            writeUTFUsing4ByteSequences(s);
+        } else {
+            writeUTFUsing3ByteSequences(s);
+        }
+    }
+
+    private void writeUTFUsing4ByteSequences(String s) throws IOException {
         // Attempt to write directly to buffer space if there's enough room,
         // otherwise fall back to chunking into place
         if (mBufferCap - mBufferPos < 2 + s.length()) drain();
@@ -183,6 +223,27 @@
         }
     }
 
+    private void writeUTFUsing3ByteSequences(String s) throws IOException {
+        final int len = (int) ModifiedUtf8.countBytes(s, false);
+        if (len > MAX_UNSIGNED_SHORT) {
+            throw new IOException("Modified UTF-8 length too large: " + len);
+        }
+
+        // Attempt to write directly to buffer space if there's enough room,
+        // otherwise fall back to chunking into place
+        if (mBufferCap >= 2 + len) {
+            if (mBufferCap - mBufferPos < 2 + len) drain();
+            writeShort(len);
+            ModifiedUtf8.encode(mBuffer, mBufferPos, s);
+            mBufferPos += len;
+        } else {
+            final byte[] tmp = (byte[]) mRuntime.newNonMovableArray(byte.class, len + 1);
+            ModifiedUtf8.encode(tmp, 0, s);
+            writeShort(len);
+            write(tmp, 0, len);
+        }
+    }
+
     /**
      * Write a {@link String} value with the additional signal that the given
      * value is a candidate for being canonicalized, similar to
diff --git a/core/java/com/android/internal/util/ModifiedUtf8.java b/core/java/com/android/internal/util/ModifiedUtf8.java
new file mode 100644
index 0000000..a144c00
--- /dev/null
+++ b/core/java/com/android/internal/util/ModifiedUtf8.java
@@ -0,0 +1,110 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import java.io.UTFDataFormatException;
+
+public class ModifiedUtf8 {
+    /**
+     * Decodes a byte array containing <i>modified UTF-8</i> bytes into a string.
+     *
+     * <p>Note that although this method decodes the (supposedly impossible) zero byte to U+0000,
+     * that's what the RI does too.
+     */
+    public static String decode(byte[] in, char[] out, int offset, int utfSize)
+            throws UTFDataFormatException {
+        int count = 0, s = 0, a;
+        while (count < utfSize) {
+            if ((out[s] = (char) in[offset + count++]) < '\u0080') {
+                s++;
+            } else if (((a = out[s]) & 0xe0) == 0xc0) {
+                if (count >= utfSize) {
+                    throw new UTFDataFormatException("bad second byte at " + count);
+                }
+                int b = in[offset + count++];
+                if ((b & 0xC0) != 0x80) {
+                    throw new UTFDataFormatException("bad second byte at " + (count - 1));
+                }
+                out[s++] = (char) (((a & 0x1F) << 6) | (b & 0x3F));
+            } else if ((a & 0xf0) == 0xe0) {
+                if (count + 1 >= utfSize) {
+                    throw new UTFDataFormatException("bad third byte at " + (count + 1));
+                }
+                int b = in[offset + count++];
+                int c = in[offset + count++];
+                if (((b & 0xC0) != 0x80) || ((c & 0xC0) != 0x80)) {
+                    throw new UTFDataFormatException("bad second or third byte at " + (count - 2));
+                }
+                out[s++] = (char) (((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F));
+            } else {
+                throw new UTFDataFormatException("bad byte at " + (count - 1));
+            }
+        }
+        return new String(out, 0, s);
+    }
+
+    /**
+     * Returns the number of bytes the modified UTF-8 representation of 's' would take. Note
+     * that this is just the space for the bytes representing the characters, not the length
+     * which precedes those bytes, because different callers represent the length differently,
+     * as two, four, or even eight bytes. If {@code shortLength} is true, we'll throw an
+     * exception if the string is too long for its length to be represented by a short.
+     */
+    public static long countBytes(String s, boolean shortLength) throws UTFDataFormatException {
+        long result = 0;
+        final int length = s.length();
+        for (int i = 0; i < length; ++i) {
+            char ch = s.charAt(i);
+            if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.
+                ++result;
+            } else if (ch <= 2047) {
+                result += 2;
+            } else {
+                result += 3;
+            }
+            if (shortLength && result > 65535) {
+                throw new UTFDataFormatException("String more than 65535 UTF bytes long");
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Encodes the <i>modified UTF-8</i> bytes corresponding to string {@code s} into the
+     * byte array {@code dst}, starting at the given {@code offset}.
+     */
+    public static void encode(byte[] dst, int offset, String s) {
+        final int length = s.length();
+        for (int i = 0; i < length; i++) {
+            char ch = s.charAt(i);
+            if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.
+                dst[offset++] = (byte) ch;
+            } else if (ch <= 2047) {
+                dst[offset++] = (byte) (0xc0 | (0x1f & (ch >> 6)));
+                dst[offset++] = (byte) (0x80 | (0x3f & ch));
+            } else {
+                dst[offset++] = (byte) (0xe0 | (0x0f & (ch >> 12)));
+                dst[offset++] = (byte) (0x80 | (0x3f & (ch >> 6)));
+                dst[offset++] = (byte) (0x80 | (0x3f & ch));
+            }
+        }
+    }
+
+    private ModifiedUtf8() {
+    }
+}
diff --git a/core/java/com/android/internal/util/ScreenshotHelper.java b/core/java/com/android/internal/util/ScreenshotHelper.java
index f4f438b..518fa53 100644
--- a/core/java/com/android/internal/util/ScreenshotHelper.java
+++ b/core/java/com/android/internal/util/ScreenshotHelper.java
@@ -217,8 +217,8 @@
                 throw new IllegalArgumentException("Bundle does not contain a hardware bitmap");
             }
 
-            HardwareBuffer buffer = bundle.getParcelable(KEY_BUFFER);
-            ParcelableColorSpace colorSpace = bundle.getParcelable(KEY_COLOR_SPACE);
+            HardwareBuffer buffer = bundle.getParcelable(KEY_BUFFER, android.hardware.HardwareBuffer.class);
+            ParcelableColorSpace colorSpace = bundle.getParcelable(KEY_COLOR_SPACE, android.graphics.ParcelableColorSpace.class);
 
             return Bitmap.wrapHardwareBuffer(Objects.requireNonNull(buffer),
                     colorSpace.getColorSpace());
diff --git a/core/java/com/android/internal/util/TEST_MAPPING b/core/java/com/android/internal/util/TEST_MAPPING
index 5881c51..41d59bb 100644
--- a/core/java/com/android/internal/util/TEST_MAPPING
+++ b/core/java/com/android/internal/util/TEST_MAPPING
@@ -1,7 +1,20 @@
 {
   "presubmit": [
     {
-       "name": "ScreenshotHelperTests"
+      "name": "ScreenshotHelperTests",
+      "file_patterns": ["ScreenshotHelper"]
+    },
+    {
+      "name": "FrameworksCoreTests",
+      "options": [
+        {
+          "include-filter": "android.util.XmlTest"
+        },
+        {
+          "include-filter": "android.util.BinaryXmlTest"
+        }
+      ],
+      "file_patterns": ["Xml"]
     }
   ]
-}
\ No newline at end of file
+}
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 4bed47c..9e0b249 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -38,25 +38,21 @@
     // TODO: Use ParceledListSlice instead
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
             + "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)")
-    List<InputMethodInfo> getInputMethodList(int userId);
-
-    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
-            + "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)")
-    List<InputMethodInfo> getAwareLockedInputMethodList(int userId, int directBootAwareness);
+    List<InputMethodInfo> getInputMethodList(int userId, int directBootAwareness);
 
     // TODO: Use ParceledListSlice instead
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
             + "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)")
     List<InputMethodInfo> getEnabledInputMethodList(int userId);
 
-    List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in String imiId,
+    List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in @nullable String imiId,
             boolean allowsImplicitlySelectedSubtypes);
-    InputMethodSubtype getLastInputMethodSubtype();
+    @nullable InputMethodSubtype getLastInputMethodSubtype();
 
-    boolean showSoftInput(in IInputMethodClient client, IBinder windowToken, int flags,
-            in ResultReceiver resultReceiver, int reason);
-    boolean hideSoftInput(in IInputMethodClient client, IBinder windowToken, int flags,
-            in ResultReceiver resultReceiver, int reason);
+    boolean showSoftInput(in IInputMethodClient client, @nullable IBinder windowToken, int flags,
+            in @nullable ResultReceiver resultReceiver, int reason);
+    boolean hideSoftInput(in IInputMethodClient client, @nullable IBinder windowToken, int flags,
+            in @nullable ResultReceiver resultReceiver, int reason);
 
     // If windowToken is null, this just does startInput().  Otherwise this reports that a window
     // has gained focus, and if 'editorInfo' is non-null then also does startInput.
@@ -65,34 +61,39 @@
             + "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)")
     InputBindResult startInputOrWindowGainedFocus(
             /* @StartInputReason */ int startInputReason,
-            in IInputMethodClient client, in IBinder windowToken,
+            in IInputMethodClient client, in @nullable IBinder windowToken,
             /* @StartInputFlags */ int startInputFlags,
             /* @android.view.WindowManager.LayoutParams.SoftInputModeFlags */ int softInputMode,
-            int windowFlags, in EditorInfo editorInfo, in IRemoteInputConnection inputConnection,
-            in IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
+            /* @android.view.WindowManager.LayoutParams.Flags */ int windowFlags,
+            in @nullable EditorInfo editorInfo, in @nullable IRemoteInputConnection inputConnection,
+            in @nullable IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
             int unverifiedTargetSdkVersion, in ImeOnBackInvokedDispatcher imeDispatcher);
 
     void showInputMethodPickerFromClient(in IInputMethodClient client,
             int auxiliarySubtypeMode);
 
+    @EnforcePermission("WRITE_SECURE_SETTINGS")
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
             + "android.Manifest.permission.WRITE_SECURE_SETTINGS)")
     void showInputMethodPickerFromSystem(in IInputMethodClient client,
             int auxiliarySubtypeMode, int displayId);
 
-    void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client, String topId);
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+            + "android.Manifest.permission.TEST_INPUT_METHOD)")
     boolean isInputMethodPickerShownForTest();
-    InputMethodSubtype getCurrentInputMethodSubtype();
+
+    @nullable InputMethodSubtype getCurrentInputMethodSubtype();
     void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);
     // This is kept due to @UnsupportedAppUsage.
     // TODO(Bug 113914148): Consider removing this.
     int getInputMethodWindowVisibleHeight(in IInputMethodClient client);
 
     oneway void reportVirtualDisplayGeometryAsync(in IInputMethodClient parentClient,
-            int childDisplayId, in float[] matrixValues);
+            int childDisplayId, in @nullable float[] matrixValues);
 
     oneway void reportPerceptibleAsync(in IBinder windowToken, boolean perceptible);
 
+    @EnforcePermission("INTERNAL_SYSTEM_WINDOW")
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
             + "android.Manifest.permission.INTERNAL_SYSTEM_WINDOW)")
     void removeImeSurface();
@@ -114,4 +115,10 @@
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
             + "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)")
     boolean isStylusHandwritingAvailableAsUser(int userId);
+
+    /** add virtual stylus id for test Stylus handwriting session **/
+    @EnforcePermission("INJECT_EVENTS")
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+            + "android.Manifest.permission.INJECT_EVENTS)")
+    void addVirtualStylusIdForTestSession(in IInputMethodClient client);
 }
diff --git a/core/java/com/android/internal/widget/CallLayout.java b/core/java/com/android/internal/widget/CallLayout.java
index 83345da..acb0e44 100644
--- a/core/java/com/android/internal/widget/CallLayout.java
+++ b/core/java/com/android/internal/widget/CallLayout.java
@@ -125,7 +125,7 @@
      */
     @RemotableViewMethod
     public void setData(Bundle extras) {
-        setUser(extras.getParcelable(Notification.EXTRA_CALL_PERSON));
+        setUser(extras.getParcelable(Notification.EXTRA_CALL_PERSON, android.app.Person.class));
         updateCallLayout();
     }
 
diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java
index 4706aff..9f21760 100644
--- a/core/java/com/android/internal/widget/ConversationLayout.java
+++ b/core/java/com/android/internal/widget/ConversationLayout.java
@@ -390,11 +390,11 @@
                 = Notification.MessagingStyle.Message.getMessagesFromBundleArray(histMessages);
 
         // mUser now set (would be nice to avoid the side effect but WHATEVER)
-        setUser(extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON));
+        setUser(extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON, android.app.Person.class));
 
         // Append remote input history to newMessages (again, side effect is lame but WHATEVS)
         RemoteInputHistoryItem[] history = (RemoteInputHistoryItem[])
-                extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS);
+                extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS, android.app.RemoteInputHistoryItem.class);
         addRemoteInputHistoryToMessages(newMessages, history);
 
         boolean showSpinner =
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 17a47d3..24a3c16 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -144,21 +144,12 @@
      */
     public static final int USER_FRP = UserHandle.USER_NULL + 1;
 
-    @Deprecated
-    public final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently";
     public final static String PATTERN_EVER_CHOSEN_KEY = "lockscreen.patterneverchosen";
     public final static String PASSWORD_TYPE_KEY = "lockscreen.password_type";
     @Deprecated
     public final static String PASSWORD_TYPE_ALTERNATE_KEY = "lockscreen.password_type_alternate";
     public final static String LOCK_PASSWORD_SALT_KEY = "lockscreen.password_salt";
     public final static String DISABLE_LOCKSCREEN_KEY = "lockscreen.disabled";
-    public final static String LOCKSCREEN_OPTIONS = "lockscreen.options";
-    @Deprecated
-    public final static String LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK
-            = "lockscreen.biometric_weak_fallback";
-    @Deprecated
-    public final static String BIOMETRIC_WEAK_EVER_CHOSEN_KEY
-            = "lockscreen.biometricweakeverchosen";
     public final static String LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS
             = "lockscreen.power_button_instantly_locks";
     @Deprecated
@@ -180,8 +171,6 @@
     public static final String SYNTHETIC_PASSWORD_KEY_PREFIX = "synthetic_password_";
 
     public static final String SYNTHETIC_PASSWORD_HANDLE_KEY = "sp-handle";
-    public static final String SYNTHETIC_PASSWORD_ENABLED_KEY = "enable-sp";
-    public static final int SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT = 1;
     public static final String PASSWORD_HISTORY_DELIMITER = ",";
 
     @UnsupportedAppUsage
@@ -1709,19 +1698,6 @@
         }
     }
 
-    public void enableSyntheticPassword() {
-        setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1L, UserHandle.USER_SYSTEM);
-    }
-
-    public void disableSyntheticPassword() {
-        setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0L, UserHandle.USER_SYSTEM);
-    }
-
-    public boolean isSyntheticPasswordEnabled() {
-        return getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT,
-                UserHandle.USER_SYSTEM) != 0;
-    }
-
     /**
      * Returns whether the given user has pending escrow tokens
      */
diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java
index 9ac6ef7..67b671e 100644
--- a/core/java/com/android/internal/widget/MessagingLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLayout.java
@@ -164,9 +164,9 @@
         Parcelable[] histMessages = extras.getParcelableArray(Notification.EXTRA_HISTORIC_MESSAGES);
         List<Notification.MessagingStyle.Message> newHistoricMessages
                 = Notification.MessagingStyle.Message.getMessagesFromBundleArray(histMessages);
-        setUser(extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON));
+        setUser(extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON, android.app.Person.class));
         RemoteInputHistoryItem[] history = (RemoteInputHistoryItem[])
-                extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS);
+                extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS, android.app.RemoteInputHistoryItem.class);
         addRemoteInputHistoryToMessages(newMessages, history);
         boolean showSpinner =
                 extras.getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false);
diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
index 1cdc108..af9c5a5 100644
--- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java
+++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
@@ -53,7 +53,7 @@
     /**
      * Max width of the whole drawer layout
      */
-    private int mMaxWidth;
+    private final int mMaxWidth;
 
     /**
      * Max total visible height of views not marked always-show when in the closed/initial state
@@ -187,8 +187,10 @@
     }
 
     public void setSmallCollapsed(boolean smallCollapsed) {
-        mSmallCollapsed = smallCollapsed;
-        requestLayout();
+        if (mSmallCollapsed != smallCollapsed) {
+            mSmallCollapsed = smallCollapsed;
+            requestLayout();
+        }
     }
 
     public boolean isSmallCollapsed() {
@@ -200,9 +202,10 @@
     }
 
     public void setShowAtTop(boolean showOnTop) {
-        mShowAtTop = showOnTop;
-        invalidate();
-        requestLayout();
+        if (mShowAtTop != showOnTop) {
+            mShowAtTop = showOnTop;
+            requestLayout();
+        }
     }
 
     public boolean getShowAtTop() {
@@ -220,6 +223,9 @@
     public void setCollapsibleHeightReserved(int heightPixels) {
         final int oldReserved = mCollapsibleHeightReserved;
         mCollapsibleHeightReserved = heightPixels;
+        if (oldReserved != mCollapsibleHeightReserved) {
+            requestLayout();
+        }
 
         final int dReserved = mCollapsibleHeightReserved - oldReserved;
         if (dReserved != 0 && mIsDragging) {
@@ -255,7 +261,7 @@
 
         if (getShowAtTop()) {
             // Keep the drawer fully open.
-            mCollapseOffset = 0;
+            setCollapseOffset(0);
             return false;
         }
 
@@ -264,9 +270,9 @@
             if (remainClosed && (oldCollapsibleHeight < mCollapsibleHeight
                     && mCollapseOffset == oldCollapsibleHeight)) {
                 // Stay closed even at the new height.
-                mCollapseOffset = mCollapsibleHeight;
+                setCollapseOffset(mCollapsibleHeight);
             } else {
-                mCollapseOffset = Math.min(mCollapseOffset, mCollapsibleHeight);
+                setCollapseOffset(Math.min(mCollapseOffset, mCollapsibleHeight));
             }
             final boolean isCollapsedNew = mCollapseOffset != 0;
             if (isCollapsedOld != isCollapsedNew) {
@@ -274,11 +280,18 @@
             }
         } else {
             // Start out collapsed at first unless we restored state for otherwise
-            mCollapseOffset = mOpenOnLayout ? 0 : mCollapsibleHeight;
+            setCollapseOffset(mOpenOnLayout ? 0 : mCollapsibleHeight);
         }
         return true;
     }
 
+    private void setCollapseOffset(float collapseOffset) {
+        if (mCollapseOffset != collapseOffset) {
+            mCollapseOffset = collapseOffset;
+            requestLayout();
+        }
+    }
+
     private int getMaxCollapsedHeight() {
         return (isSmallCollapsed() ? mMaxCollapsedHeightSmall : mMaxCollapsedHeight)
                 + mCollapsibleHeightReserved;
@@ -420,8 +433,7 @@
 
             case MotionEvent.ACTION_POINTER_DOWN: {
                 final int pointerIndex = ev.getActionIndex();
-                final int pointerId = ev.getPointerId(pointerIndex);
-                mActivePointerId = pointerId;
+                mActivePointerId = ev.getPointerId(pointerIndex);
                 mInitialTouchX = ev.getX(pointerIndex);
                 mInitialTouchY = mLastTouchY = ev.getY(pointerIndex);
             }
@@ -924,7 +936,7 @@
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         final int sourceWidth = MeasureSpec.getSize(widthMeasureSpec);
         int widthSize = sourceWidth;
-        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
 
         // Single-use layout; just ignore the mode and use available space.
         // Clamp to maxWidth.
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index 96e9cc1..ff97ab0 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -47,6 +47,7 @@
 per-file android_hardware_SensorManager* = arthuri@google.com, bduddie@google.com, stange@google.com
 
 per-file *Zygote* = file:/ZYGOTE_OWNERS
+per-file core_jni_helpers.* = file:/ZYGOTE_OWNERS
 per-file fd_utils.* = file:/ZYGOTE_OWNERS
 per-file Android.bp = file:platform/build/soong:/OWNERS
 per-file android_animation_* = file:/core/java/android/animation/OWNERS
diff --git a/core/jni/TEST_MAPPING b/core/jni/TEST_MAPPING
new file mode 100644
index 0000000..004c30e
--- /dev/null
+++ b/core/jni/TEST_MAPPING
@@ -0,0 +1,16 @@
+{
+  "presubmit": [
+    {
+      "name": "FrameworksCoreTests",
+      "options": [
+        {
+          "include-filter": "android.util.CharsetUtilsTest"
+        },
+        {
+          "include-filter": "com.android.internal.util.FastDataTest"
+        }
+      ],
+      "file_patterns": ["CharsetUtils|FastData"]
+    }
+  ]
+}
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index 0d530f6..bb4ab39 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -549,10 +549,15 @@
        return NULL;
     }
 
-    // do not marshall if there are binder objects in the parcel
+    if (parcel->isForRpc()) {
+        jniThrowException(env, "java/lang/RuntimeException", "Tried to marshall an RPC Parcel.");
+        return NULL;
+    }
+
     if (parcel->objectsCount())
     {
-        jniThrowException(env, "java/lang/RuntimeException", "Tried to marshall a Parcel that contained Binder objects.");
+        jniThrowException(env, "java/lang/RuntimeException",
+                          "Tried to marshall a Parcel that contains objects (binders or FDs).");
         return NULL;
     }
 
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index f89298a..ab751cb 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -1018,6 +1018,15 @@
                               static_cast<int8_t>(changeFrameRateStrategy));
 }
 
+static void nativeSetDefaultFrameRateCompatibility(JNIEnv* env, jclass clazz, jlong transactionObj,
+                                                   jlong nativeObject, jint compatibility) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
+    const auto ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
+
+    transaction->setDefaultFrameRateCompatibility(ctrl, static_cast<int8_t>(compatibility));
+}
+
 static void nativeSetFixedTransformHint(JNIEnv* env, jclass clazz, jlong transactionObj,
                                         jlong nativeObject, jint transformHint) {
     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
@@ -2157,6 +2166,8 @@
             (void*)nativeSetShadowRadius },
     {"nativeSetFrameRate", "(JJFII)V",
             (void*)nativeSetFrameRate },
+    {"nativeSetDefaultFrameRateCompatibility", "(JJI)V",
+            (void*)nativeSetDefaultFrameRateCompatibility},
     {"nativeGetPhysicalDisplayIds", "()[J",
             (void*)nativeGetPhysicalDisplayIds },
     {"nativeGetPrimaryPhysicalDisplayId", "()J",
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index ef6fd7d..be82879 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -36,7 +36,6 @@
 #include <inttypes.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <linux/fs.h>
 
 #include <memory>
 
@@ -254,16 +253,6 @@
         return INSTALL_FAILED_CONTAINER_ERROR;
     }
 
-    // If a filesystem like f2fs supports per-file compression, set the compression bit before data
-    // writes
-    unsigned int flags;
-    if (ioctl(fd, FS_IOC_GETFLAGS, &flags) == -1) {
-        ALOGE("Failed to call FS_IOC_GETFLAGS on %s: %s\n", localTmpFileName, strerror(errno));
-    } else if ((flags & FS_COMPR_FL) == 0) {
-        flags |= FS_COMPR_FL;
-        ioctl(fd, FS_IOC_SETFLAGS, &flags);
-    }
-
     if (!zipFile->uncompressEntry(zipEntry, fd)) {
         ALOGE("Failed uncompressing %s to %s\n", fileName, localTmpFileName);
         close(fd);
diff --git a/core/jni/com_android_internal_net_NetworkUtilsInternal.cpp b/core/jni/com_android_internal_net_NetworkUtilsInternal.cpp
index 83e2f2b..2279856 100644
--- a/core/jni/com_android_internal_net_NetworkUtilsInternal.cpp
+++ b/core/jni/com_android_internal_net_NetworkUtilsInternal.cpp
@@ -21,17 +21,17 @@
 #include "jni.h"
 
 namespace android {
-static void android_net_utils_setAllowNetworkingForProcess(JNIEnv *env, jobject thiz,
+static void android_net_utils_setAllowNetworkingForProcess(JNIEnv *env, jclass clazz,
                                                            jboolean hasConnectivity) {
     setAllowNetworkingForProcess(hasConnectivity == JNI_TRUE);
 }
 
-static jboolean android_net_utils_protectFromVpn(JNIEnv *env, jobject thiz, jint socket) {
+static jboolean android_net_utils_protectFromVpn(JNIEnv *env, jclass clazz, jint socket) {
     return (jboolean)!protectFromVpn(socket);
 }
 
-static jboolean android_net_utils_protectFromVpnWithFd(JNIEnv *env, jobject thiz, jobject javaFd) {
-    return android_net_utils_protectFromVpn(env, thiz, AFileDescriptor_getFd(env, javaFd));
+static jboolean android_net_utils_protectFromVpnWithFd(JNIEnv *env, jclass clazz, jobject javaFd) {
+    return android_net_utils_protectFromVpn(env, clazz, AFileDescriptor_getFd(env, javaFd));
 }
 
 static const JNINativeMethod gNetworkUtilMethods[] = {
diff --git a/core/proto/android/server/powermanagerservice.proto b/core/proto/android/server/powermanagerservice.proto
index 04f4d7b..bd4f990 100644
--- a/core/proto/android/server/powermanagerservice.proto
+++ b/core/proto/android/server/powermanagerservice.proto
@@ -238,6 +238,7 @@
         optional bool is_stay_on_while_plugged_in_ac = 1;
         optional bool is_stay_on_while_plugged_in_usb = 2;
         optional bool is_stay_on_while_plugged_in_wireless = 3;
+        optional bool is_stay_on_while_plugged_in_dock = 4;
     }
     message ScreenBrightnessSettingLimitsProto {
         option (.android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 92ac389..505ef30 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -578,7 +578,7 @@
     optional WindowStateProto pending_control_target = 6;
     optional WindowStateProto fake_control_target = 7;
     optional .android.view.SurfaceControlProto captured_leash = 8;
-    optional .android.graphics.RectProto ime_overridden_frame = 9;
+    optional .android.graphics.RectProto ime_overridden_frame = 9 [deprecated=true];
     optional bool is_leash_ready_for_dispatching = 10;
     optional bool client_visible = 11;
     optional bool server_visible = 12;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index c2fcd1d..a40a55e 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -484,8 +484,6 @@
 
     <protected-broadcast android:name="android.intent.action.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED" />
     <protected-broadcast android:name="android.intent.action.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED" />
-    <protected-broadcast android:name="android.intent.action.ACTION_SUBINFO_CONTENT_CHANGE" />
-    <protected-broadcast android:name="android.intent.action.ACTION_SUBINFO_RECORD_UPDATED" />
 
     <protected-broadcast android:name="android.intent.action.ACTION_SET_RADIO_CAPABILITY_DONE" />
     <protected-broadcast android:name="android.intent.action.ACTION_SET_RADIO_CAPABILITY_FAILED" />
@@ -4068,6 +4066,11 @@
     <permission android:name="android.permission.BIND_INPUT_METHOD"
         android:protectionLevel="signature" />
 
+    <!-- Allows access to Test APIs defined in {@link android.view.inputmethod.InputMethodManager}.
+         @hide -->
+    <permission android:name="android.permission.TEST_INPUT_METHOD"
+        android:protectionLevel="signature" />
+
     <!-- Must be required by an {@link android.media.midi.MidiDeviceService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature
diff --git a/core/res/res/drawable-nodpi/default_wallpaper.png b/core/res/res/drawable-nodpi/default_wallpaper.png
index 5152972..a23f553 100644
--- a/core/res/res/drawable-nodpi/default_wallpaper.png
+++ b/core/res/res/drawable-nodpi/default_wallpaper.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-nodpi/default_wallpaper.png b/core/res/res/drawable-sw600dp-nodpi/default_wallpaper.png
index 26376fb..1e272e0 100644
--- a/core/res/res/drawable-sw600dp-nodpi/default_wallpaper.png
+++ b/core/res/res/drawable-sw600dp-nodpi/default_wallpaper.png
Binary files differ
diff --git a/core/res/res/drawable-sw720dp-nodpi/default_wallpaper.png b/core/res/res/drawable-sw720dp-nodpi/default_wallpaper.png
index 490ebee..d10c77d 100644
--- a/core/res/res/drawable-sw720dp-nodpi/default_wallpaper.png
+++ b/core/res/res/drawable-sw720dp-nodpi/default_wallpaper.png
Binary files differ
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index d1c3876..e9381e0 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Laat die program toe om die skermslot-kompleksiteitvlak (hoog, medium, laag of geen) te leer, wat die moontlike omvang van die lengte en soort skermslot aandui. Hierdie program kan ook aan gebruikers voorstel dat hulle die skermslot na \'n sekere vlak opdateer, maar gebruikers kan dit uit vrye wil ignoreer en weggaan. Let daarop dat die skermslot nie in skoonteks geberg word nie en die program dus nie die presiese wagwoord ken nie."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"wys kennisgewings"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Laat die program toe om kennisgewings te wys"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"skakel die skerm aan"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Laat die program toe om die skerm aan te skakel."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"gebruik biometriese hardeware"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Laat die program toe om biometriese hardeware vir stawing te gebruik"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"bestuur vingerafdrukhardeware"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Kan nie toegang tot die foon se kamera op jou <xliff:g id="DEVICE">%1$s</xliff:g> kry nie"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Kan nie toegang tot die tablet se kamera op jou <xliff:g id="DEVICE">%1$s</xliff:g> kry nie"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Stelselverstek"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 21751c8..78f383c 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -416,7 +416,7 @@
     <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"መተግበሪያው በእርስዎ ስልክ ላይ ስለተከማቹ እውቂያዎችዎ ያለ ውሂብን እንዲቀይር ያስችለዋል። ይህ ፈቃድ መተግበሪያዎች የእውቂያ ውሂብን እንዲሰርዙ ያስችላቸዋል።"</string>
     <string name="permlab_readCallLog" msgid="1739990210293505948">"የጥሪ ምዝግብ ማስታወሻን ያንብቡ"</string>
     <string name="permdesc_readCallLog" msgid="8964770895425873433">"ይህ መተግበሪያ የእርስዎን የጥሪ ታሪክ ማንበብ ይችላል።"</string>
-    <string name="permlab_writeCallLog" msgid="670292975137658895">"የጥሪ ምዝግብ ማስታወሻን ፃፍ"</string>
+    <string name="permlab_writeCallLog" msgid="670292975137658895">"የጥሪ ምዝግብ ማስታወሻን ጻፍ"</string>
     <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"ስለ ገቢ እና ወጪ ጥሪዎችን ውሂብ ጨምሮ፣ የጡባዊተኮህን ምዝግብ ማስታወሻ ለመቀየር ለመተግበሪያው ይፈቅዳል። ይሄንን ተንኮል አዘል መተግበሪያዎች የስልክህን ምዝግብ ማስታወሻ ለመሰረዝ ወይም ለመለወጥ ሊጠቀሙበት ይችላሉ።"</string>
     <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"መተግበሪያው ስለገቢ እና ወጪ ጥሪዎች ያለ ውሂብም ጨምሮ የእርስዎ Android TV መሣሪያ ምዝግብ ማስታወሻ እንዲቀይር ያስችለዋል። ተንኮል-አዘል መተግበሪያዎች ይህን ተጠቅመው የስልክዎን ምዝግብ ማስታወሻ ሊደመስሱ ወይም ሊቀይሩ ይችላሉ።"</string>
     <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"ስለ ገቢ እና ወጪ ጥሪዎችን ውሂብ ጨምሮ፣ የስልክህን ምዝግብ ማስታወሻ ለመቀየር ለመተግበሪያው ይፈቅዳል። ይሄንን ተንኮል አዘል መተግበሪያዎች የስልክህን ምዝግብ ማስታወሻ ለመሰረዝ ወይም ለመለወጥ ሊጠቀሙበት ይችላሉ።"</string>
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"መተግበሪያው የማያ ገጽ መቆለፊያው ውስብስብነት ደረጃ (ከፍተኛ፣ መካከለኛ፣ ዝቅተኛ ወይም ምንም) እንዲያውቅ ያስችለዋል፣ ይህም ሊሆኑ የሚችለው የማያ ገጽ መቆለፊያው ርዝመት እና ዓይነት ክልል ያመለክታል። መተግበሪያው እንዲሁም ለተጠቃሚዎች የማያ ገጽ መቆለፊያውን ወደተወሰነ ደረጃ እንዲያዘምኑት ሊጠቁማቸው ይችላል። የማያ ገጽ መቆለፊያው በስነጣ አልባ ጽሑፍ እንደማይከማች ልብ ይበሉ፣ በዚህም መተግበሪያው ትክክለኛውን የይለፍ ቃል አያውቅም።"</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"ማሳወቂያዎች አሳይ"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"መተግበሪያው ማሳወቂያዎችን እንዲያሳይ ያስችለዋል"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"ማያ ገጹን አብራ"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"መተግበሪያው ማያ ገጹን እንዲያበራ ይፈቅድለታል።"</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"ባዮሜትራዊ ሃርድዌርን መጠቀም"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"መተግበሪያው የባዮሜትራዊ ሃርድዌር ለማረጋገጥ ስራ እንዲጠቀም ያስችለዋል"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"የጣት አሻራ ሃርድዌርን አስተዳድር"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"የስልኩን ካሜራ ከእርስዎ <xliff:g id="DEVICE">%1$s</xliff:g> መድረስ አይቻልም"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ጡባዊውን ካሜራ ከእርስዎ <xliff:g id="DEVICE">%1$s</xliff:g> መድረስ አይቻልም"</string>
     <string name="system_locale_title" msgid="711882686834677268">"የሥርዓት ነባሪ"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index b75f962..5d25ba4 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -557,6 +557,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"للسماح للتطبيق بمعرفة مستوى صعوبة قفل الشاشة (عالي أو متوسط أو منخفض الصعوبة أو بدون)، والذي يحدّد النطاق المحتمل لطول ونوع قفل الشاشة. ويمكن أن يقترح التطبيق للمستخدمين أيضًا تعديل قفل الشاشة إلى مستوى معيّن، ولهم مطلق الحرية في تجاهل هذا الاقتراح ورفضه. وتجدر الإشارة إلى أنه لا يتم حفظ قفل الشاشة في نص عادي، لذا لا يعرف التطبيق كلمة المرور تحديدًا."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"عرض الإشعارات"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"السماح للتطبيق بعرض إشعارات"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"تفعيل الشاشة"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"يسمح هذا الإذن للتطبيق بتفعيل الشاشة."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"استخدام الأجهزة البيومترية"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"للسماح للتطبيق باستخدام الأجهزة البيومترية للمصادقة"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"لإدارة أجهزة بصمة الإصبع"</string>
@@ -2079,10 +2081,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"مزيد من المعلومات"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"‏تم إبدال الإشعارات التكيُّفية لنظام التشغيل Android في الإصدار 12 منه بالإشعارات المحسّنة. تعرض هذه الميزة إجراءات وردودًا مقترحة وتنظِّم الإشعارات.\n\nيمكن للإشعارات المحسّنة الوصول إلى محتوى الإشعارات، بما في ذلك المعلومات الشخصية، مثلاً أسماء جهات الاتصال والرسائل. يمكن لهذه الميزة أيضًا إغلاق الإشعارات أو الاستجابة لها، مثلاً الردّ على مكالمات الهاتف والتحكّم في ميزة \"عدم الإزعاج\"."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"إشعار معلومات \"وضع سلسلة الإجراءات\""</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"تم تفعيل ميزة توفير شحن البطارية"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"يتم تقليل استخدام البطارية لإطالة عمرها."</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"توفير شحن البطارية"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"تم تفعيل ميزة \"توفير شحن البطارية\""</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"تم شحن الهاتف بدرجة كافية وتفعيل الميزات مرة أخرى"</string>
@@ -2290,4 +2290,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"يتعذّر الوصول إلى كاميرا الهاتف من على جهاز <xliff:g id="DEVICE">%1$s</xliff:g>."</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"يتعذّر الوصول إلى كاميرا الجهاز اللوحي من على جهاز <xliff:g id="DEVICE">%1$s</xliff:g>."</string>
     <string name="system_locale_title" msgid="711882686834677268">"الإعداد التلقائي للنظام"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index c1c1e96..3964725 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"এপ্‌টোক স্ক্ৰীন লকৰ জটিলতাৰ স্তৰ (উচ্চ, মধ্যম, নিম্ন বা একেবাৰে নাই)ৰ বিষয়ে জানিবলৈ অনুমতি দিয়ে, যিয়ে স্ক্ৰীন লকৰ সম্ভাব্য দৈৰ্ঘ্য বা স্ক্ৰীন লকৰ প্ৰকাৰ দৰ্শায়। লগতে এপ্‌টোৱে ব্যৱহাৰকাৰীক স্ক্ৰীন লকটো এটা নিৰ্দিষ্ট স্তৰলৈ আপডে’ট কৰিবলৈ পৰামৰ্শ দিব পাৰে যিটো ব্যৱহাৰকাৰীয়ে অৱজ্ঞা কৰি পৰৱর্তী পৃষ্ঠালৈ যাব পাৰে। মনত ৰাখিব যে স্ক্ৰীন লকটো সাধাৰণ পাঠ হিচাপে ষ্ট\'ৰ কৰা নহয়; সেয়েহে, এপ্‌টোৱে সঠিক পাছৱৰ্ডটো জানিব নোৱাৰে।"</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"জাননী দেখুৱাওক"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"এপ্‌টোক জাননী দেখুৱাবলৈ দিয়ে"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"স্ক্ৰীনখন অন কৰক"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"এপ্‌টোক স্ক্ৰীনখন অন কৰিবলৈ দিয়ে।"</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"বায়োমেট্ৰিক হাৰ্ডৱেৰ ব্যৱহাৰ কৰক"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"বিশ্বাসযোগ্য়তা প্ৰমাণীকৰণৰ বাবে এপক বায়োমেট্ৰিক হাৰ্ডৱেৰ ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়ে"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"ফিংগাৰপ্ৰিণ্ট হাৰ্ডৱেৰ পৰিচালনা কৰিব পাৰে"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"অধিক জানক"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12ত Androidৰ অভিযোজিত জাননীক উন্নত জাননীৰ দ্বাৰা সলনি কৰা হৈছে। এই সুবিধাটোৱে পৰামৰ্শ দিয়া কাৰ্য আৰু প্ৰত্যুত্তৰ দেখুৱায় আৰু আপোনাৰ জাননীসমূহ শৃংখলাবদ্ধ কৰে।\n\nউন্নত জাননীয়ে সম্পৰ্কৰ নাম আৰু বাৰ্তাৰ দৰে ব্যক্তিগত তথ্যকে ধৰি জাননীৰ সমল এক্সেছ কৰিব পাৰে। এই সুবিধাটোৱে জাননী অগ্ৰাহ্য কৰিব অথবা জাননীৰ প্ৰতি সঁহাৰি জনাবও পাৰে, যেনে ফ’ন কলৰ উত্তৰ দিয়া আৰু অসুবিধা নিদিব সুবিধাটো নিয়ন্ত্ৰণ কৰা আদি।"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ৰুটিন ম’ডৰ তথ্য জাননী"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"বেটাৰী সঞ্চয়কাৰী অন কৰা হৈছে"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"বেটাৰীৰ জীৱনকাল বৃদ্ধি কৰিবলৈ বেটাৰীৰ ব্যৱহাৰ কমোৱা হৈছে"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"বেটাৰী সঞ্চয়কাৰী"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"বেটাৰী সঞ্চয়কাৰী অফ কৰা হ’ল"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"ফ\'নটোত পর্যাপ্ত পৰিমাণে চার্জ আছে। সুবিধাবোৰ আৰু সীমাবদ্ধ কৰা নাই।"</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ৰ পৰা ফ’নটোৰ কেমেৰা এক্সেছ কৰিব নোৱাৰি"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ৰ পৰা টেবলেটটোৰ কেমেৰা এক্সেছ কৰিব নোৱাৰি"</string>
     <string name="system_locale_title" msgid="711882686834677268">"ছিষ্টেম ডিফ’ল্ট"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 8343ae6..c41f4d7 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Tətbiqin ekran kilidinin uzunluğunu və növünü göstərən mürəkəblilik dərəcəsini (yüksək, orta, aşağı və ya heç biri) öyrənməsinə icazə verir. Tətbiq ekran kilidinin müəyyən səviyyəyə yenilənməsini təklif edə bilər. İstifadəçilər bu təklifdən imtina edə və davam edə bilər. Yadda saxlayın ekran kilidi açıq mətn formatında saxlanılmır, buna görə də tətbiq dəqiq parolu bilməyəcək."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"bildirişləri göstərmək"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Tətbiqə bildirişləri göstərmək icazəsi verir"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"ekranı aktiv etmək"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Tətbiqə ekranı aktiv etməyə icazə verir."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"biometrik proqramdan istifadə edin"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Doğrulama üçün biometrik proqramdan istifadə etməyə imkan verir"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"barmaq izi avadanlığını idarə edin"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Ətraflı məlumat"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12-də qabaqcıl bildirişlər var. Bu funksiya bütün bildirişləri qaydaya salır, cavab və əməliyyatlara dair tövsiyə verir.\n\nFunksiyanın kontaktlar, mesajlar və şəxsi məlumatlar daxil olmaqla bütün bildirişlərə girişi var. Zənglərə cavab verə, \"Narahat etməyin\" rejimini idarə edə, bildirişləri qapada və cavablaya bilər."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Rejim üçün məlumat bildirişi"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Enerjiyə Qənaət aktivdir"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Batareyanın ömrünü uzatmaq üçün batareyadan istifadəni azaldın"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Enerjiyə qənaət"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Enerjiyə qənaət deaktivdir"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Telefonun kifayət qədər enerjisi var. Funksiyalar artıq məhdud deyil."</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan telefonun kamerasına giriş etmək olmur"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan planşetin kamerasına giriş etmək olmur"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Sistem defoltu"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index f1efc7a..9bc0a91 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -554,6 +554,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Dozvoljava aplikaciji da sazna nivo složenosti zaključavanja ekrana (visoka, srednja, niska ili nijedna), što ukazuje na mogući opseg trajanja i tip zaključavanja ekrana. Aplikacija može i da predlaže korisnicima da ažuriraju zaključavanje ekrana na određeni nivo, ali korisnici slobodno mogu da zanemare to i da idu na druge stranice. Imajte na umu da se podaci za zaključavanje ekrana ne čuvaju kao običan tekst, pa aplikacija ne zna tačnu lozinku."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"prikazivanje obaveštenja"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Dozvoljava aplikaciji da prikazuje obaveštenja"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"uključivanje ekrana"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Dozvoljava aplikaciji da uključi ekran."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"koristi biometrijski hardver"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Dozvoljava aplikaciji da koristi biometrijski hardver za potvrdu identiteta"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"upravljaj hardverom za otiske prstiju"</string>
@@ -2285,4 +2287,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ne može da se pristupi kameri telefona sa <xliff:g id="DEVICE">%1$s</xliff:g> uređaja"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ne može da se pristupi kameri tableta sa <xliff:g id="DEVICE">%1$s</xliff:g> uređaja"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Podrazumevani sistemski"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 7c313c8..34bbb0e 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -555,6 +555,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Дазваляе праграме вызначаць узровень складанасці блакіроўкі экрана (высокі, сярэдні, нізкі ці нулявы), які залежыць ад даўжыні пароля і ад тыпу блакіроўкі экрана. Праграма можа прапанаваць карыстальнікам ускладніць блакіроўку экрана, аднак гэту прапанову можна ігнараваць. Заўважце, што праграма не можа ведаць тып і пароль блакіроўкі экрана, таму што яны захоўваюцца ў зашыфраваным выглядзе."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"паказваць апавяшчэнні"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Дазваляе праграме паказваць апавяшчэнні"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"уключаць экран"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Дазваляе праграме ўключаць экран."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"выкарыстоўваць біяметрычнае абсталяванне"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Дазваляе праграме выкарыстоўваць для аўтэнтыфікацыі біяметрычнае абсталяванне"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"кіраваць апаратнымі сродкамі для адбіткаў пальцаў"</string>
@@ -2077,10 +2079,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Даведацца больш"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"У версіі Android 12 Адаптыўныя апавяшчэнні Android заменены Палепшанымі апавяшчэннямі. Гэта функцыя ўпарадкоўвае вашы апавяшчэнні і паказвае прапановы дзеянняў і адказаў.\n\nПалепшаныя апавяшчэнні маюць доступ да змесціва ўсіх апавяшчэнняў, у тым ліку да асабістай інфармацыі – імён кантактаў і паведамленняў. Яшчэ гэта функцыя можа адхіляць апавяшчэнні ці адказваць на іх, напрыклад рэагаваць на тэлефонныя выклікі і кіраваць функцыяй \"Не турбаваць\"."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Апавяшчэнне з інфармацыяй пра ўсталяваны рэжым"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Рэжым энергазберажэння ўключаны"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Абмежаванне выкарыстання зараду для падаўжэння часу працы ад акумулятара"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Рэжым энергазберажэння"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Рэжым эканоміі зараду выключаны"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"У тэлефона дастатковы ўзровень зараду. Функцыі больш не абмежаваны."</string>
@@ -2288,4 +2288,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Не ўдалося атрымаць доступ да камеры тэлефона з прылады \"<xliff:g id="DEVICE">%1$s</xliff:g>\""</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Не ўдалося атрымаць доступ да камеры планшэта з прылады \"<xliff:g id="DEVICE">%1$s</xliff:g>\""</string>
     <string name="system_locale_title" msgid="711882686834677268">"Стандартная сістэмная налада"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index d52e3e2..575e3471 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Разрешава на приложението да разбере нивото на сложност на опцията за заключване на екрана (високо, средно, ниско или липса на такова), което указва възможния диапазон на дължината и типа на опцията. Приложението може също да предложи на потребителите да актуализират опцията за заключване на екрана до определено ниво, но те могат да пренебрегнат това и да излязат от него. Обърнете внимание, че опцията за заключване на екрана не се съхранява като обикновен текст, така че приложението не знае точната парола."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"показване на известията"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Разрешава на приложението да показва известия"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"включване на екрана"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Разрешава на приложението да включва екрана."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"използване на хардуера за биометрични данни"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Разрешава на приложението да използва хардуера за биометрични данни с цел удостоверяване"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"управление на хардуера за отпечатъци"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Научете повече"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Адаптивните известия бяха заменени от функцията за подобрени известия в Android 12. Тя показва предложени действия и отговори и организира известията ви.\n\nФункцията може да осъществява достъп до съдържанието в известията, включително личната информация, като например имената на контактите и текстовите съобщения. Тя има възможност да отхвърля известията или да предприема действия в тях, като например приемане на телефонни обаждания или контролиране на режима „Не безпокойте“."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Известие с информация за режима на поредица"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Режимът за запазване на батерията е включен"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Използването на батерията се намалява с цел удължаване на живота ѝ"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Режим за запазване на батерията"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Режимът за запазване на батерията е изключен"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Батерията на телефона има достатъчно заряд. Функциите вече не са ограничени."</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Няма достъп до камерата на телефона от вашия <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Няма достъп до камерата на таблета от вашия <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Стандартно за системата"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 7ba759f..45935fa 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"এটি অ্যাপটিকে স্ক্রিন লকের জটিলতার লেভেল বুঝতে সাহায্য করে (খুব বেশি, মাঝারি, অল্প জটিল বা কোনও জটিলতা নেই), যা স্ক্রিন লকটি সম্ভবত কত দীর্ঘ ও সেটির ধরন কীরকম, তার ইঙ্গিত দেয়। এই অ্যাপটি একটি নির্দিষ্ট লেভেল পর্যন্ত স্ক্রিন লক আপডেট করার সাজেশনও দিতে পারে, তবে ব্যবহারকারী তা উপেক্ষা করে অন্য কোথাও চলে যেতে পারেন। মনে রাখবেন যে স্ক্রিন লক প্লেন টেক্সট হিসেবে সংরক্ষণ করা হয় না, তাই অ্যাপ কখনও আসল পাসওয়ার্ড জানতে পারে না।"</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"বিজ্ঞপ্তি দেখুন"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"অ্যাপকে বিজ্ঞপ্তি দেখানোর জন্য অনুমতি দেয়"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"স্ক্রিন চালু করতে চাই"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"অ্যাপকে স্ক্রিন চালু করার অনুমতি দেয়।"</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"বায়োমেট্রিক হার্ডওয়্যার ব্যবহার করুন"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"অ্যাপটিকে যাচাইকরণের জন্য বায়োমেট্রিক হার্ডওয়্যার ব্যবহার করার অনুমতি দেয়"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"আঙ্গুলের ছাপ নেওয়ার হার্ডওয়্যার পরিচালনা করুন"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"আপনার <xliff:g id="DEVICE">%1$s</xliff:g> থেকে ফোনের ক্যামেরা অ্যাক্সেস করা যাচ্ছে না"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"আপনার <xliff:g id="DEVICE">%1$s</xliff:g> থেকে ট্যাবলেটের ক্যামেরা অ্যাক্সেস করা যাচ্ছে না"</string>
     <string name="system_locale_title" msgid="711882686834677268">"সিস্টেম ডিফল্ট"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 5616dd8..0b8d3d3 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -554,6 +554,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Omogućava aplikaciji da sazna nivo kompleksnosti zaključavanja ekrana (visoki, srednji, niski ili bez zaključavanja), što naznačava mogući raspon trajanja i vrste zaključavanja ekrana. Aplikacija također može korisnicima predložiti da ažuriraju zaključavanje ekrana do određenog nivoa, ali korisnici slobodno mogu ignorirati prijedlog i napustiti stranicu. Važno je napomenuti da se zaključavanje ekrana ne pohranjuje kao obični tekst tako da aplikacija ne zna tačnu lozinku."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"prikaz obavještenja"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Dozvoljava aplikaciji da prikazuje obavještenja"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"uključivanje ekrana"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Omogućava aplikaciji da uključi ekran."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"koristi biometrijski hardver za otiske prstij"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Omogućava aplikaciji da za autentifikaciju koristi biometrijski hardver"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"upravljanje hardverom za otisak prsta"</string>
@@ -2076,8 +2078,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Saznajte više"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Poboljšana obavještenja su zamijenila Prilagodljiva obavještenja Androida u verziji Android 12. Ova funkcija prikazuje predložene radnje i odgovore te organizira vaša obavještenja.\n\nPoboljšana obavještenja mogu pristupiti sadržaju obavještenja, uključujući lične informacije kao što su imena kontakata i poruke. Ova funkcija također može odbacivati obavještenja ili reagirati na njih, npr. može odgovarati na telefonske pozive i kontrolirati funkciju Ne ometaj."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Obavještenje za informacije Rutinskog načina"</string>
-    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Uključena je štednja baterije"</string>
-    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Smanjuje se potrošnja baterije radi produženja njezinog trajanja"</string>
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Ušteda baterije je uključena"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Smanjena je potrošnja baterije da se produži vijek trajanja baterije"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Ušteda baterije"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Ušteda baterije je isključena"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Telefon se dovoljno napunio. Funkcije nisu više ograničene."</string>
@@ -2285,4 +2287,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nije moguće pristupiti kameri telefona s uređaja <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nije moguće pristupiti kameri tableta s uređaja <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Sistemski zadano"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 70faff5..c595ee1 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Permet que l\'aplicació conegui el nivell de complexitat del bloqueig de pantalla (alt, mitjà, baix o cap), que indica la llargària i el tipus de bloqueig de pantalla possibles. L\'aplicació també pot suggerir que els usuaris actualitzin el bloqueig de pantalla a un nivell determinat, però els usuaris poden ignorar aquestes recomanacions. Tingues en compte que el bloqueig de pantalla no s\'emmagatzema com a text sense format, de manera que l\'aplicació no coneix la contrasenya exacta."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"mostra notificacions"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Permet que l\'aplicació mostri notificacions"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"activar la pantalla"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Permet a l\'aplicació activar la pantalla."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"utilitza maquinari biomètric"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Permet que l\'aplicació faci servir maquinari biomètric per a l\'autenticació"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"Gestionar el maquinari d\'empremtes digitals"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"No es pot accedir a la càmera del telèfon des del teu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"No es pot accedir a la càmera de la tauleta des del teu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Valor predeterminat del sistema"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index c42b888..cf7fc26 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -555,6 +555,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Umožňuje aplikaci zjistit úroveň složitosti zámku obrazovky (vysoká, střední, nízká nebo žádná), která ukazuje možnou délku a typ zámku obrazovky. Aplikace také může uživatelům navrhovat, aby zámek obrazovky upravili na určitou úroveň, ale uživatelé mohou návrhy klidně ignorovat a odejít. Zámek obrazovky není uložen jako prostý text, a tak aplikace přesné heslo nezná."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"zobrazovat oznámení"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Povolí aplikaci zobrazovat oznámení"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"zapnutí obrazovky"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Umožňuje aplikaci zapnout obrazovku."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"použití biometrického hardwaru"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Umožňuje aplikaci použít k ověření biometrický hardware"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"správa hardwaru na čtení otisků prstů"</string>
@@ -2286,4 +2288,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ze zařízení <xliff:g id="DEVICE">%1$s</xliff:g> nelze získat přístup k fotoaparátu telefonu"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ze zařízení <xliff:g id="DEVICE">%1$s</xliff:g> nelze získat přístup k fotoaparátu tabletu"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Výchozí nastavení systému"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 80476bb..749b5e8 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Giver appen tilladelse til at kende skærmlåsens kompleksitet (høj, medium, lav eller ingen), hvilket kan afsløre oplysninger om skærmlåsens længde og type. Appen kan også foreslå brugerne at opdatere deres skærmlås til et bestemt niveau, men brugerne kan frit ignorere det og gå videre. Bemærk! Skærmlåsen gemmes ikke som almindelig tekst, så appen kender ikke den nøjagtige adgangskode."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"vise notifikationer"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Giver appen tilladelse til at vise notifikationer"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"tænd skærmen"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Tillader, at appen tænder skærmen."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"brug biometrisk hardware"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Tillader, at appen kan bruge biometrisk hardware til godkendelse"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"administrer hardware til fingeraftryk"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Kameraet på din telefon kan ikke tilgås via din <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Kameraet på din tablet kan ikke tilgås via din <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Systemstandard"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 4cfb46f..8759640 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Ermöglicht es der App, die Komplexitätsstufe der Displaysperre (hoch, mittel, niedrig oder keine) zu ermitteln, was auf Art und mögliche Dauer der Displaysperre hinweist. Die App kann Nutzern auch vorschlagen, die Displaysperre auf eine bestimmte Stufe zu setzen. Nutzer können diesen Vorschlag jedoch einfach ignorieren und fortfahren. Beachten Sie, dass die Displaysperre nicht im Klartext gespeichert ist, sodass die App nicht das genaue Passwort kennt."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"Benachrichtigungen anzeigen"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Ermöglicht der App, Benachrichtigungen anzuzeigen"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"das Display einschalten"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Ermöglicht der App, das Display einzuschalten."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"Biometrische Hardware verwenden"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Erlaubt der App, biometrische Hardware zur Authentifizierung zu verwenden"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"Fingerabdruckhardware verwalten"</string>
@@ -1625,7 +1627,7 @@
     <string name="display_manager_built_in_display_name" msgid="1015775198829722440">"Integrierter Bildschirm"</string>
     <string name="display_manager_hdmi_display_name" msgid="1022758026251534975">"HDMI-Bildschirm"</string>
     <string name="display_manager_overlay_display_name" msgid="5306088205181005861">"Overlay-Nr. <xliff:g id="ID">%1$d</xliff:g>"</string>
-    <string name="display_manager_overlay_display_title" msgid="1480158037150469170">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_title" msgid="1480158037150469170">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> × <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="2810034719482834679">", sicher"</string>
     <string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"Muster vergessen"</string>
     <string name="kg_wrong_pattern" msgid="1342812634464179931">"Falsches Muster"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Weitere Informationen"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Die adaptiven Benachrichtigungen wurden in Android 12 durch die Funktion „Erweiterte Benachrichtigungen“ ersetzt. Diese Funktion zeigt Vorschläge für Aktionen und Antworten an und sortiert Benachrichtigungen.\n\nDie Funktion hat Zugriff auf alle Benachrichtigungen, darunter auch personenbezogene Daten wie Kontaktnamen und Nachrichten. Außerdem kann sie auf Benachrichtigungen antworten oder diese schließen und so beispielsweise Anrufe entgegennehmen oder „Bitte nicht stören“ steuern."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Infomitteilung zum Ablaufmodus"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Energiesparmodus aktiviert"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Reduzierung der Akkunutzung, um die Akkulaufzeit zu verlängern"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Energiesparmodus"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Energiesparmodus deaktiviert"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Das Smartphone ist ausreichend geladen. Es sind keine Funktionen mehr beschränkt."</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Zugriff auf die Kamera des Smartphones über dein Gerät (<xliff:g id="DEVICE">%1$s</xliff:g>) nicht möglich"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Zugriff auf die Kamera des Tablets über dein Gerät (<xliff:g id="DEVICE">%1$s</xliff:g>) nicht möglich"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Standardeinstellung des Systems"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index b246d0b..7f8160c 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Επιτρέπει στην εφαρμογή να μάθει το επίπεδο πολυπλοκότητας του κλειδώματος οθόνης (υψηλό, μέσο, χαμηλό ή κανένα), το οποίο υποδεικνύει το πιθανό εύρος του μήκους και του τύπου κλειδώματος οθόνης. Η εφαρμογή μπορεί επίσης να προτείνει στους χρήστες να ενημερώσουν το κλείδωμα οθόνης σε ένα συγκεκριμένο επίπεδο, όμως οι χρήστες μπορούν να την αγνοήσουν και να συνεχίσουν. Λάβετε υπόψη ότι το κλείδωμα οθόνης δεν αποθηκεύεται σε απλό κείμενο. Συνεπώς, η εφαρμογή δεν γνωρίζει τον κωδικό."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"εμφάνιση ειδοποιήσεων"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Επιτρέπει στην εφαρμογή να εμφανίζει ειδοποιήσεις"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"ενεργοποίηση της οθόνης"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Επιτρέπει στην εφαρμογή να ενεργοποιεί την οθόνη."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"χρήση βιομετρικού εξοπλισμού"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Επιτρέπει στην εφαρμογή να χρησιμοποιεί βιομετρικό εξοπλισμό για έλεγχο ταυτότητας"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"διαχείριση εξοπλισμού δακτυλικού αποτυπώματος"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Δεν είναι δυνατή η πρόσβαση στην κάμερα του τηλεφώνου από τη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Δεν είναι δυνατή η πρόσβαση στην κάμερα του tablet από τη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Προεπιλογή συστήματος"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 32ad56dc..138bb3b 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Allows the app to learn the screen lock complexity level (high, medium, low or none), which indicates the possible range of length and type of the screen lock. The app can also suggest to users that they update the screen lock to a certain level but users can freely ignore and navigate away. Note that the screen lock is not stored in plain text so the app does not know the exact password."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"show notifications"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Allows the app to show notifications"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"turn on the screen"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Allows the app to turn on the screen."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"use biometric hardware"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Allows the app to use biometric hardware for authentication"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"manage fingerprint hardware"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Can’t access the phone’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Can’t access the tablet’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"System default"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index a678b28..1972db3 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Allows the app to learn the screen lock complexity level (high, medium, low or none), which indicates the possible range of length and type of the screen lock. The app can also suggest to users that they update the screen lock to a certain level but users can freely ignore and navigate away. Note that the screen lock is not stored in plain text so the app does not know the exact password."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"show notifications"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Allows the app to show notifications"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"turn on the screen"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Allows the app to turn on the screen."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"use biometric hardware"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Allows the app to use biometric hardware for authentication"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"manage fingerprint hardware"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Can’t access the phone’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Can’t access the tablet’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"System default"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 38c97db..bb3a9d1 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Allows the app to learn the screen lock complexity level (high, medium, low or none), which indicates the possible range of length and type of the screen lock. The app can also suggest to users that they update the screen lock to a certain level but users can freely ignore and navigate away. Note that the screen lock is not stored in plain text so the app does not know the exact password."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"show notifications"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Allows the app to show notifications"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"turn on the screen"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Allows the app to turn on the screen."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"use biometric hardware"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Allows the app to use biometric hardware for authentication"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"manage fingerprint hardware"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Can’t access the phone’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Can’t access the tablet’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"System default"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 06dd854..526b0d5 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Allows the app to learn the screen lock complexity level (high, medium, low or none), which indicates the possible range of length and type of the screen lock. The app can also suggest to users that they update the screen lock to a certain level but users can freely ignore and navigate away. Note that the screen lock is not stored in plain text so the app does not know the exact password."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"show notifications"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Allows the app to show notifications"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"turn on the screen"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Allows the app to turn on the screen."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"use biometric hardware"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Allows the app to use biometric hardware for authentication"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"manage fingerprint hardware"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Can’t access the phone’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Can’t access the tablet’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"System default"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 1bac742..daa0685 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‏‎‎‎‎‏‎‏‏‎‎‎‎‎‏‏‏‎Allows the app to learn the screen lock complexity level (high, medium, low or none), which indicates the possible range of length and type of the screen lock. The app can also suggest to users that they update the screen lock to a certain level but users can freely ignore and navigate away. Note that the screen lock is not stored in plaintext so the app does not know the exact password.‎‏‎‎‏‎"</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‏‎‎‎‏‏‏‎‎‏‏‏‏‎‎‎‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‏‎‏‎‎‎‏‎‏‎‎show notifications‎‏‎‎‏‎"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‏‎‎‏‎‏‎‎‎‏‏‎‏‏‎‏‎‏‎‏‏‏‏‎‏‎‏‎‏‏‎‎‏‎‎‏‏‎Allows the app to show notifications‎‏‎‎‏‎"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‎‏‎‎‎‏‎‎‎‏‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‎‎turn on the screen‎‏‎‎‏‎"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‏‏‎‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎‏‎‏‏‏‎‏‏‎‎‏‏‏‏‎‎‎‎‏‎‏‏‏‎Allows the app to turn on the screen.‎‏‎‎‏‎"</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‏‎‏‎‎use biometric hardware‎‏‎‎‏‎"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‎‏‏‏‎‎‏‎‎Allows the app to use biometric hardware for authentication‎‏‎‎‏‎"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎‎‎‏‎‎‎‏‏‎‏‏‎‎‏‏‎‎‎‎‏‎‎‏‎‎‏‎‏‎‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‎‎manage fingerprint hardware‎‏‎‎‏‎"</string>
@@ -2284,4 +2286,5 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‎‎‎‎‎‎‎‎‎‎‎‎‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‏‏‏‎‎‎‎‏‎‏‏‎‏‎‏‏‏‏‏‎‎‏‎‎‏‎Can’t access the phone’s camera from your ‎‏‎‎‏‏‎<xliff:g id="DEVICE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‏‏‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‎‏‏‏‎‏‎‏‏‎‏‎‎‎‎‏‏‎‏‏‎‏‎‎‎Can’t access the tablet’s camera from your ‎‏‎‎‏‏‎<xliff:g id="DEVICE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="system_locale_title" msgid="711882686834677268">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‎‏‏‏‎‏‎‎‎‏‎‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‏‎‎‎System default‎‏‎‎‏‎"</string>
+    <string name="default_card_name" msgid="9198284935962911468">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‎CARD ‎‏‎‎‏‏‎<xliff:g id="CARDNUMBER">%d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
 </resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index f67c659..2b46223 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Permite que la app conozca el nivel de complejidad del bloqueo de pantalla (alta, media, baja o ninguna), lo que indica el rango de duración posible y el tipo de bloqueo. La app también puede sugerirles a los usuarios que actualicen el bloqueo de pantalla a un determinado nivel, aunque ellos pueden ignorar esta sugerencia y seguir navegando. Ten en cuenta que el bloqueo de pantalla no se almacena como texto sin formato, por lo que la app no conoce la contraseña exacta."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"mostrar notificaciones"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Permite que la app muestre notificaciones"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"encender la pantalla"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Permite que la app encienda la pantalla."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"usar hardware biométrico"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Permite que la app use hardware biométrico para realizar la autenticación"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"Administrar el hardware de huellas dactilares"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"No se puede acceder a la cámara del dispositivo desde tu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"No se puede acceder a la cámara de la tablet desde tu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Predeterminado del sistema"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 408d71d..a71491b 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Permite que la aplicación entienda el nivel de complejidad del bloqueo de pantalla (alto, medio, bajo o ninguno) que indica la longitud y el tipo del bloqueo de pantalla posibles. La aplicación también puede sugerir a los usuarios que actualicen el bloqueo de pantalla para que tenga un nivel concreto de complejidad, pero los usuarios pueden ignorar la advertencia libremente. El bloqueo de pantalla no se almacena en texto sin formato, así que la aplicación no puede saber cuál es la contraseña exacta."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"mostrar notificaciones"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Permite que la aplicación muestre notificaciones"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"encender la pantalla"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Permite que la aplicación active la pantalla."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"usar hardware biométrico"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Permite que la aplicación utilice el hardware biométrico para realizar la autenticación"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"administrar hardware de huellas digitales"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Más información"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Las notificaciones mejoradas sustituyeron las notificaciones adaptativas en Android 12. Esta función te muestra acciones y respuestas sugeridas, y organiza tus notificaciones.\n\nLas notificaciones mejoradas pueden acceder al contenido de tus notificaciones, incluida información personal, como nombres de contactos y mensajes. También permiten descartar o responder a notificaciones; por ejemplo, es posible contestar llamadas telefónicas y controlar el modo No molestar."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificación sobre el modo rutina"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Ahorro de batería activado"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Reduciendo el uso de batería para prolongar su duración"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Ahorro de batería"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Ahorro de batería desactivado"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"El teléfono tiene suficiente batería. Las funciones ya no están restringidas."</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"No se puede acceder a la cámara del teléfono desde tu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"No se puede acceder a la cámara del tablet desde tu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Predeterminado del sistema"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index cbfe44b..6e00da7 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Lubab rakendusel vaadata ekraaniluku keerukuse taset (kõrge, keskmine, madal või puudub), mis näitab ekraaniluku võimalikku pikkust ja tüüpi. Rakendus võib kasutajatele soovitada ka ekraaniluku viimist teatud tasemele, kuid kasutajad võivad seda eirata ja kuvalt lahkuda. Pange tähele, et ekraanilukku ei salvestata lihttekstina, seega ei tea rakendus täpset parooli."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"märguannete kuvamine"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Lubab rakendusel märguandeid kuvada"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"ekraani sisselülitamine"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Lubab rakendusel ekraani sisse lülitada."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"kasutada biomeetrilist riistvara"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Võimaldab rakendusel autentimiseks kasutada biomeetrilist riistvara"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"sõrmejälje riistvara haldamine"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Lisateave"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Androidi versioonis 12 asendasid täiustatud märguanded Androidi kohanduvad märguanded. See funktsioon näitab soovitatud toiminguid ja vastuseid ning korrastab teie märguandeid.\n\nTäiustatud märguanded pääsevad juurde märguande sisule, sh isiklikule teabele, nagu kontaktide nimed ja sõnumid. Samuti saab selle funktsiooni abil märguannetest loobuda või neile vastata (nt vastata telefonikõnedele ja juhtida funktsiooni Mitte segada)."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Rutiinirežiimi teabe märguanne"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Akusäästja lülitati sisse"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Aku tööea pikendamiseks vähendatakse akukasutust"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Akusäästja"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Akusäästja on välja lülitatud"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Telefon on piisavalt laetud. Funktsioonid ei ole enam piiratud."</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Teie seadmest <xliff:g id="DEVICE">%1$s</xliff:g> ei pääse telefoni kaamerale juurde"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Teie seadmest <xliff:g id="DEVICE">%1$s</xliff:g> ei pääse tahvelarvuti kaamerale juurde"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Süsteemi vaikeseade"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 4d955bb..9ec5525 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Pantailaren blokeoaren konplexutasun-maila (handia, ertaina, txikia edo bat ere ez) jakiteko baimena ematen die aplikazioei. Informazio horrekin, pantailaren blokeoaren luzera-barruti edo mota posiblea ondoriozta liteke. Halaber, pantailaren blokeoa maila jakin batera igotzeko iradoki diezaiekete aplikazioek erabiltzaileei, baina horri ez ikusi egin eta aplikazioak erabiltzen jarraitzeko aukera dute erabiltzaileek. Kontuan izan pantailaren blokeoa ez dela gordetzen testu arrunt gisa; beraz, aplikazioek ez dute jakingo pasahitz zehatza zein den."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"jakinarazpenak erakutsi"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Jakinarazpenak erakusteko baimena ematen die aplikazioei"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"piztu pantaila"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Pantaila pizteko baimena ematen dio aplikazioari."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"erabili hardware biometrikoa"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Autentifikatzeko hardware biometrikoa erabiltzeko baimena ematen die aplikazioei."</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"kudeatu hatz-marken hardwarea"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ezin da atzitu telefonoaren kamera <xliff:g id="DEVICE">%1$s</xliff:g> gailutik"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ezin da atzitu tabletaren kamera <xliff:g id="DEVICE">%1$s</xliff:g> gailutik"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Sistemaren balio lehenetsia"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index d15780c..8aa014b 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"به برنامه اجازه می‌دهد سطح پیچیدگی قفل صفحه (بالا، متوسط، پایین، یا هیچ‌کدام) را بیاموزد که نشان‌دهنده بازه ممکن طول و نوع قفل صفحه است. همچنین برنامه می‌تواند به کاربران پیشنهاد دهد قفل صفحه را به سطح خاصی به‌روزرسانی کنند، اما کاربران می‌توانند آزادانه این پیشنهاد را نادیده بگیرند و به سطح دیگری بروند. توجه داشته باشید که قفل صفحه در قالب نوشتار ساده ذخیره نمی‌شود، بنابراین برنامه گذرواژه دقیق را نمی‌داند."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"نمایش اعلان"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"به این برنامه اجازه می‌دهد اعلان نمایش دهد"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"روشن کردن صفحه‌نمایش"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"به برنامه اجازه می‌دهد صفحه‌نمایش را روشن کند."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"استفاده از سخت‌افزار بیومتریک"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"به برنامه امکان می‌دهد از سخت‌افزار بیومتریک برای اصالت‌سنجی استفاده کند"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"مدیریت سخت‌افزار اثر انگشت"</string>
@@ -623,7 +625,7 @@
     <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"برای حذف مدل چهره‌تان ضربه بزنید، سپس چهره‌تان را دوباره اضافه کنید"</string>
     <string name="face_setup_notification_title" msgid="8843461561970741790">"راه‌اندازی «قفل‌گشایی با چهره»"</string>
     <string name="face_setup_notification_content" msgid="5463999831057751676">"برای باز کردن قفل تلفن خود به آن نگاه کنید"</string>
-    <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"‏برای استفاده از «قفل‌گشایی با چهره»، "<b>"دسترسی به دوربین"</b>" را در «تنظیمات &gt; حریم‌خصوصی» روشن کنید"</string>
+    <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"‏برای استفاده از «قفل‌گشایی با چهره»، "<b>"دسترسی به دوربین"</b>" را در «تنظیمات &gt; حریم خصوصی» روشن کنید"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"راه‌اندازی روش‌های بیشتر برای باز کردن قفل"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"برای افزودن اثر انگشت، ضربه بزنید"</string>
     <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"قفل‌گشایی با اثر انگشت"</string>
@@ -1046,7 +1048,7 @@
     <string name="permlab_writeGeolocationPermissions" msgid="8605631647492879449">"تغییر مجوزهای مکان جغرافیایی مرورگر"</string>
     <string name="permdesc_writeGeolocationPermissions" msgid="5817346421222227772">"‏به برنامه اجازه می‎دهد تا مجوزهای جغرافیایی مرورگر را تغییر دهد. برنامه‌های مخرب می‎توانند از آن استفاده کنند تا اطلاعات موقعیت مکانی را به سایت‌های وب کتابخانه بفرستند."</string>
     <string name="save_password_message" msgid="2146409467245462965">"می‌خواهید مرورگر این گذرواژه را به خاطر داشته باشد؟"</string>
-    <string name="save_password_notnow" msgid="2878327088951240061">"اکنون نه"</string>
+    <string name="save_password_notnow" msgid="2878327088951240061">"حالا نه"</string>
     <string name="save_password_remember" msgid="6490888932657708341">"به خاطر سپردن"</string>
     <string name="save_password_never" msgid="6776808375903410659">"هیچ‌وقت"</string>
     <string name="open_permission_deny" msgid="5136793905306987251">"شما اجازه بازکردن این صفحه را ندارید."</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"بیشتر بدانید"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"‏در Android نسخه ۱۲، اعلان‌های بهبودیافته جایگزین «اعلان‌های تطبیقی» شده است. این ویژگی پاسخ‌ها و کنش‌های پیشنهادی را نمایش می‌دهد و اعلان‌هایتان را سازمان‌دهی می‌کند.\n\nاعلان‌های بهبودیافته می‌توانند به محتوای اعلان، ازجمله اطلاعات شخصی مثل نام‌ها و پیام‌های مخاطبین دسترسی داشته باشند. این ویژگی همچنین می‌تواند اعلان‌ها را رد کند یا به آن‌ها پاسخ دهد؛ مثلاً پاسخ به تماس‌های تلفنی و کنترل کردن «مزاحم نشوید»."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"اعلان اطلاعات حالت روال معمول"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"«بهینه‌سازی باتری» روشن شد"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"برای افزایش عمر باتری، مصرف باتری کاهش می‌یابد"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"بهینه‌سازی باتری"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"«بهینه‌سازی باتری» خاموش شد"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"تلفن به‌اندازه کافی شارژ دارد. ویژگی‌ها دیگر محدود نمی‌شوند."</string>
@@ -2270,7 +2270,7 @@
     <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"لغو انسداد دوربین دستگاه"</string>
     <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"‏برای &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; و همه برنامه‌ها و سرویس‌ها"</string>
     <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"لغو انسداد"</string>
-    <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"حریم‌خصوصی حسگر"</string>
+    <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"حریم خصوصی حسگر"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"نماد برنامه"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"تصویر نمانام‌سازی برنامه"</string>
     <string name="view_and_control_notification_title" msgid="4300765399209912240">"بررسی تنظیمات دسترسی"</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"نمی‌توان از <xliff:g id="DEVICE">%1$s</xliff:g> شما به دوربین تلفن دسترسی داشت"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"نمی‌توان از <xliff:g id="DEVICE">%1$s</xliff:g> شما به دوربین رایانه لوحی دسترسی داشت"</string>
     <string name="system_locale_title" msgid="711882686834677268">"پیش‌فرض سیستم"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 33b43ba..8e65d49e 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Sovellus saa luvan selvittää näytön lukituksen monimutkaisuuden (korkea, keskitaso tai matala) eli sen pituusluokan ja tyypin. Sovellus voi myös ehdottaa käyttäjille näytön lukituksen vaihtamista tietylle tasolle, mutta he voivat ohittaa tämän ja poistua. Itse näytön lukitusta ei säilytetä tekstimuodossa, joten sovellus ei tiedä sitä tarkalleen."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"näyttää ilmoituksia"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Antaa sovelluksen näyttää ilmoituksia"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"laita näyttö päälle"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Salli sovelluksen laittaa näyttö päälle."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"käytä biometristä laitteistoa"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Sallii sovelluksen käyttää biometristä laitteistoa todennukseen"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"sormenjälkilaitteiston hallinnointi"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Lue lisää"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Parannetut ilmoitukset korvasivat Androidin mukautuvat ilmoitukset Android 12:ssa. Tämä ominaisuus näyttää toiminto- ja vastausehdotuksia ja järjestää ilmoituksesi.\n\nParannetuilla ilmoituksilla on pääsy kaikkeen ilmoitussisältöön, myös henkilökohtaisiin tietoihin (esim. kontaktien nimet ja viestit). Ominaisuus voi myös ohittaa ilmoituksia tai vastata niihin, esim. vastata puheluihin ja ohjata Älä häiritse ‑tilaa."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Ohjelmatilan tietoilmoitus"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Virransäästö päällä"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Akun käyttöä rajoitetaan akunkeston pidentämiseksi"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Virransäästö"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Virransäästö laitettiin pois päältä"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Puhelimessa on tarpeeksi virtaa. Ominaisuuksia ei enää rajoiteta."</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> ei pääse puhelimen kameraan"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> ei pääse tabletin kameraan"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Järjestelmän oletusarvo"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 23b8f04..2240a91 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Autorise l\'application à apprendre le niveau de complexité de l\'écran de verrouillage (élevé, moyen, faible ou aucun), qui indique la gamme possible de longueur et de type de verrouillage d\'écran. L\'application peut aussi suggérer aux utilisateurs de mettre à jour l\'écran de verrouillage afin d\'utiliser un certain niveau de complexité, mais ils peuvent ignorer la suggestion. Notez que le verrouillage d\'écran n\'est pas stocké en texte brut pour de manière à ce que l\'application n\'ait pas accès au mot de passe exact."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"afficher les notifications"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Permet à l\'application d\'afficher les notifications"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"allumer l\'écran"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Permet à l\'application d\'allumer l\'écran."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"utiliser le matériel biométrique"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Permet à l\'application d\'utiliser du matériel biométrique pour l\'authentification"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"gérer le lecteur d\'empreintes digitales"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"En savoir plus"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Les notifications améliorées ont remplacé les notifications adaptatives Android sous Android 12. Cette fonctionnalité vous présente des suggestions d\'actions et de réponses, et organise vos notifications.\n\nLes notifications améliorées peuvent accéder au contenu de toutes les notifications, y compris les renseignements personnels comme le nom des contacts et les messages. Cette fonctionnalité peut aussi fermer des notifications ou interagir avec elles, comme répondre aux appels téléphoniques et gérer le mode Ne pas déranger."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notification d\'information du mode Routine"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Économiseur de pile activé"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Réduction de l\'utilisation de la pile pour en prolonger l\'autonomie"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Économiseur de pile"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Le mode Économiseur de pile est désactivé"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Le téléphone est suffisamment chargé. Ces fonctionnalités ne sont plus restreintes."</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Impossible d\'accéder à l\'appareil photo du téléphone à partir de votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Impossible d\'accéder à l\'appareil photo de la tablette à partir de votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Paramètre système par défaut"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index e14d506..2b14219 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Permet à l\'application de connaître le niveau de complexité du verrouillage de l\'écran (élevé, moyen, faible ou aucun), qui indique les possibilités en matière de longueur du mot de passe et de type de verrouillage de l\'écran. L\'application peut également suggérer aux utilisateurs de modifier la complexité du verrouillage, mais ces derniers peuvent librement l\'ignorer. Remarque : Comme le verrouillage de l\'écran n\'est pas stocké au format texte brut, l\'application ne connaît pas le mot de passe exact."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"afficher des notifications"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Autorise l\'appli à afficher des notifications"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"Allumer l\'écran"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Autorise l\'appli à allumer l\'écran."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"utiliser les composants biométriques"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Autoriser l\'application à utiliser les composants biométriques pour l\'authentification"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"Gérer le matériel d\'empreintes digitales"</string>
@@ -623,7 +625,7 @@
     <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Appuyez pour supprimer votre empreinte faciale, puis ajoutez de nouveau votre visage"</string>
     <string name="face_setup_notification_title" msgid="8843461561970741790">"Configurer le déverrouillage par reconnaissance faciale"</string>
     <string name="face_setup_notification_content" msgid="5463999831057751676">"Déverrouillez votre téléphone en le regardant"</string>
-    <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Pour utiliser Face Unlock, activez "<b>"Accès à l\'appareil photo"</b>" dans Paramètres &gt; Confidentialité"</string>
+    <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Pour utiliser le déverrouillage par reconnaissance faciale, activez "<b>"Accès à l\'appareil photo"</b>" dans Paramètres &gt; Confidentialité"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configurer d\'autres méthodes de déverrouillage"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Appuyez pour ajouter une empreinte digitale"</string>
     <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Déverrouillage par empreinte digitale"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"En savoir plus"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Les notifications améliorées remplacent les notifications intelligentes dans Android 12. Cette fonctionnalité affiche les suggestions d\'actions et de réponses, et organise vos notifications.\n\nElle a accès au contenu des notifications, y compris aux informations personnelles tels que les noms des contacts et les messages. Elle peut aussi fermer les notifications ou effectuer des actions comme répondre à un appel téléphonique et contrôler le mode Ne pas déranger."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notification d\'information du mode Routine"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Économiseur de batterie activé"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Réduction de l\'utilisation de la batterie pour prolonger son autonomie"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Économiseur de batterie"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Économiseur de batterie désactivé"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Téléphone suffisamment chargé. Les fonctionnalités ne sont plus restreintes."</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Impossible d\'accéder à l\'appareil photo du téléphone depuis votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Impossible d\'accéder à l\'appareil photo de la tablette depuis votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Paramètre système par défaut"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 72f0dcc..52c26ca 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Permite que a aplicación consulte o nivel (alto, medio, baixo ou inexistente) de complexidade do bloqueo de pantalla para saber a lonxitude aproximada do contrasinal e o tipo de bloqueo de pantalla. A aplicación tamén pode suxerirlles aos usuarios que aumenten o nivel de complexidade do bloqueo de pantalla, aínda que poden ignorar a suxestión e seguir navegando. Ten en conta que o bloqueo de pantalla non se almacena como texto sen formato, polo que a aplicación non pode consultar o contrasinal exacto."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"mostrar notificacións"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Permite que a aplicación mostre notificacións"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"activar pantalla"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Permite que a aplicación active a pantalla."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"utilizar hardware biométrico"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Permite que a aplicación utilice hardware biométrico para a autenticación"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"xestionar hardware de impresión dixital"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Máis información"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"En Android 12, as notificacións melloradas substitúen as notificacións intelixentes. Esta función ofréceche suxestións de accións e respostas, ademais de organizar as notificacións.\n\nEste servizo pode acceder ao contido das notificacións, mesmo á información persoal, como os nomes dos contactos e as mensaxes. Ademais, esta función pode ignorar ou responder as notificacións (por exemplo, coller chamadas telefónicas e controlar o modo Non molestar)."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificación da información do modo de rutina"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Activouse Aforro de batería"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Estase limitando o uso da batería para aumentar a súa duración"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Aforro de batería"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Desactivouse a función Aforro de batería."</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"O teléfono non ten suficiente batería. Xa non se restrinxirán as funcións."</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Non se puido acceder á cámara do teléfono desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>)"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Non se puido acceder á cámara da tableta desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>)"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Opción predeterminada do sistema"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index f1f0b86..713e33f 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"ઍપને સ્ક્રીન લૉકની જટિલતાનું લેવલ (ઊંચું, મધ્યમ, નીચું અથવા કોઈ નહીં) જાણવાની મંજૂરી આપે છે, જે સ્ક્રીન લૉકના પ્રકાર અને લંબાઈની સંભવિત શ્રેણી સૂચવે છે. ઍપ વપરાશકર્તાઓને સ્ક્રીન લૉકને ચોક્કસ લેવલ સુધી અપડેટ કરવાનું સૂચન પણ કરી શકે છે, પરંતુ વપરાશકર્તાઓ મુક્ત રીતે અવગણીને નૅવિગેટ કરી શકે છે. નોંધી લો કે સ્ક્રીન લૉકનો plaintextમાં સંગ્રહ કરવામાં આવતો નથી, તેથી ઍપને ચોક્કસ પાસવર્ડની જાણ હોતી નથી."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"નોટિફિકેશન બતાવો"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"ઍપને નોટિફિકેશન બતાવવાની મંજૂરી આપે છે"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"સ્ક્રીન ચાલુ કરો"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"ઍપને સ્ક્રીન ચાલુ કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"બાયોમેટ્રિક હાર્ડવેરનો ઉપયોગ કરો"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"ઍપને પ્રમાણીકરણ માટે બાયોમેટ્રિક હાર્ડવેરનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"ફિંગરપ્રિન્ટ હાર્ડવેરને મેનેજ કરો"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"તમારા <xliff:g id="DEVICE">%1$s</xliff:g> પરથી ફોનના કૅમેરાનો ઍક્સેસ કરી શકતાં નથી"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"તમારા <xliff:g id="DEVICE">%1$s</xliff:g> પરથી ટૅબ્લેટના કૅમેરાનો ઍક્સેસ કરી શકતાં નથી"</string>
     <string name="system_locale_title" msgid="711882686834677268">"સિસ્ટમ ડિફૉલ્ટ"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 6d90d53..ddf0aa7 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -302,9 +302,9 @@
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"मैसेज (एसएमएस) भेजें और देखें"</string>
     <string name="permgrouplab_storage" msgid="17339216290379241">"फ़ाइलें"</string>
     <string name="permgroupdesc_storage" msgid="5378659041354582769">"अपने डिवाइस में मौजूद फ़ाइलों का ऐक्सेस दें"</string>
-    <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"संगीत और ऑडियो को ऐक्सेस करने की अनुमति"</string>
+    <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"संगीत और ऑडियो के ऐक्सेस"</string>
     <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"आपके डिवाइस पर संगीत और ऑडियो को ऐक्सेस करने की अनुमति"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"फ़ोटो और वीडियो को ऐक्सेस करने की अनुमति"</string>
+    <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"फ़ोटो और वीडियो के ऐक्सेस"</string>
     <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"आपके डिवाइस पर फ़ोटो और वीडियो को ऐक्सेस करने की अनुमति"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"माइक्रोफ़ोन"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ऑडियो रिकॉर्ड करें"</string>
@@ -550,9 +550,11 @@
     <string name="permlab_disableKeyguard" msgid="3605253559020928505">"अपना स्‍क्रीन लॉक अक्षम करें"</string>
     <string name="permdesc_disableKeyguard" msgid="3223710003098573038">"ऐप्स को कीलॉक और कोई भी संबद्ध पासवर्ड सुरक्षा बंद करने देता है. उदाहरण के लिए, इनकमिंग फ़ोन कॉल पाते समय फ़ोन, कीलॉक को बंद कर देता है, फिर कॉल खत्म होने पर कीलॉक को फिर से चालू कर देता है."</string>
     <string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"जानें कि स्क्रीन लॉक कितना मुश्किल बनाया गया है"</string>
-    <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"यह मंज़ूरी मिलने के बाद ऐप्लिकेशन जान पाता है कि स्क्रीन लॉक कितना मुश्किल (बहुत ज़्यादा, मध्यम, कम या बिल्कुल नहीं) है. इस स्तर से यह पता चलता है कि स्क्रीन लॉक कितना लंबा या किस तरह का है. ऐप्लिकेशन उपयोगकर्ताओं को यह सुझाव भी दे सकता है कि वे स्क्रीन लॉक को एक तय लेवल तक अपडेट करें. लेकिन उपयोगकर्ता इसे बेझिझक अनदेखा करके छोड़ सकते हैं. ध्यान दें कि स्क्रीन लॉक को सादे टेक्स्ट में सेव नहीं किया जाता है इसलिए ऐप्लिकेशन को सटीक पासवर्ड पता नहीं होता है."</string>
+    <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"यह मंज़ूरी मिलने के बाद ऐप्लिकेशन जान पाता है कि स्क्रीन लॉक कितना मुश्किल (बहुत ज़्यादा, मध्यम, कम या बिलकुल नहीं) है. इस स्तर से यह पता चलता है कि स्क्रीन लॉक कितना लंबा या किस तरह का है. ऐप्लिकेशन उपयोगकर्ताओं को यह सुझाव भी दे सकता है कि वे स्क्रीन लॉक को एक तय लेवल तक अपडेट करें. लेकिन उपयोगकर्ता इसे बेझिझक अनदेखा करके छोड़ सकते हैं. ध्यान दें कि स्क्रीन लॉक को सादे टेक्स्ट में सेव नहीं किया जाता है इसलिए ऐप्लिकेशन को सटीक पासवर्ड पता नहीं होता है."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"सूचनाएं दिखाएं"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"ऐप्लिकेशन को सूचनाएं दिखाने की अनुमति दें"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"स्क्रीन चालू करें"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"ऐप्लिकेशन को स्क्रीन चालू करने की अनुमति दें."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"बायोमीट्रिक हार्डवेयर इस्तेमाल करने दें"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"पुष्टि के लिए, ऐप्लिकेशन को बायोमीट्रिक हार्डवेयर इस्तेमाल करने की मंज़ूरी दें"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"फ़िंगरप्रिंट हार्डवेयर को प्रबंधित करें"</string>
@@ -644,9 +646,9 @@
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"कृपया फिर से अपने चेहरे की पहचान कराएं."</string>
     <string name="face_acquired_too_different" msgid="2520389515612972889">"चेहरे की पहचान नहीं हुई. फिर से कोशिश करें."</string>
     <string name="face_acquired_too_similar" msgid="8882920552674125694">"अपने सिर की पोज़िशन को थोड़ा बदलें"</string>
-    <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"अपने फ़ोन की तरफ़ बिल्कुल सीधा देखें"</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"अपने फ़ोन की तरफ़ बिल्कुल सीधा देखें"</string>
-    <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"अपने फ़ोन की तरफ़ बिल्कुल सीधा देखें"</string>
+    <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"अपने फ़ोन की तरफ़ बिलकुल सीधा देखें"</string>
+    <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"अपने फ़ोन की तरफ़ बिलकुल सीधा देखें"</string>
+    <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"अपने फ़ोन की तरफ़ बिलकुल सीधा देखें"</string>
     <string name="face_acquired_obscured" msgid="4917643294953326639">"आपके चेहरे को छिपाने वाली सभी चीज़ों को हटाएं."</string>
     <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"अपनी स्क्रीन के सबसे ऊपरी हिस्से को साफ़ करें, जिसमें काले रंग वाला बार भी शामिल है"</string>
     <string name="face_acquired_dark_glasses_detected" msgid="7263638432128692048">"आपका पूरा चेहरा दिखना चाहिए"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"आपके <xliff:g id="DEVICE">%1$s</xliff:g> से फ़ोन के कैमरे को ऐक्सेस नहीं किया जा सकता"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"आपके <xliff:g id="DEVICE">%1$s</xliff:g> से टैबलेट के कैमरे को ऐक्सेस नहीं किया जा सकता"</string>
     <string name="system_locale_title" msgid="711882686834677268">"सिस्टम डिफ़ॉल्ट"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 63782e8..48aece5 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -554,6 +554,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Omogućuje aplikaciji da sazna razinu složenosti zaključavanja zaslona (visoka, srednja, niska ili nijedna), što upućuje na mogući raspon duljine i vrstu zaključavanja zaslona. Aplikacija također korisnicima može predložiti da ažuriraju zaključavanje zaslona na određenu razinu, no korisnici to mogu slobodno zanemariti i nastaviti dalje. Napominjemo da se zaključavanje zaslona ne pohranjuje u običnom tekstu, pa aplikacija ne zna točnu zaporku."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"prikazati obavijesti"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Aplikaciji omogućuje prikazivanje obavijesti"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"uključiti zaslon"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Aplikaciji omogućuje uključivanje zaslona."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"koristiti biometrijski hardver"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Aplikaciji omogućuje upotrebu biometrijskog hardvera radi autentifikacije"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"upravljanje hardverom za čitanje otisaka prstiju"</string>
@@ -2285,4 +2287,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"S vašeg uređaja <xliff:g id="DEVICE">%1$s</xliff:g> nije moguće pristupiti fotoaparatu telefona"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"S vašeg uređaja <xliff:g id="DEVICE">%1$s</xliff:g> nije moguće pristupiti fotoaparatu tableta"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Zadane postavke sustava"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index ed656ac..f752b82 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Lehetővé teszi az alkalmazás számára, hogy megismerje a képernyőzár összetettségi szintjét (magas, közepes, alacsony vagy nincs), amely jelzi a képernyőzár lehetséges típusát és hosszát. Az alkalmazás ezenkívül javaslatot tehet a felhasználóknak a képernyőzár bizonyos szintre való frissítésére, de ezt a javaslatot a felhasználók figyelmen kívül hagyhatják. A képernyőzárat nem egyszerű szöveges formátumban tárolja a rendszer, ezért az alkalmazás nem fogja tudni a pontos jelszót."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"értesítések megjelenítése"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Lehetővé teszi az alkalmazás számára az értesítések megjelenítését"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"képernyő bekapcsolása"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Engedélyezi az alkalmazásnak a képernyő bekapcsolását."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"biometrikus hardver használata"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Lehetővé teszi az alkalmazás számára a biometrikus hardver hitelesítésre való használatát"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"ujjlenyomat-olvasó hardver kezelése"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nem lehet hozzáférni a telefon kamerájához a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nem lehet hozzáférni a táblagép kamerájához a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Rendszerbeállítás"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 282a212..e162499 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Հավելվածին հասանելի կդառնան էկրանի կողպման բարդության մակարդակի մասին տեղեկությունները (բարձր, միջին, ցածր կամ ոչ մեկը), այդ թվում՝ կողպման տեսակի և գաղտնաբառի երկարության մասին տվյալները: Բացի այդ, հավելվածը կկարողանա առաջարկել օգտատերերին բարձրացնել կողպման բարդության մակարդակը: Օգտատերերը կարող են անտեսել այդ առաջարկները: Նկատի ունեցեք, որ գաղտնաբառը չի պահվում բաց տեքստի տեսքով և հասանելի չէ հավելվածին:"</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"ցուցադրել ծանուցումներ"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Թույլ է տալիս հավելվածին ցուցադրել ծանուցումներ"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"Էկրանի միացում"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Թույլ է տալիս հավելվածին միացնել էկրանը։"</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"կենսաչափական սարքի օգտագործում"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Հավելվածին թույլ է տալիս օգտագործել նույնականացման համար նախատեսված կենսաչափական սարքը"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"կառավարել մատնահետքերի գրանցման սարքը"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Իմանալ ավելին"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12-ում ընդլայնված ծանուցումները փոխարինում են Android-ի հարմարվող ծանուցումներին։ Այս գործառույթը դասավորում է ձեր բոլոր ծանուցումները և առաջարկում գործողություններ և պատասխաններ։\n\nԸնդլայնված ծանուցումներին հասանելի է բոլոր ծանուցումների պարունակությունը, ներառյալ անձնական տվյալները, օրինակ՝ կոնտակտների անուններն ու հաղորդագրությունները։ Այս գործառույթը կարող է նաև փակել ծանուցումները կամ սեղմել դրանցում առկա կոճակները, այդ թվում՝ պատասխանել հեռախոսազանգերի և կառավարել «Չանհանգստացնել» ռեժիմը։"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Ծանուցում լիցքավորման մասին"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Մարտկոցի տնտեսումը միացվել է"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Մարտկոցի օգտագործումը նվազեցվել է դրա աշխատաժամանակը երկարացնելու համար"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Մարտկոցի տնտեսում"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Մարտկոցի տնտեսումն անջատված է"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Հեռախոսի լիցքը բավարար է։ Գործառույթներն այլևս չեն սահմանափակվում։"</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Հնարավոր չէ օգտագործել հեռախոսի տեսախցիկը ձեր <xliff:g id="DEVICE">%1$s</xliff:g> սարքից"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Հնարավոր չէ օգտագործել պլանշետի տեսախցիկը ձեր <xliff:g id="DEVICE">%1$s</xliff:g> սարքից"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Կանխադրված"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index a5fa54d..3886108 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Mengizinkan aplikasi mempelajari tingkat kompleksitas kunci layar (tinggi, sedang, rendah, atau tidak ada), yang menunjukkan kemungkinan rentang durasi dan jenis kunci layar. Aplikasi juga dapat menyarankan agar pengguna memperbarui kunci layar ke tingkat tertentu, namun pengguna dapat mengabaikan dan keluar dengan bebas. Perhatikan bahwa kunci layar tidak disimpan dalam teks biasa, sehingga aplikasi tidak mengetahui sandi yang sebenarnya."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"tampilkan notifikasi"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Mengizinkan aplikasi untuk menampilkan notifikasi"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"aktifkan layar"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Mengizinkan aplikasi mengaktifkan layar."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"gunakan hardware biometrik"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Mengizinkan aplikasi menggunakan hardware biometrik untuk autentikasi"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"kelola hardware sidik jari"</string>
@@ -745,7 +747,7 @@
     <string name="permdesc_startReviewPermissionDecisions" msgid="2775556853503004236">"Mengizinkan pemegang memulai layar untuk meninjau keputusan izin. Tidak pernah dibutuhkan untuk aplikasi normal."</string>
     <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"mulai lihat fitur aplikasi"</string>
     <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Memungkinkan pemegang mulai melihat info fitur untuk aplikasi."</string>
-    <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"mengakses data sensor pada frekuensi pengambilan sampel yang tinggi"</string>
+    <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"mengakses data sensor pada frekuensi sampling yang tinggi"</string>
     <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Mengizinkan aplikasi mengambil sampel data sensor pada frekuensi yang lebih besar dari 200 Hz"</string>
     <string name="policylab_limitPassword" msgid="4851829918814422199">"Setel aturan sandi"</string>
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"Mengontrol panjang dan karakter yang diizinkan dalam sandi dan PIN kunci layar."</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Pelajari lebih lanjut"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Notifikasi yang ditingkatkan menggantikan Notifikasi Adaptif Android di Android 12. Fitur ini menunjukkan tindakan dan balasan yang disarankan, serta mengatur notifikasi.\n\nNotifikasi yang ditingkatkan dapat mengakses konten notifikasi, termasuk informasi pribadi seperti nama kontak dan pesan. Fitur ini juga dapat menutup atau merespons notifikasi, seperti menjawab panggilan telepon dan mengontrol fitur Jangan Ganggu."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notifikasi info Mode Rutinitas"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Penghemat Baterai diaktifkan"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Mengurangi penggunaan baterai untuk memperpanjang masa pakai baterai"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Penghemat Baterai"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Penghemat Baterai dinonaktifkan"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Baterai ponsel cukup terisi. Fitur tidak lagi dibatasi."</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Tidak dapat mengakses kamera ponsel dari <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Tidak dapat mengakses kamera tablet dari <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Default sistem"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index ff29303..62a30c7 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Leyfir forritinu að læra hversu flókinn skjálásinn er (erfiður, miðlungs, léttur eða enginn), sem gefur til kynna lengd og tegund skjálássins. Forritið getur einnig lagt til að notendur geri skjálásinn flóknari upp að tilteknu marki, en notendur geta valið að hunsa það og halda áfram að vafra. Hafðu í huga að skjálásinn er ekki geymdur í ódulkóðuðum texta svo forritið veit ekki nákvæmt aðgangsorð."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"sýna tilkynningar"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Leyfir forritinu að sýna tilkynningar"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"kveikja á skjánum"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Leyfir forritinu að kveikja á skjánum."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"nota búnað fyrir líffræðileg gögn"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Leyfir forritinu að nota búnað fyrir líffræðileg gögn til auðkenningar"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"stjórna fingrafarabúnaði"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Nánar"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Auknar tilkynningar hafa leyst breytilegar tilkynningar í Android af hólmi í Android 12. Eiginleikinn birtir tillögur að aðgerðum og svörum og flokkar tilkynningar.\n\nAuknar tilkynningar hafa aðgang að efni tilkynninga, þ. á m. persónuupplýsingum á borð við nöfn tengiliða og skilaboð. Eiginleikinn getur einnig hunsað eða svarað tilkynningum, til dæmis svarað símtölum og stjórnað „Ónáðið ekki“."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Upplýsingatilkynning aðgerðastillingar"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Kveikt á rafhlöðusparnaði"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Dregur úr rafhlöðunotkun til að auka endingu rafhlöðunnar"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Rafhlöðusparnaður"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Slökkt á rafhlöðusparnaði"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Síminn er með næga hleðslu. Eiginleikar eru ekki lengur takmarkaðir."</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ekki er hægt að opna myndavél símans úr <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ekki er hægt að opna myndavél spjaldtölvunnar úr <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Sjálfgildi kerfis"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 89367e1..bf320c9 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Consente all\'app di conoscere il livello di complessità del blocco schermo (alto, medio, basso o nessuno), che indica l\'intervallo di caratteri possibile e il tipo di blocco schermo. L\'app può inoltre suggerire agli utenti di aggiornare il blocco schermo a un livello specifico di complessità, ma gli utenti possono ignorare liberamente il suggerimento e uscire. Tieni presente che il blocco schermo non viene memorizzato come testo non crittografato, quindi l\'app non conosce la password esatta."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"Visualizzazione di notifiche"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Consente all\'app di mostrare notifiche"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"attiva lo schermo"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Consente all\'app di attivare lo schermo."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"utilizzo di hardware biometrico"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Consente all\'app di utilizzare hardware biometrico per eseguire l\'autenticazione"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"gestione di hardware per il riconoscimento delle impronte"</string>
@@ -1916,13 +1918,13 @@
     <string name="user_creation_adding" msgid="7305185499667958364">"Consentire a <xliff:g id="APP">%1$s</xliff:g> di creare un nuovo utente con l\'account <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="supervised_user_creation_label" msgid="6884904353827427515">"Aggiungi utente supervisionato"</string>
     <string name="language_selection_title" msgid="52674936078683285">"Aggiungi una lingua"</string>
-    <string name="country_selection_title" msgid="5221495687299014379">"Area geografica preferita"</string>
+    <string name="country_selection_title" msgid="5221495687299014379">"Regione preferita"</string>
     <string name="search_language_hint" msgid="7004225294308793583">"Digita nome lingua"</string>
     <string name="language_picker_section_suggested" msgid="6556199184638990447">"Suggerite"</string>
     <string name="language_picker_section_suggested_bilingual" msgid="5932198319583556613">"Lingue suggerite"</string>
-    <string name="region_picker_section_suggested_bilingual" msgid="704607569328224133">"Aree geografiche consigliate"</string>
+    <string name="region_picker_section_suggested_bilingual" msgid="704607569328224133">"Regioni consigliate"</string>
     <string name="language_picker_section_all" msgid="1985809075777564284">"Tutte le lingue"</string>
-    <string name="region_picker_section_all" msgid="756441309928774155">"Tutte le aree geografiche"</string>
+    <string name="region_picker_section_all" msgid="756441309928774155">"Tutte le regioni"</string>
     <string name="locale_search_menu" msgid="6258090710176422934">"Cerca"</string>
     <string name="app_suspended_title" msgid="888873445010322650">"App non disponibile"</string>
     <string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> non è al momento disponibile. Viene gestita tramite <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Impossibile accedere alla fotocamera del telefono dal tuo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Impossibile accedere alla fotocamera del tablet dal tuo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Predefinita di sistema"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index bbc2581..1e12b11 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -555,6 +555,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"מאפשרת לאפליקציה ללמוד את רמת המורכבות של נעילת המסך (גבוהה, בינונית, נמוכה או לא מורכבת). הרמה הזו מציינת את הטווח האפשרי של אורך וסוג נעילת המסך. האפליקציה יכולה גם להציע למשתמשים לעדכן את נעילת המסך לרמה מסוימת, אבל המשתמשים יכולים להתעלם מההצעה ולנווט לפריט אחר. לתשומת ליבך, נעילת המסך לא מאוחסנת כטקסט פשוט, ולכן האפליקציה לא יודעת מה הסיסמה המדויקת."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"הצגת התראות"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"מאפשרת לאפליקציה להציג התראות"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"הפעלת המסך"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"ההרשאה מאפשרת לאפליקציה להפעיל את המסך."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"שימוש בחומרה ביומטרית"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"מאפשרת לאפליקציה להשתמש בחומרה ביומטרית לצורך אימות"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"ניהול חומרה של טביעות אצבעות"</string>
@@ -2286,4 +2288,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"לא ניתן לגשת למצלמה של הטלפון מה‑<xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"לא ניתן לגשת למצלמה של הטאבלט מה‑<xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"ברירת המחדל של המערכת"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 60d0b91..6bbf5b4 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"このアプリに画面ロックの複雑さレベル(高、中、低、なし)を認識することを許可します。複雑さレベルは、画面ロックの文字数の範囲やタイプを示すものです。アプリから一定レベルまで画面ロックを更新するよう推奨されることもありますが、ユーザーは無視したり別の操作を行ったりできます。画面ロックは平文で保存されないため、アプリが正確なパスワードを知ることはありません。"</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"通知の表示"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"通知の表示をアプリに許可"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"画面をオンにする"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"画面をオンにすることをアプリに許可します。"</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"生体認証ハードウェアの使用"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"生体認証ハードウェアを認証に使用することをアプリに許可します"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"指紋認証ハードウェアの管理"</string>
@@ -1443,7 +1445,7 @@
     <string name="permdesc_route_media_output" msgid="1759683269387729675">"メディア出力を他の外部デバイスにルーティングすることをアプリに許可します。"</string>
     <string name="permlab_readInstallSessions" msgid="7279049337895583621">"インストールセッションの読み取り"</string>
     <string name="permdesc_readInstallSessions" msgid="4012608316610763473">"インストールセッションの読み取りをアプリに許可します。これにより、アプリはアクティブパッケージのインストールに関する詳細情報を参照できるようになります。"</string>
-    <string name="permlab_requestInstallPackages" msgid="7600020863445351154">"インストールパッケージのリクエスト"</string>
+    <string name="permlab_requestInstallPackages" msgid="7600020863445351154">"request install packages"</string>
     <string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"パッケージのインストールをリクエストすることをアプリケーションに許可します。"</string>
     <string name="permlab_requestDeletePackages" msgid="2541172829260106795">"パッケージの削除のリクエスト"</string>
     <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"パッケージの削除をリクエストすることをアプリに許可します。"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> からスマートフォンのカメラにアクセスできません"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> からタブレットのカメラにアクセスできません"</string>
     <string name="system_locale_title" msgid="711882686834677268">"システムのデフォルト"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 9974606..508cc42 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"საშუალებას აძლევს აპს, შეიტყოს ეკრანის დაბლოკვის მეთოდის სირთულე (მაღალი, საშუალო, დაბალი ან არანაირი), რისი მეშვეობითაც შესაძლებელია ეკრანის დაბლოკვის მეთოდის სიგრძის შესაძლო დიაპაზონისა და ტიპის განსაზღვრა. გარდა ამისა, აპს შეუძლია მომხმარებლებისთვის ეკრანის დაბლოკვის მეთოდის გარკვეულ დონემდე გაძლიერების შეთავაზება, თუმცა მომხმარებლებს შეეძლებათ აღნიშნული შეტყობინების უგულებელყოფა და სხვა ეკრანზე გადასვლა. გაითვალისწინეთ, რომ ეკრანის დაბლოკვის მეთოდი არ ინახება ჩვეულებრივი ტექსტის სახით, ამიტომ აპს არ ეცოდინება ზუსტი პაროლი."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"შეტყობინებების ჩვენება"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"უფლებას აძლევს აპს, აჩვენოს შეტყობინებები"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"ეკრანის ჩართვა"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"უფლებას აძლევს აპს, ჩართოს ეკრანი."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"ბიომეტრიული აპარატის გამოყენება"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"საშუალებას აძლევს აპს, ავტორიზაციისთვის გამოიყენოს ბიომეტრიული აპარატი"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"თითის ანაბეჭდის აპარატის მართვა"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ტელეფონის კამერაზე წვდომა ვერ მოხერხდა თქვენი <xliff:g id="DEVICE">%1$s</xliff:g>-დან"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ტაბლეტის კამერაზე წვდომა ვერ მოხერხდა თქვენი <xliff:g id="DEVICE">%1$s</xliff:g>-დან"</string>
     <string name="system_locale_title" msgid="711882686834677268">"სისტემის ნაგულისხმევი"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 3545559..e43fc2e 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -264,7 +264,7 @@
     <string name="global_action_lockdown" msgid="2475471405907902963">"Құлыптау"</string>
     <string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
     <string name="notification_hidden_text" msgid="2835519769868187223">"Жаңа хабарландыру"</string>
-    <string name="notification_channel_virtual_keyboard" msgid="6465975799223304567">"Виртуалды пернетақта"</string>
+    <string name="notification_channel_virtual_keyboard" msgid="6465975799223304567">"Виртуалдық пернетақта"</string>
     <string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Физикалық пернетақта"</string>
     <string name="notification_channel_security" msgid="8516754650348238057">"Қауіпсіздік"</string>
     <string name="notification_channel_car_mode" msgid="2123919247040988436">"Көлік режимі"</string>
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Қолданбаға экран құлпының күрделілік деңгейін (жоғары, орташа, төмен немесе жоқ), соның ішінде ұзындығының ықтимал ауқымын және оның түрін анықтауға мүмкіндік береді. Сонымен қатар қолданба пайдаланушыларға құлыпты белгілі бір деңгейге жаңартуды ұсынады. Бірақ бұл ұсыныстарды елемеуге болады. Экран құлпы қарапайым мәтін түрінде сақталмайтындықтан, құпия сөз қолданбаға белгісіз болатынын ескеріңіз."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"хабарландыруларды көрсету"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Қолданбаға хабарландыруларды көрсетуге мүмкіндік береді."</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"экранды қосу"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Қолдабаға экранды қосуға рұқсат етеді."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"биометрикалық жабдықты пайдалану"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Аутентификациялау үшін қолданбаға биометрикалық жабдықты пайдалануға рұқсат береді"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"саусақ ізі жабдығын басқару"</string>
@@ -1134,7 +1136,7 @@
     <string name="replace" msgid="7842675434546657444">"… сөзін алмастыру"</string>
     <string name="delete" msgid="1514113991712129054">"Жою"</string>
     <string name="copyUrl" msgid="6229645005987260230">"URL мекенжайын көшіру"</string>
-    <string name="selectTextMode" msgid="3225108910999318778">"Мәтінді бөлектеу"</string>
+    <string name="selectTextMode" msgid="3225108910999318778">"Мәтінді ерекшелеу"</string>
     <string name="undo" msgid="3175318090002654673">"Қайтару"</string>
     <string name="redo" msgid="7231448494008532233">"Қайтару"</string>
     <string name="autofill" msgid="511224882647795296">"Aвтотолтыру"</string>
@@ -1379,7 +1381,7 @@
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ҚАБЫЛДАМАУ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Енгізу әдісін таңдау"</string>
     <string name="show_ime" msgid="6406112007347443383">"Физикалық пернетақта қосулы кезде оны экранға шығару"</string>
-    <string name="hardware" msgid="1800597768237606953">"Виртуалды пернетақтаны көрсету"</string>
+    <string name="hardware" msgid="1800597768237606953">"Виртуалдық пернетақтаны көрсету"</string>
     <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"Физикалық пернетақтаны конфигурациялау"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Тіл мен пернетақта схемасын таңдау үшін түртіңіз"</string>
     <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1478,7 +1480,7 @@
     <string name="wallpaper_binding_label" msgid="1197440498000786738">"Артқы фоны"</string>
     <string name="chooser_wallpaper" msgid="3082405680079923708">"Артқы фонын өзгерту"</string>
     <string name="notification_listener_binding_label" msgid="2702165274471499713">"Хабар бақылағыш"</string>
-    <string name="vr_listener_binding_label" msgid="8013112996671206429">"Виртуалды шынайылық тыңдаушысы"</string>
+    <string name="vr_listener_binding_label" msgid="8013112996671206429">"Виртуалдық шынайылық тыңдаушысы"</string>
     <string name="condition_provider_service_binding_label" msgid="8490641013951857673">"Шарт провайдері"</string>
     <string name="notification_ranker_binding_label" msgid="432708245635563763">"Хабарландыруларды жіктеу қызметі"</string>
     <string name="vpn_title" msgid="5906991595291514182">"VPN белсенді"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Толығырақ"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 жүйесінде \"Бейімделетін хабарландырулар\" функциясын \"Кеңейтілген хабарландырулар\" алмастырды. Бұл функция ұсынылған әрекеттер мен жауаптарды көрсетіп, хабарландыруларыңызды ретке келтіреді.\n\nОл хабарландыру мазмұнын, соның ішінде жеке ақпаратыңызды (мысалы, контакт аттары мен хабарларды) пайдалана алады. Сондай-ақ бұл функция арқылы хабарландыруларды жабуға немесе оларға жауап беруге (мысалы, телефон қоңырауларына жауап беруге және Мазаламау режимін басқаруға) болады."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Режим туралы хабарландыру"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Батареяны үнемдеу режимі қосулы"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Батарея шығынын азайтсаңыз, батареяның жұмысы ұзарады."</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Батареяны үнемдеу режимі"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Батареяны үнемдеу режимі өшірілді"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Телефонның заряды жеткілікті. Функцияларға енді шектеу қойылмайды."</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан телефон камерасын пайдалану мүмкін емес."</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан планшет камерасын пайдалану мүмкін емес."</string>
     <string name="system_locale_title" msgid="711882686834677268">"Жүйенің әдепкі параметрі"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 2da5ac0..08ec6e8 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"អនុញ្ញាតឱ្យ​កម្មវិធី​រៀនអំពី​កម្រិតស្មុគស្មាញ​ការនៃការចាក់សោអេក្រង់ (ខ្ពស់ មធ្យម​ ទាប ឬគ្មាន) ដែល​បញ្ជាក់អំពី​​ប្រវែង និងប្រភេទ​នៃការចាក់សោអេក្រង់។ កម្មវិធី​នេះ​ក៏​អាច​ណែនាំឱ្យ​អ្នកប្រើប្រាស់​ធ្វើបច្ចុប្បន្នភាព​ការចាក់សោ​អេក្រង់​ទៅកម្រិតជាក់លាក់​ផងដែរ ប៉ុន្តែ​អ្នកប្រើប្រាស់​អាច​មិនអើពើនឹង​ការណែនាំនេះ​ដោយសេរី។ សូម​ចំណាំថា ការចាក់សោអេក្រង់​មិន​ត្រូវបាន​រក្សាទុក​ជាអត្ថបទ​ធម្មតាទេ ដូច្នេះ​កម្មវិធីនេះ​មិន​ស្គាល់​ពាក្យសម្ងាត់​ពិតប្រាកដ​ឡើយ។"</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"បង្ហាញ​ការជូនដំណឹង"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"អនុញ្ញាតឱ្យ​កម្មវិធីបង្ហាញ​ការជូនដំណឹង"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"បើកអេក្រង់"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"អនុញ្ញាតឱ្យកម្មវិធីបើកអេក្រង់។"</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"ប្រើ​ឧបករណ៍​ស្កេន​ស្នាមម្រាមដៃ"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"អនុញ្ញាត​ឱ្យ​កម្មវិធី​ប្រើ​ឧបករណ៍​ស្កេន​ស្នាមម្រាមដៃ​សម្រាប់​ការផ្ទៀងផ្ទាត់"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"គ្រប់គ្រងផ្នែករឹងស្នាមម្រាមដៃ"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"មិនអាច​ចូលប្រើ​កាមេរ៉ាទូរសព្ទ​ពី <xliff:g id="DEVICE">%1$s</xliff:g> របស់អ្នក​បានទេ"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"មិនអាច​ចូលប្រើ​កាមេរ៉ា​ថេប្លេតពី <xliff:g id="DEVICE">%1$s</xliff:g> របស់អ្នក​បានទេ"</string>
     <string name="system_locale_title" msgid="711882686834677268">"លំនាំ​ដើម​ប្រព័ន្ធ"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 4b90f4d..e6e7f07 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"ಆ್ಯಪ್‌ಗೆ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಸಂಕೀರ್ಣತೆ ಮಟ್ಟವನ್ನು (ಅಧಿಕ, ಮಧ್ಯಮ, ಕಡಿಮೆ ಅಥವಾ ಯಾವುದೂ ಅಲ್ಲ) ತಿಳಿದುಕೊಳ್ಳಲು ಅನುಮತಿಸುತ್ತದೆ, ಅದು ಉದ್ದದ ಸಂಭವನೀಯ ಶ್ರೇಣಿ ಮತ್ತು ಸ್ಕ್ರೀನ್ ಲಾಕ್‌ನ ವಿಧವನ್ನು ಸೂಚಿಸುತ್ತದೆ. ಬಳಕೆದಾರರು ನಿರ್ದಿಷ್ಟ ಹಂತದವರೆಗೆ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಅಪ್‌ಡೇಟ್ ಮಾಡಬಹುದು, ಆದರೆ ಅವರು ಅದನ್ನು ನಿರ್ಲಕ್ಷಿಸಬಹುದು ಮತ್ತು ಅದರಿಂದ ಹೊರಬರಬಹುದು ಎಂಬುದನ್ನು ಸಹ ಆ್ಯಪ್ ಬಳಕೆದಾರರಿಗೆ ಸೂಚಿಸುತ್ತದೆ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಪಠ್ಯದ ರೂಪದಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವುದಿಲ್ಲ, ಇದರಿಂದಾಗಿ ಆ್ಯಪ್‌ಗೆ ಸರಿಯಾದ ಪಾಸ್‌ವರ್ಡ್ ಗೊತ್ತಿರುವುದಿಲ್ಲ ಎಂಬುದನ್ನು ಗಮನಿಸಿ."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"ಅಧಿಸೂಚನೆಗಳನ್ನು ತೋರಿಸಿ"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"ಅಧಿಸೂಚನೆಗಳನ್ನು ತೋರಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"ಸ್ಕ್ರೀನ್ ಅನ್ನು ಆನ್ ಮಾಡಿ"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"ಸ್ಕ್ರೀನ್ ಅನ್ನು ಆನ್ ಮಾಡಲು ಆ್ಯಪ್ ಅನ್ನು ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"ಬಯೋಮೆಟ್ರಿಕ್ ಹಾರ್ಡ್‌ವೇರ್‌ ಬಳಸಿ"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"ಪ್ರಮಾಣೀಕರಣಕ್ಕಾಗಿ ಬಯೋಮೆಟ್ರಿಕ್ ಹಾರ್ಡ್‌ವೇರ್ ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಹಾರ್ಡ್‌ವೇರ್ ನಿರ್ವಹಿಸಿ"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ನಿಮ್ಮ <xliff:g id="DEVICE">%1$s</xliff:g> ಮೂಲಕ ಫೋನ್‌ನ ಕ್ಯಾಮರಾವನ್ನು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ನಿಮ್ಮ <xliff:g id="DEVICE">%1$s</xliff:g> ಮೂಲಕ ಟ್ಯಾಬ್ಲೆಟ್‌ನ ಕ್ಯಾಮರಾವನ್ನು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
     <string name="system_locale_title" msgid="711882686834677268">"ಸಿಸ್ಟಂ ಡೀಫಾಲ್ಟ್"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index d75f3a8..43d8080 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"앱이 화면 잠금 길이와 유형의 가능한 범위를 나타내는 잠금 화면 복잡도 수준(높음, 보통, 낮음 또는 없음)을 파악하도록 허용합니다. 앱이 사용자에게 화면 잠금을 특정 수준으로 업데이트할 것을 제안할 수도 있지만, 사용자는 자유롭게 이를 무시하고 다른 곳으로 이동할 수 있습니다. 화면 잠금은 일반 텍스트로 저장되지 않으므로 앱에서 정확한 비밀번호를 알 수 없습니다."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"알림 표시"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"앱에서 알림을 표시하도록 허용"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"화면 켜기"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"앱이 화면을 켜도록 허용합니다."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"생체 인식 하드웨어 사용"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"앱에서 생체 인식 하드웨어를 인증에 사용하도록 허용합니다."</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"지문 하드웨어 관리"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"자세히 알아보기"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12에서는 Android 적응형 알림이 개선된 알림으로 대체됩니다. 이 기능은 추천 작업과 답장을 표시하고 알림을 정리해 줍니다.\n\n개선된 알림은 연락처 이름과 메시지 등 개인 정보가 포함된 알림 내용에 액세스할 수 있습니다. 또한 전화를 받고 방해 금지 모드를 제어하는 등 알림을 닫거나 처리하는 것도 가능합니다."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"루틴 모드 정보 알림"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"절전 모드 사용 설정됨"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"배터리 사용량을 줄여서 배터리 수명을 늘립니다."</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"절전 모드"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"절전 모드가 사용 중지되었습니다"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"휴대전화의 배터리가 충분하므로 기능이 더 이상 제한되지 않습니다"</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"사용자의 <xliff:g id="DEVICE">%1$s</xliff:g>에서 휴대전화 카메라에 액세스할 수 없습니다."</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"사용자의 <xliff:g id="DEVICE">%1$s</xliff:g>에서 태블릿 카메라에 액세스할 수 없습니다."</string>
     <string name="system_locale_title" msgid="711882686834677268">"시스템 기본값"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index b9d681c..8ce3f13 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Колдонмого экранды бөгөттөөнүн татаалдыгын (татаал, орточо, оңой же такыр жок) үйрөнүүгө мүмкүнчүлүк берет. Татаалдык деңгээли сырсөздүн узундугу жана экранды бөгөттөөнүн түрү боюнча айырмаланат. Колдонмо экранды бөгөттөөнү белгилүү деңгээлге тууралоону колдонуучуларга сунуштай да алат, бирок колдонуучулар ага көңүл бурбай койсо болот. Сырсөздү колдонмо билбеши үчүн, экранды бөгөттөө сырсөзүн кадимки текстте сактоого болбойт."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"билдирмелерди көрсөтүү"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Колдонмолор билдирмелерди көрсөтө алат"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"экранды күйгүзүү"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Колдонмого экранды күйгүзүүгө уруксат берет."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"биометрикалык аппаратты колдонуу"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Колдонмого аныктыгын текшерүү үчүн биометрикалык аппаратты пайдалануу мүмкүндүгүн берет"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"манжа изинин аппараттык камсыздоосун башкаруу"</string>
@@ -1229,7 +1231,7 @@
     <string name="smv_process" msgid="1398801497130695446">"<xliff:g id="PROCESS">%1$s</xliff:g> процесси өзүнүн мажбурланган StrictMode саясатын бузуп койду."</string>
     <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Телефон жаңырууда…"</string>
     <string name="android_upgrading_title" product="tablet" msgid="4268417249079938805">"Планшет жаңыртылууда…"</string>
-    <string name="android_upgrading_title" product="device" msgid="6774767702998149762">"Түзмөк жаңыртылууда…"</string>
+    <string name="android_upgrading_title" product="device" msgid="6774767702998149762">"Түзмөк жаңырууда…"</string>
     <string name="android_start_title" product="default" msgid="4036708252778757652">"Телефон күйгүзүлүүдө…"</string>
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android жүргүзүлүүдө…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Планшет күйгүзүлүүдө…"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн телефондун камерасына мүмкүнчүлүк жок"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн планшетиңиздин камерасына мүмкүнчүлүк жок"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Системанын демейки параметрлери"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index eeae8ce..197b4b3 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"ອະນຸຍາດໃຫ້ແອັບສຶກສາລະດັບຄວາມຊັບຊ້ອນຂອງໜ້າຈໍລັອກ (ສູງ, ກາງ ຫຼື ບໍ່ມີ), ເຊິ່ງລະບຸຂອບເຂດຄວາມເປັນໄປໄດ້ຂອງຄວາມຍາວ ແລະ ປະເພດຂອງການລັອກໜ້າຈໍ. ແອັບນີ້ສາມາດແນະນຳຜູ້ໃຊ້ວ່າເຂົາເຈົ້າສາມາດອັບເດດໜ້າຈໍລັອກເປັນລະດັບໃດໜຶ່ງເປັນການສະເພາະໄດ້, ແຕ່ຜູ້ໃຊ້ສາມາດທີ່ຈະບໍ່ສົນໃຈ ຫຼື ເປີດໄປອັນອື່ນໄດ້. ກະລຸນາຮັບຊາບວ່າການລັອກໜ້າຈໍບໍ່ໄດ້ບັນທຶກໃນແບບຂໍ້ຄວາມທຳມະດາ, ດັ່ງນັ້ນແອັບຈະບໍ່ຮູ້ລະຫັດຜ່ານທີ່ແນ່ນອນ."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"ສະແດງການແຈ້ງເຕືອນ"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"ອະນຸຍາດໃຫ້ແອັບສະແດງການແຈ້ງເຕືອນ"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"ເປີດໜ້າຈໍ"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"ອະນຸຍາດໃຫ້ແອັບເປີດໜ້າຈໍໄດ້."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"ໃຊ້ຮາດແວຊີວະມິຕິ"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"ອະນຸຍາດໃຫ້ແອັບນຳໃຊ້ຮາດແວຊີວະມິຕິສຳລັບການພິສູດຢືນຢັນ"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"ຈັດ​ການ​ຮາດ​ແວ​ລາຍ​ນີ້ວ​ມື"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ສຶກສາເພີ່ມເຕີມ"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"ການແຈ້ງເຕືອນແບບປັບຕົວໄດ້ຂອງ Android ຖືກແທນທີ່ດ້ວຍການແຈ້ງເຕືອນທີ່ປັບປຸງໃຫ້ດີຂຶ້ນໃນ Android 12 ແລ້ວ. ຄຸນສົມບັດນີ້ສະແດງຄຳສັ່ງ ແລະ ການຕອບກັບທີ່ແນະນຳ ແລະ ຈັດລະບຽບການແຈ້ງເຕືອນຂອງທ່ານ.\n\nການແຈ້ງເຕືອນທີ່ປັບປຸງໃຫ້ດີຂຶ້ນສາມາດເຂົ້າເຖິງເນື້ອຫາການແຈ້ງເຕືອນໄດ້, ຮວມທັງຂໍ້ມູນສ່ວນຕົວ ເຊັ່ນ: ຊື່ຜູ້ຕິດຕໍ່ ແລະ ຂໍ້ຄວາມ. ຄຸນສົມບັດນີ້ສາມາດປິດ ຫຼື ຕອບກັບຫາການແຈ້ງເຕືອນໄດ້ນຳ ເຊັ່ນ: ການຮັບສາຍໂທລະສັບ ແລະ ຄວບຄຸມໂໝດຫ້າມລົບກວນ."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ການແຈ້ງເຕືອນຂໍ້ມູນໂໝດກິດຈະວັດປະຈຳວັນ"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"ເປີດໃຊ້ຕົວປະຢັດແບັດເຕີຣີແລ້ວ"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"ກຳລັງຫຼຸດການໃຊ້ແບັດເຕີຣີເພື່ອຍືດອາຍຸແບັດເຕີຣີ"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"ຕົວປະຢັດແບັດເຕີຣີ"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"ປິດຕົວປະຢັດແບັດເຕີຣີແລ້ວ"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"ໂທລະສັບມີໄຟພຽງພໍແລ້ວ. ບໍ່ມີການຈຳກັດຄຸນສົມບັດອີກຕໍ່ໄປແລ້ວ."</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ບໍ່ສາມາດເຂົ້າເຖິງກ້ອງຖ່າຍຮູບຂອງໂທລະສັບຈາກ <xliff:g id="DEVICE">%1$s</xliff:g> ຂອງທ່ານໄດ້"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ບໍ່ສາມາດເຂົ້າເຖິງກ້ອງຖ່າຍຮູບຂອງແທັບເລັດຈາກ <xliff:g id="DEVICE">%1$s</xliff:g> ຂອງທ່ານໄດ້"</string>
     <string name="system_locale_title" msgid="711882686834677268">"ຄ່າເລີ່ມຕົ້ນຂອງລະບົບ"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index f68b292..a640897 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -555,6 +555,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Leidžiama programai sužinoti ekrano užrakto sudėtingumo lygį (aukštas, vidutinis, žemas arba nėra), nurodantį galimą ekrano užrakto trukmės diapazoną ir tipą. Be to, programa gali pasiūlyti naudotojams atnaujinti ekrano užraktą į tam tikrą lygį, bet naudotojai gali laisvai nepaisyti ir išeiti. Atminkite, kad ekrano užraktas nesaugomas kaip grynasis tekstas, todėl programa nežino tikslaus slaptažodžio."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"rodyti pranešimus"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Programai leidžiama rodyti pranešimus"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"įjungti ekraną"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Programai leidžiama įjungti ekraną."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"naudoti biometrinę aparatinę įrangą"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Leidžiama programai naudoti biometrinę aparatinę įrangą tapatybei nustatyti"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"tvarkyti piršto antspaudo aparatinę įrangą"</string>
@@ -2286,4 +2288,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nepavyko pasiekti telefono fotoaparato iš „<xliff:g id="DEVICE">%1$s</xliff:g>“"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nepavyko pasiekti planšetinio kompiuterio fotoaparato iš „<xliff:g id="DEVICE">%1$s</xliff:g>“"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Numatytoji sistemos vertė"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index d2bb73c..7612ea5 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -554,6 +554,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Atļauj lietotnei saglabāt informāciju par ekrāna bloķēšanas sarežģītības pakāpi (augsta, vidēja, zema, nav), kas apzīmē iespējamo garumu un ekrāna bloķēšanas veidus. Lietotnē lietotājiem var tikt rādīts arī ieteikums ekrāna bloķēšanai iestatīt citu līmeni, taču šo ieteikumu var ignorēt un aizvērt. Ņemiet vērā, ka ekrāna bloķēšanas parole netiek glabāta vienkārša teksta formātā, tāpēc lietotnei nav piekļuves precīzai parolei."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"Paziņojumu rādīšana"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Ļauj lietotnei rādīt paziņojumus."</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"ekrāna ieslēgšana"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Ļauj lietotnei ieslēgt ekrānu."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"izmantot biometrisko datu aparatūru"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Atļauj lietotnei izmantot biometrisko datu aparatūru autentificēšanai"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"pārvaldīt pirkstu nospiedumu aparatūru"</string>
@@ -2076,10 +2078,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Uzzināt vairāk"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android adaptīvie paziņojumi ir aizstāti ar funkciju “Uzlabotie paziņojumi” operētājsistēmā Android 12. Šī funkcija parāda ieteiktās darbības un atbildes, kā arī kārto jūsu paziņojumus.\n\nFunkcija “Uzlabotie paziņojumi” var piekļūt paziņojumu saturam, tostarp personas informācijai, piemēram, kontaktpersonu vārdiem un ziņojumiem. Šī funkcija var arī noraidīt paziņojumus vai atbildēt uz tiem, piemēram, atbildēt uz tālruņa zvaniem vai pārvaldīt funkciju “Netraucēt”."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Informatīvs paziņojums par akumulatoru"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Ieslēgts akumulatora enerģijas taupīšanas režīms"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Tiek samazināts akumulatora lietojums, lai paildzinātu akumulatora darbību."</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Akumulatora enerģijas taupīšanas režīms"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Akumulatora enerģijas taupīšanas režīms ir izslēgts"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Tālruņa uzlādes līmenis ir pietiekams. Funkcijas vairs netiek ierobežotas."</string>
@@ -2287,4 +2287,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nevar piekļūt tālruņa kamerai no jūsu ierīces (<xliff:g id="DEVICE">%1$s</xliff:g>)."</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nevar piekļūt planšetdatora kamerai no jūsu ierīces (<xliff:g id="DEVICE">%1$s</xliff:g>)."</string>
     <string name="system_locale_title" msgid="711882686834677268">"Sistēmas noklusējums"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 0df4312..15d1022 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Дозволува апликацијата да го научи нивото на сложеност за заклучувањето на екранот (високо, средно, ниско или нема), коешто ги означува можниот опсег на должината и типот на заклучувањето на екранот. Апликацијата може да им дава предлози на корисниците да го ажурираат заклучувањето на екранот на одредено ниво, но корисниците можат да го игнорираат и да продолжат понатаму. Имајте предвид дека заклучувањето на екранот не се складира како обичен текст, па апликацијата не ја знае точната лозинка."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"да прикажува известувања"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Ѝ дозволува на апликацијата да прикажува известувања"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"да го вклучува екранот"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Дозволува апликацијата да го вклучува екранот."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"користи биометриски хардвер"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Дозволува апликацијата да користи биометриски хардвер за проверка"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"управувај хардвер за отпечатоци"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Не може да се пристапи до камерата на вашиот телефон од <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Не може да се пристапи до камерата на вашиот таблет од <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Стандардно за системот"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index f18fb00..8365de4 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -43,7 +43,7 @@
     <string name="invalidPin" msgid="7542498253319440408">"4 മുതൽ 8 വരെ അക്കങ്ങളുള്ള ഒരു പിൻ ടൈപ്പുചെയ്യുക."</string>
     <string name="invalidPuk" msgid="8831151490931907083">"എട്ടോ അതിലധികമോ അക്കങ്ങളുള്ള ഒരു PUK ടൈപ്പുചെയ്യുക."</string>
     <string name="needPuk" msgid="7321876090152422918">"നിങ്ങളുടെ സിം കാർഡ് PUK ലോക്ക് ചെയ്‌തതാണ്. ഇത് അൺലോക്ക് ചെയ്യാൻ PUK കോഡ് ടൈപ്പുചെയ്യുക."</string>
-    <string name="needPuk2" msgid="7032612093451537186">"സിം കാർഡ് തടഞ്ഞത് മാറ്റാൻ PUK2 ടൈപ്പുചെയ്യുക."</string>
+    <string name="needPuk2" msgid="7032612093451537186">"സിം കാർഡ് അൺബ്ലോക്ക് ചെയ്യാൻ PUK2 ടൈപ്പ് ചെയ്യുക."</string>
     <string name="enablePin" msgid="2543771964137091212">"വിജയകരമല്ല, സിം/RUIM ലോക്ക് പ്രവർത്തനക്ഷമമാക്കുക."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
       <item quantity="other">SIM ലോക്കാകുന്നതിന് മുമ്പായി നിങ്ങൾക്ക് <xliff:g id="NUMBER_1">%d</xliff:g> ശ്രമങ്ങൾ കൂടി ശേഷിക്കുന്നു.</item>
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"സ്ക്രീൻ ലോക്കിന്റെ സാധ്യമായ നീളവും തരവും സൂചിപ്പിക്കുന്ന, അതിന്റെ സങ്കീർണ്ണത നില (ഉയർന്നത്, ഇടത്തരം, കുറഞ്ഞത് അല്ലെങ്കിൽ ഒന്നുമില്ല) മനസ്സിലാക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. സ്‌ക്രീൻ ലോക്ക് ഒരു പ്രത്യേക തലത്തിലേക്ക് അപ്ഡേറ്റ് ചെയ്യാൻ ഉപയോക്താക്കളെ നിർദ്ദേശിക്കാനും ആപ്പിനാവും, പക്ഷെ ഉപയോക്താക്കൾക്ക് എളുപ്പത്തിൽ അവഗണിക്കാനും മറ്റൊന്നിലേക്ക് നാവിഗേറ്റ് ചെയ്യാനുമാവും. പ്ലെയിൻടെക്‌സ്‌റ്റിൽ സ്ക്രീൻ ലോക്ക് സംഭരിക്കപ്പെട്ടിട്ടില്ലെന്ന കാര്യം ശ്രദ്ധിക്കുക, അതിനാൽ ആപ്പിന് കൃത്യമായ പാസ്‌വേഡ് അറിയില്ല."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"അറിയിപ്പുകൾ കാണിക്കുക"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"അറിയിപ്പുകൾ കാണിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"സ്ക്രീൻ ഓണാക്കുക"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"സ്ക്രീൻ ഓണാക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"ബയോമെട്രിക് ഹാർ‌ഡ്‌വെയർ ഉപയോഗിക്കുക"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"പരിശോധിച്ചുറപ്പിക്കുന്നതിനായി, ബയോമെട്രിക് ഹാർഡ്‌വെയർ ഉപയോഗിക്കാൻ ആപ്പിനെ അനുവദിക്കുക"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"ഫിംഗർപ്രിന്റ് ഹാർഡ്‌വെയർ നിയന്ത്രിക്കുക"</string>
@@ -1013,7 +1015,7 @@
     <string name="js_dialog_before_unload_negative_button" msgid="3873765747622415310">"ഈ പേജിൽ തുടരുക"</string>
     <string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nഈ പേജിൽ നിന്നും നാവിഗേറ്റുചെയ്‌തു പോകണമെന്ന് തീർച്ചയാണോ?"</string>
     <string name="save_password_label" msgid="9161712335355510035">"സ്ഥിരീകരിക്കുക"</string>
-    <string name="double_tap_toast" msgid="7065519579174882778">"നുറുങ്ങ്: സൂം ഇൻ ചെയ്യാനും സൂം ഔട്ട് ചെയ്യാനും ഇരട്ട-ടാപ്പുചെയ്യുക."</string>
+    <string name="double_tap_toast" msgid="7065519579174882778">"നുറുങ്ങ്: സൂം ഇൻ ചെയ്യാനും സൂം ഔട്ട് ചെയ്യാനും ഡബിൾ ടാപ്പ് ചെയ്യുക."</string>
     <string name="autofill_this_form" msgid="3187132440451621492">"ഓട്ടോഫിൽ"</string>
     <string name="setup_autofill" msgid="5431369130866618567">"ഓട്ടോഫിൽ സജ്ജീകരിക്കുക"</string>
     <string name="autofill_window_title" msgid="4379134104008111961">"<xliff:g id="SERVICENAME">%1$s</xliff:g> ഉപയോഗിച്ച് സ്വമേധയാ പൂരിപ്പിക്കുക"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"നിങ്ങളുടെ <xliff:g id="DEVICE">%1$s</xliff:g> എന്നതിൽ നിന്ന് ഫോണിന്റെ ക്യാമറ ആക്‌സസ് ചെയ്യാനാകില്ല"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"നിങ്ങളുടെ <xliff:g id="DEVICE">%1$s</xliff:g> എന്നതിൽ നിന്ന് ടാബ്‌ലെറ്റിന്റെ ക്യാമറ ആക്‌സസ് ചെയ്യാനാകില്ല"</string>
     <string name="system_locale_title" msgid="711882686834677268">"സിസ്‌റ്റം ഡിഫോൾട്ട്"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 3b679c8..2826b5d6 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -284,9 +284,9 @@
     <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Апп батарей ашиглаж байна"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Томруулах"</string>
     <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Хандалтын ашиглалт"</string>
-    <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> батерей ашиглаж байна"</string>
-    <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> апп батерей ашиглаж байна"</string>
-    <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Батерей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string>
+    <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> батарей ашиглаж байна"</string>
+    <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> апп батарей ашиглаж байна"</string>
+    <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Батарей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string>
     <string name="foreground_service_multiple_separator" msgid="5002287361849863168">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="8974401416068943888">"Аюулгүй горим"</string>
     <string name="android_system_label" msgid="5974767339591067210">"Андройд систем"</string>
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Аппад дэлгэцийн түгжээний боломжтой уртын хэмжээ болон төрлийг заадаг дэлгэцийн түгжээний төвөгтэй байдлын түвшнийг (өндөр, дундаж, бага эсвэл байхгүй) мэдэж авахыг зөвшөөрдөг. Түүнчлэн, апп хэрэглэгчдэд дэлгэцийн түгжээг тодорхой түвшинд шинэчлэхийг санал болгох боломжтой хэдий ч хэрэглэгч үүнийг чөлөөтэй үл хэрэгсэж, орхих боломжтой. Дэлгэцийн түгжээг ил бичвэрээр хадгалдаггүй тул энэ апп тодорхой нууц үгийг мэддэггүй болохыг анхаарна уу."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"мэдэгдэл харуулах"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Аппад мэдэгдэл харуулахыг зөвшөөрнө"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"дэлгэцийг асаах"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Аппад дэлгэцийг асаахыг зөвшөөрнө."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"биометрийн техник хангамжийг ашиглах"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Aппад биометрийн техник хангамжийг баталгаажуулалтад ашиглахыг зөвшөөрдөг"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"хурууны хээний төхөөрөмжийг удирдах"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Таны <xliff:g id="DEVICE">%1$s</xliff:g>-с утасны камерт хандах боломжгүй"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Таны <xliff:g id="DEVICE">%1$s</xliff:g>-с таблетын камерт хандах боломжгүй"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Системийн өгөгдмөл"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 0477a06..c54325c 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -43,7 +43,7 @@
     <string name="invalidPin" msgid="7542498253319440408">"4 ते 8 अंकांचा पिन टाइप करा."</string>
     <string name="invalidPuk" msgid="8831151490931907083">"8 अंकांचा किंवा मोठा PUK टाइप करा."</string>
     <string name="needPuk" msgid="7321876090152422918">"तुमचे सिम कार्ड PUK-लॉक केलेले आहे. ते अनलॉक करण्यासाठी PUK कोड टाइप करा."</string>
-    <string name="needPuk2" msgid="7032612093451537186">"सिम कार्ड अनावरोधित करण्यासाठी PUK2 टाइप करा."</string>
+    <string name="needPuk2" msgid="7032612093451537186">"सिम कार्ड अनब्लॉक करण्यासाठी PUK2 टाइप करा."</string>
     <string name="enablePin" msgid="2543771964137091212">"अयशस्वी, सिम/RUIM लॉक सुरू करा."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
       <item quantity="other">सिम लॉक होण्यापूर्वी आपल्याकडे <xliff:g id="NUMBER_1">%d</xliff:g> प्रयत्न उर्वरित आहेत.</item>
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"अ‍ॅपला स्क्रीन लॉक क्लिष्टता पातळी (उच्च, मध्यम, खालची किंवा काहीही नाही) जाणून घेऊ देते, जी लांबीची संभाव्य रेंज आणि स्क्रीन लॉकचा प्रकार सूचित करते. अ‍ॅप वापरकर्त्यांना असेदेखील सुचवू शकते की त्यांनी स्क्रीन लॉक ठरावीक पातळीपर्यंत अपडेट करावे, परंतु वापरकर्ते त्याकडे मोकळेपणाने दुर्लक्ष करू शकतात आणि तेथून नेव्हिगेट करू शकतात. स्क्रीन लॉक प्लेनटेक्स्टमध्ये स्टोअर केले जात नसल्यामुळे अ‍ॅपला नेमका पासवर्ड माहीत नसतो याची नोंद घ्या."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"सूचना दाखवा"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"ॲपला सूचना दाखवू देते"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"स्क्रीन सुरू करा"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"अ‍ॅपला स्क्रीन सुरू करण्याची परवानगी देते."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"बायोमेट्रिक हार्डवेअर वापरा"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"ऑथेंटिकेशनसाठी बायोमेट्रिक हार्डवेअरचा वापर करण्याची ॲपला अनुमती देते"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"फिंगरप्रिंट हार्डवेअर व्यवस्थापित करा"</string>
@@ -693,7 +695,7 @@
     <string name="permdesc_readMediaImages" msgid="5836219373138469259">"ॲपला तुमच्या शेअर केलेल्या स्टोरेजमधून इमेज फाइल वाचण्याची अनुमती देते."</string>
     <string name="permlab_sdcardWrite" msgid="4863021819671416668">"तुमच्या शेअर केलेल्या स्टोरेजच्या आशयांमध्ये सुधारणा करा किंवा हटवा"</string>
     <string name="permdesc_sdcardWrite" msgid="8376047679331387102">"ॲपला तुमच्या शेअर केलेल्या स्टोरेजचे आशय लिहिण्याची अनमती देते."</string>
-    <string name="permlab_use_sip" msgid="8250774565189337477">"SIP कॉल करा/प्राप्त करा"</string>
+    <string name="permlab_use_sip" msgid="8250774565189337477">"SIP कॉल करा/मिळवा"</string>
     <string name="permdesc_use_sip" msgid="3590270893253204451">"ॲपला SIP कॉल करण्‍याची आणि प्राप्त करण्‍याची अनुमती देते."</string>
     <string name="permlab_register_sim_subscription" msgid="1653054249287576161">"नवीन टेलिकॉम सिम कनेक्शनची नोंदणी करा"</string>
     <string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"नवीन टेलिकॉम सिम कनेक्शनची नोंदणी करण्यासाठी ॲपला अनुमती देते."</string>
@@ -729,7 +731,7 @@
     <string name="permdesc_setInputCalibration" msgid="2937872391426631726">"स्पर्श स्क्रीनची कॅलिब्रेशन प्राचले सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. सामान्य अ‍ॅप्स साठी कधीही आवश्यक नसते."</string>
     <string name="permlab_accessDrmCertificates" msgid="6473765454472436597">"DRM प्रमाणपत्रे अ‍ॅक्सेस करा"</string>
     <string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"DRM प्रमाणपत्रांची तरतूद करण्यासाठी आणि वापरण्यासाठी अनुप्रयोगास अनुमती देते. सामान्य ॲप्सकरिता कधीही आवश्यकता नसते."</string>
-    <string name="permlab_handoverStatus" msgid="7620438488137057281">"Android बीम स्थानांतरण स्थिती प्राप्त करा"</string>
+    <string name="permlab_handoverStatus" msgid="7620438488137057281">"Android बीम स्थानांतरण स्थिती मिळवा"</string>
     <string name="permdesc_handoverStatus" msgid="3842269451732571070">"वर्तमान Android बीम स्थानांतरणांविषयी माहिती प्राप्त करण्यासाठी या अनुप्रयोगास अनुमती देते"</string>
     <string name="permlab_removeDrmCertificates" msgid="710576248717404416">"DRM प्रमाणपत्रे काढा"</string>
     <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"DRM प्रमाणपत्रे काढण्यासाठी अनुप्रयोगास अनुमती देते. सामान्य अ‍ॅप्स साठी कधीही आवश्यकता नसते."</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"तुमच्या <xliff:g id="DEVICE">%1$s</xliff:g> वरून फोनचा कॅमेरा अ‍ॅक्सेस करू शकत नाही"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"तुमच्या <xliff:g id="DEVICE">%1$s</xliff:g> वरून टॅबलेटचा कॅमेरा अ‍ॅक्सेस करू शकत नाही"</string>
     <string name="system_locale_title" msgid="711882686834677268">"सिस्टीम डीफॉल्ट"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index cfb8739..c3fba8c 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Benarkan apl mengetahui tahap kekompleksan kunci skrin (tinggi, sederhana, rendah atau tiada) yang menunjukkan kemungkinan julat panjang dan jenis kunci skrin. Apl juga boleh mencadangkan kepada pengguna supaya mengemas kini kunci skrin pada tahap tertentu namun pengguna boleh mengabaikan dan menavigasi keluar dengan bebas. Sila ambil perhatian bahawa kunci skrin tidak disimpan dalam format teks biasa, maka apl tidak mengetahui kata laluan yang tepat."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"tunjukkan pemberitahuan"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Membenarkan apl menunjukkan pemberitahuan"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"hidupkan skrin"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Membenarkan apl untuk menghidupkan skrin."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"gunakan perkakasan biometrik"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Membenarkan apl menggunakan perkakasan biometrik untuk pengesahan"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"urus perkakasan cap jari"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Tidak dapat mengakses kamera telefon daripada <xliff:g id="DEVICE">%1$s</xliff:g> anda"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Tidak dapat mengakses kamera tablet daripada <xliff:g id="DEVICE">%1$s</xliff:g> anda"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Lalai sistem"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 07e54a6..665bbce 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"ဖုန်းမျက်နှာပြင်လော့ခ်၏ ရှုပ်ထွေးမှုအဆင့် (မြင့်၊ အလယ်အလတ်၊ နိမ့် သို့မဟုတ် မရှိ) အား လေ့လာရန် အက်ပ်ကို ခွင့်ပြုသည်။ ၎င်းက သတ်မှတ်ထားနိုင်သော ဖုန်းမျက်နှာပြင်လော့ခ်၏ စာလုံးရေနှင့် အမျိုးအစားကို ညွှန်ပြပေးသည်။ အသုံးပြုသူများအနေနှင့် ဖုန်းမျက်နှာပြင်လော့ခ်ကို အတိုင်းအတာတစ်ခုအထိ အဆင့်မြှင့်ရန် အက်ပ်က အကြံပြုနိုင်သည်။ သို့သော်လည်း အသုံးပြုသူများက ၎င်းကို ဂရုပြုမနေဘဲ လွတ်လပ်စွာ ကြည့်ရှုနိုင်ပါသည်။ ဖုန်းမျက်နှာပြင်လော့ခ်ကို စာသားအတိုင်း သိမ်းမထားသဖြင့် အက်ပ်သည် စကားဝှက်အစစ်ကို မသိနိုင်ကြောင်း သတိပြုပါ။"</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"အကြောင်းကြားချက်များ ပြခြင်း"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"အကြောင်းကြားချက်များ ပြရန် အက်ပ်ကို ခွင့်ပြုနိုင်သည်"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"ဖန်သားပြင်ဖွင့်ခြင်း"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"ဖန်သားပြင်ဖွင့်ရန် အက်ပ်ကို ခွင့်ပြုနိုင်သည်။"</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"ဇီဝဗေဒဆိုင်ရာ အချက်အလက်သုံး ကွန်ပျူတာဆိုင်ရာ စက်ပစ္စည်းကို အသုံးပြုရန်"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"အထောက်အထားစိစစ်ခြင်းအတွက် ဇီဝဗေဒဆိုင်ရာ သတင်းအချက်အလက်များသုံးသည့် ကွန်ပျူတာဆိုင်ရာ စက်ပစ္စည်းကို အသုံးပြုရန် အက်ပ်ကို ခွင့်ပြုသည်"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"လက်ဗွေစစ်ပစ္စည်းကို စီမံခြင်း"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"သင်၏ <xliff:g id="DEVICE">%1$s</xliff:g> မှ ဖုန်းကင်မရာကို သုံး၍မရပါ"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"သင်၏ <xliff:g id="DEVICE">%1$s</xliff:g> မှ တက်ဘလက်ကင်မရာကို သုံး၍မရပါ"</string>
     <string name="system_locale_title" msgid="711882686834677268">"စနစ်မူရင်း"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index d5d230b..65b58acb 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -88,7 +88,7 @@
     <string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Status for mobildata"</string>
     <string name="notification_channel_sms" msgid="1243384981025535724">"SMS-meldinger"</string>
     <string name="notification_channel_voice_mail" msgid="8457433203106654172">"Talepostmeldinger"</string>
-    <string name="notification_channel_wfc" msgid="9048240466765169038">"Wi-Fi-anrop"</string>
+    <string name="notification_channel_wfc" msgid="9048240466765169038">"Wifi-anrop"</string>
     <string name="notification_channel_sim" msgid="5098802350325677490">"SIM-status"</string>
     <string name="notification_channel_sim_high_prio" msgid="642361929452850928">"SIM-status er satt til høy prioritet"</string>
     <string name="peerTtyModeFull" msgid="337553730440832160">"Motpart ba om TTY-modus FULL"</string>
@@ -117,25 +117,25 @@
     <string name="roamingText11" msgid="5245687407203281407">"Roaming-banner på"</string>
     <string name="roamingText12" msgid="673537506362152640">"Roaming-banner av"</string>
     <string name="roamingTextSearching" msgid="5323235489657753486">"Leter etter tjeneste"</string>
-    <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Kunne ikke konfigurere Wi-Fi-anrop"</string>
+    <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Kunne ikke konfigurere wifi-anrop"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="468830943567116703">"For å ringe og sende meldinger over Wi-Fi, må du først be operatøren om å konfigurere denne tjenesten. Deretter slår du på Wi-Fi-anrop igjen fra Innstillinger. (Feilkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
+    <item msgid="468830943567116703">"For å ringe og sende meldinger over Wi-Fi, må du først be operatøren om å konfigurere denne tjenesten. Deretter slår du på wifi-anrop igjen fra Innstillinger. (Feilkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="4795145070505729156">"Problem med å registrere Wi-Fi-anrop med operatøren din: <xliff:g id="CODE">%1$s</xliff:g>"</item>
+    <item msgid="4795145070505729156">"Problem med å registrere wifi-anrop med operatøren din: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
     <!-- no translation found for wfcSpnFormat_spn (2982505428519096311) -->
     <skip />
-    <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi-anrop"</string>
-    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"<xliff:g id="SPN">%s</xliff:g>-Wi-Fi-anrop"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> Wifi-anrop"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"<xliff:g id="SPN">%s</xliff:g>-Wifi-anrop"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="4895315549916165700">"WLAN-anrop"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="255919245825481510">"<xliff:g id="SPN">%s</xliff:g> WLAN-anrop"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="7232899594327126970">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
-    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Wi-Fi-anrop | <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Wifi-anrop | <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_vowifi" msgid="6865214948822061486">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
-    <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Wi-Fi-anrop"</string>
+    <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Wifi-anrop"</string>
     <string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
-    <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi-anrop"</string>
+    <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wifi-anrop"</string>
     <string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="5626710010766902560">"Av"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Ring via Wi-Fi"</string>
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Lar appen lære skjermlåsens kompleksitetsnivå (høy, middels, lav eller ingen), som indikerer det mulige området for lengde og type skjermlås. Appen kan foreslå at brukeren oppdaterer skjermlåsen til et bestemt nivå, men brukere kan velge å ignorere dette og navigere bort. Vær oppmerksom på at skjermlåsen ikke er lagret klartekst, så appen kan ikke se det nøyaktige passordet."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"vise varsler"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Lar appen vise varsler"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"slå på skjermen"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Gir appen tillatelse til å slå på skjermen."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"bruke biometrisk maskinvare"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Lar appen bruke biometrisk maskinvare til godkjenning"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"administrere fingeravtrykkmaskinvare"</string>
@@ -1036,9 +1038,9 @@
     <string name="permlab_readHistoryBookmarks" msgid="9102293913842539697">"lese nettbokmerkene og nettloggen din"</string>
     <string name="permdesc_readHistoryBookmarks" msgid="2323799501008967852">"Lar appen lese loggen for alle nettadressene nettleseren har besøkt, og alle bokmerkene i nettleseren. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
     <string name="permlab_writeHistoryBookmarks" msgid="6090259925187986937">"skrive nettbokmerker og nettlogg"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"Lar appen endre nettleserens logg eller bokmerker lagret på nettbrettet ditt. Dette kan føre til at appen sletter eller endrer nettleserdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"Lar appen endre nettleserens logg eller bokmerker som er lagret på Android TV-enheten din. Dette kan føre til at appen sletter eller endrer nettleserdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"Lar appen endre nettleserens logg eller bokmerker lagret på telefonen din. Dette kan føre til at appen sletter eller endrer nettleserdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"Lar appen endre nettleserens logg eller bokmerker lagret på nettbrettet ditt. Dette kan føre til at appen sletter eller endrer nettlesingsdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"Lar appen endre nettleserens logg eller bokmerker som er lagret på Android TV-enheten din. Dette kan føre til at appen sletter eller endrer nettlesingsdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"Lar appen endre nettleserens logg eller bokmerker lagret på telefonen din. Dette kan føre til at appen sletter eller endrer nettlesingsdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
     <string name="permlab_setAlarm" msgid="1158001610254173567">"stille alarm"</string>
     <string name="permdesc_setAlarm" msgid="2185033720060109640">"Lar appen stille inn alarmen for en installert alarmklokke-app. Enkelte alarmklokke-apper implementerer kanskje ikke denne funksjonen."</string>
     <string name="permlab_addVoicemail" msgid="4770245808840814471">"legge til talepost"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Finn ut mer"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Forbedrede varsler erstatter tilpassede Android-varsler i Android 12. Denne funksjonen viser foreslåtte handlinger og svar og organiserer varslene dine.\n\nForbedrede varsler har tilgang til varselinnhold, inkludert personopplysninger som kontaktnavn og meldinger. Funksjonen kan også avvise og svare på varsler, for eksempel svare på anrop og kontrollere «Ikke forstyrr»."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Varsel med informasjon om rutinemodus"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Batterisparing er slått på"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Reduserer batteribruken for å forlenge batterilevetiden"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Batterisparing"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Batterisparing er slått av"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Telefonen har nok batteri. Funksjoner begrenses ikke lenger."</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Det er ikke mulig å få tilgang til telefonkameraet fra <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Det er ikke mulig å få tilgang til kameraet på nettbrettet fra <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Systemstandard"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 6f10404..4aa6081 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"यसले एपलाई स्क्रिन लकको जटिलताको स्तर (उच्च, मध्यम, न्यून वा कुनै पनि होइन) थाहा पाउने अनुमति दिन्छ जसले स्क्रिन लकको लम्बाइको सम्भावित दायरा र त्यसको प्रकारलाई जनाउँछ। यसै गरी, यो एपले प्रयोगकर्ताहरूलाई स्क्रिन लक अद्यावधिक गर्ने सुझाव पनि दिन सक्छ तर प्रयोगकर्ताहरू उक्त सुझावको बेवास्ता गरी बाहिर निस्कन सक्छन्। स्क्रिन लक सादा पाठको ढाँचामा भण्डारण नगरिने हुँदा यो एपलाई वास्तविक पासवर्ड थाहा नहुने कुराको हेक्का राख्नुहोस्।"</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"सूचनाहरू देखाइयोस्"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"यो एपलाई सूचना देखाउन दिनुहोस्"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"स्क्रिन अन गर्ने"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"यो एपलाई स्क्रिन अन गर्ने अनुमति दिन्छ।"</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"बायोमेट्रिक हार्डवेयर प्रयोग गर्नुहोस्‌"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"एपलाई प्रमाणीकरणका लागि बायोमेट्रिक हार्डवेयर प्रयोग गर्न अनुमति दिन्छ"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"फिंगरप्रिन्ट हार्डवेयर व्यवस्थापन गर्नुहोस्"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"थप जान्नुहोस्"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android १२ मा Android को अनुकूल पार्न मिल्ने सूचनाहरू नामक सुविधालाई परिष्कृत सूचनाहरू नामक सुविधाले प्रतिस्थापन गरेको छ। यो सुविधाले कारबाही तथा जवाफसम्बन्धी सुझाव देखाउँछ र तपाईंका सूचनाहरू व्यवस्थित गर्छ।\n\nपरिष्कृत सूचनाहरू नामक सुविधाले सूचनामा उल्लिखित सम्पर्क व्यक्तिको नाम र म्यासेज जस्ता व्यक्तिगत जानकारीलगायतका सामग्री हेर्न तथा प्रयोग गर्न सक्छ। यो सुविधाले फोन उठाउने तथा \'बाधा नपुऱ्याउनुहोस्\' मोड नियन्त्रण गर्ने कार्यसहित सूचनाहरू हटाउने वा सूचनाहरूको जवाफ दिने कार्य पनि गर्न सक्छ।"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"दिनचर्या मोडको जानकारीमूलक सूचना"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"ब्याट्री सेभर अन गरिएको छ"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"ब्याट्रीको आयु बढाउन ब्याट्रीको खपत कम गरिँदै छ"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"ब्याट्री सेभर"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"ब्याट्री सेभर अफ गरियो"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"फोनमा पर्याप्त चार्ज छ। सुविधाहरूलाई अब उप्रान्त प्रतिबन्ध लगाइँदैन।"</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"तपाईंको <xliff:g id="DEVICE">%1$s</xliff:g> मार्फत फोनको क्यामेरा प्रयोग गर्न मिल्दैन"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"तपाईंको <xliff:g id="DEVICE">%1$s</xliff:g> मार्फत ट्याब्लेटको क्यामेरा प्रयोग गर्न मिल्दैन"</string>
     <string name="system_locale_title" msgid="711882686834677268">"सिस्टम डिफल्ट"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 6c4b68e..974d642 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Hiermee krijgt de app toestemming om het complexiteitsniveau van de schermvergrendeling te achterhalen (hoog, midden, laag of geen). Dat geeft een indicatie van het mogelijke lengtebereik en type van de schermvergrendeling. De app kan gebruikers ook voorstellen de schermvergrendeling naar een bepaald niveau te updaten, maar gebruikers kunnen dit altijd negeren en de app verlaten. De schermvergrendeling wordt niet opgeslagen als platte tekst, zodat de app het precieze wachtwoord niet weet."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"meldingen laten zien"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Hiermee kan de app meldingen laten zien"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"het scherm aanzetten"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Hiermee kan de app het scherm aanzetten."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"biometrische hardware gebruiken"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Hiermee kan de app biometrische hardware gebruiken voor verificatie"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"Vingerafdrukhardware beheren"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Kan geen toegang tot de camera van de telefoon krijgen vanaf je <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Kan geen toegang tot de camera van de tablet krijgen vanaf je <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Systeemstandaard"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 331e300..f5922b9 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"ସ୍କ୍ରିନ୍ ଲକ୍‌ର ଜଟିଳତା ସ୍ତର (ଉଚ୍ଚ, ମଧ୍ୟମ, ନିମ୍ନ କିମ୍ବା କିଛିନୁହେଁ), ଜାଣିବାକୁ ଆପ୍‌କୁ ଅନୁମତି ଦିଅନ୍ତୁ, ଯାହା ସ୍କ୍ରିନ୍ ଲକ୍‌ର ସମ୍ଭାବ୍ୟ ପରିସୀମାର ଲମ୍ବ ଏବଂ ପ୍ରକାର ସୂଚୀତ କରେ। ଆପ୍ ଏହା ମଧ୍ୟ ଉପଯୋଗକର୍ତ୍ତାମାନଙ୍କୁ ପରାମର୍ଶ ଦେଇପାରେ ଯେ ସେମାନେ ସ୍କ୍ରିନ୍ ଲକ୍‌କୁ ଏକ ନିର୍ଦ୍ଧିଷ୍ଟ ସ୍ତର ପର୍ଯ୍ୟନ୍ତ ଅପ୍‌ଡେଟ୍ କରିପାରନ୍ତି, କିନ୍ତୁ ଉପଯୋଗକର୍ତ୍ତାମାନେ ନିଜ ଇଚ୍ଛାରେ ଏହାକୁ ଉପେକ୍ଷା ଏବଂ ନାଭିଗେଟ୍ କରିପାରିବେ। ଧ୍ୟାନ ଦିଅନ୍ତୁ ଯେ, ସ୍କ୍ରିନ୍ ଲକ୍ ସରଳ ଟେକ୍ସଟ୍‌ରେ ଷ୍ଟୋର୍ କରାଯାଇନଥାଏ ତେଣୁ ଆପ୍ ସଠିକ୍ ପାସ୍‌‍ୱର୍ଡ ଜାଣିପାରି ନଥାଏ।"</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଦେଖାନ୍ତୁ"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଦେଖାଇବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"ସ୍କ୍ରିନ ଚାଲୁ କରନ୍ତୁ"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"ସ୍କ୍ରିନ ଚାଲୁ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"ବାୟୋମେଟ୍ରିକ୍‌ ହାର୍ଡୱେର୍‌ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"ସ୍ୱୀକୃତି ପାଇଁ ବାୟୋମେଟ୍ରିକ୍‌ ହାର୍ଡୱେର୍‌ ବ୍ୟବହାର କରିବାକୁ ଅନୁମତି ଦିଏ"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"ଟିପଚିହ୍ନ ହାର୍ଡୱେର୍‍ ପରିଚାଳନା କରନ୍ତୁ"</string>
@@ -1151,9 +1153,9 @@
     <string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଚାଲୁଛି"</string>
     <string name="app_running_notification_text" msgid="5120815883400228566">"ଅଧିକ ସୂଚନା ପାଇଁ କିମ୍ବା ଆପ୍‍ ବନ୍ଦ କରିବାକୁ ଟାପ୍‍ କରନ୍ତୁ।"</string>
     <string name="ok" msgid="2646370155170753815">"ଠିକ୍‍ ଅଛି"</string>
-    <string name="cancel" msgid="6908697720451760115">"ବାତିଲ୍‍ କରନ୍ତୁ"</string>
+    <string name="cancel" msgid="6908697720451760115">"ବାତିଲ କରନ୍ତୁ"</string>
     <string name="yes" msgid="9069828999585032361">"ଠିକ୍‍ ଅଛି"</string>
-    <string name="no" msgid="5122037903299899715">"ବାତିଲ୍‍ କରନ୍ତୁ"</string>
+    <string name="no" msgid="5122037903299899715">"ବାତିଲ କରନ୍ତୁ"</string>
     <string name="dialog_alert_title" msgid="651856561974090712">"ଧ୍ୟାନଦିଅନ୍ତୁ"</string>
     <string name="loading" msgid="3138021523725055037">"ଲୋଡ୍ କରାଯାଉଛି…"</string>
     <string name="capital_on" msgid="2770685323900821829">"ଚାଲୁ"</string>
@@ -1174,9 +1176,9 @@
     <string name="whichOpenLinksWithApp" msgid="6917864367861910086">"<xliff:g id="APPLICATION">%1$s</xliff:g> ମାଧ୍ୟମରେ ଲିଙ୍କ୍‍ଗୁଡ଼ିକ ଖୋଲନ୍ତୁ"</string>
     <string name="whichOpenHostLinksWithApp" msgid="2401668560768463004">"<xliff:g id="APPLICATION">%2$s</xliff:g> ମାଧ୍ୟମରେ <xliff:g id="HOST">%1$s</xliff:g> ଲିଙ୍କ୍‍ଗୁଡ଼ିକ ଖୋଲନ୍ତୁ"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="7805857277166106236">"ଆକ୍ସେସ୍‌ ଦିଅନ୍ତୁ"</string>
-    <string name="whichEditApplication" msgid="6191568491456092812">"ସହିତ ଏଡିଟ୍‌ କରନ୍ତୁ"</string>
-    <string name="whichEditApplicationNamed" msgid="8096494987978521514">"%1$sରେ ସଂଶୋଧନ କରନ୍ତୁ"</string>
-    <string name="whichEditApplicationLabel" msgid="1463288652070140285">"ଏଡିଟ୍‌ କରନ୍ତୁ"</string>
+    <string name="whichEditApplication" msgid="6191568491456092812">"ସହିତ ଏଡିଟ କରନ୍ତୁ"</string>
+    <string name="whichEditApplicationNamed" msgid="8096494987978521514">"%1$sରେ ଏଡିଟ କରନ୍ତୁ"</string>
+    <string name="whichEditApplicationLabel" msgid="1463288652070140285">"ଏଡିଟ କରନ୍ତୁ"</string>
     <string name="whichSendApplication" msgid="4143847974460792029">"ସେୟାର୍ କରନ୍ତୁ"</string>
     <string name="whichSendApplicationNamed" msgid="4470386782693183461">"%1$s ସହିତ ସେୟାର୍‌ କରନ୍ତୁ"</string>
     <string name="whichSendApplicationLabel" msgid="7467813004769188515">"ସେୟାର୍‌ କରନ୍ତୁ"</string>
@@ -1318,7 +1320,7 @@
     <string name="sms_short_code_details" msgid="2723725738333388351">"ଏହା ଦ୍ୱାରା "<b>" ଆପଣଙ୍କ ମୋବାଇଲ୍ ଆକାଉଣ୍ଟରୁ ପଇସା କଟିପାରେ। "</b></string>
     <string name="sms_premium_short_code_details" msgid="1400296309866638111"><b>" ଆପଣଙ୍କ ମୋବାଇଲ୍ ଆକାଉଣ୍ଟରୁ ପଇସା କଟିପାରେ। "</b></string>
     <string name="sms_short_code_confirm_allow" msgid="920477594325526691">"ପଠାନ୍ତୁ"</string>
-    <string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"ବାତିଲ୍‍ କରନ୍ତୁ"</string>
+    <string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"ବାତିଲ କରନ୍ତୁ"</string>
     <string name="sms_short_code_remember_choice" msgid="1374526438647744862">"ମୋ ପସନ୍ଦ ମନେରଖନ୍ତୁ"</string>
     <string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"ଏହାକୁ ଆପଣ ସେଟିଙ୍ଗ ଓ ଆପ୍‍ରେ ପରବର୍ତ୍ତୀ ସମୟରେ ବଦଳାଇପାରିବେ"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"ସର୍ବଦା ଅନୁମତି ଦିଅନ୍ତୁ"</string>
@@ -1355,7 +1357,7 @@
     <string name="usb_power_notification_message" msgid="7284765627437897702">"ଯୋଡ଼ାଯାଇଥିବା ଡିଭାଇସ୍ ଚାର୍ଜ ହେଉଛି। ଅଧିକ ବିକଳ୍ପ ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
     <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"ଆନାଲଗ୍‍ ଅଡିଓ ଆକ୍ସେସରୀ ଚିହ୍ନଟ ହେଲା"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"ଏହି ଫୋନ୍‌ରେ କନେକ୍ଟ ଥିବା ଡିଭାଇସ୍‍ କମ୍ପାଟିବଲ୍‍ ନୁହେଁ। ଅଧିକ ଜାଣିବା ପାଇଁ ଟାପ୍‌ କରନ୍ତୁ।"</string>
-    <string name="adb_active_notification_title" msgid="408390247354560331">"USB ଡିବଗିଂ ସଂଯୁକ୍ତ ହୋଇଛି"</string>
+    <string name="adb_active_notification_title" msgid="408390247354560331">"USB ଡିବଗିଂ କନେକ୍ଟ କରାଯାଇଛି"</string>
     <string name="adb_active_notification_message" msgid="5617264033476778211">"USB ଡିବଗିଂକୁ ବନ୍ଦ କରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string>
     <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB ଡିବଗିଙ୍ଗକୁ ଅକ୍ଷମ କରିବା ପାଇଁ ଚୟନ କରନ୍ତୁ।"</string>
     <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"ୱାୟାରଲେସ୍ ଡିବଗିଂ ସଂଯୋଗ କରାଯାଇଛି"</string>
@@ -1541,7 +1543,7 @@
     <string name="date_picker_prev_month_button" msgid="3418694374017868369">"ପୂର୍ବ ମାସ"</string>
     <string name="date_picker_next_month_button" msgid="4858207337779144840">"ପରବର୍ତ୍ତୀ ମାସ"</string>
     <string name="keyboardview_keycode_alt" msgid="8997420058584292385">"ALT"</string>
-    <string name="keyboardview_keycode_cancel" msgid="2134624484115716975">"ବାତିଲ୍‍ କରନ୍ତୁ"</string>
+    <string name="keyboardview_keycode_cancel" msgid="2134624484115716975">"ବାତିଲ କରନ୍ତୁ"</string>
     <string name="keyboardview_keycode_delete" msgid="2661117313730098650">"ଡିଲିଟ୍‍ କରନ୍ତୁ"</string>
     <string name="keyboardview_keycode_done" msgid="2524518019001653851">"ହୋଇଗଲା"</string>
     <string name="keyboardview_keycode_mode_change" msgid="2743735349997999020">"ମୋଡ୍‍ ପରିବର୍ତ୍ତନ"</string>
@@ -1564,7 +1566,7 @@
     <string name="storage_usb_drive" msgid="448030813201444573">"USB ଡ୍ରାଇଭ୍‍"</string>
     <string name="storage_usb_drive_label" msgid="6631740655876540521">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB ଡ୍ରାଇଭ୍‍"</string>
     <string name="storage_usb" msgid="2391213347883616886">"USB ଷ୍ଟୋରେଜ୍‌"</string>
-    <string name="extract_edit_menu_button" msgid="63954536535863040">"ଏଡିଟ୍‌ କରନ୍ତୁ"</string>
+    <string name="extract_edit_menu_button" msgid="63954536535863040">"ଏଡିଟ କରନ୍ତୁ"</string>
     <string name="data_usage_warning_title" msgid="9034893717078325845">"ଡାଟା ଚେତାବନୀ"</string>
     <string name="data_usage_warning_body" msgid="1669325367188029454">"ଆପଣ <xliff:g id="APP">%s</xliff:g> ଡାଟା ବ୍ୟବହାର କରିସାରିଛନ୍ତି"</string>
     <string name="data_usage_mobile_limit_title" msgid="3911447354393775241">"ମୋବାଇଲ୍ ଡାଟା ଧାର୍ଯ୍ୟ ସୀମାରେ ପହଞ୍ଚିଲା"</string>
@@ -1690,7 +1692,7 @@
     <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"ଆକ୍ସେସିବିଲିଟୀ ବଟନ୍ ସହିତ ବ୍ୟବହାର କରିବାକୁ ଫିଚରଗୁଡ଼ିକ ବାଛନ୍ତୁ"</string>
     <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"ଭଲ୍ୟୁମ୍ କୀ ସର୍ଟକଟ୍ ସହିତ ବ୍ୟବହାର କରିବାକୁ ଫିଚରଗୁଡ଼ିକ ବାଛନ୍ତୁ"</string>
     <string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"<xliff:g id="SERVICE_NAME">%s</xliff:g> ବନ୍ଦ ହୋଇଯାଇଛି"</string>
-    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ସର୍ଟକଟଗୁଡ଼ିକୁ ସମ୍ପାଦନ କରନ୍ତୁ"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ସର୍ଟକଟଗୁଡ଼ିକୁ ଏଡିଟ କରନ୍ତୁ"</string>
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"ହୋଇଗଲା"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ଶର୍ଟକଟ୍‍ ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ଶର୍ଟକଟ୍‍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
@@ -2045,7 +2047,7 @@
     <string name="log_access_confirmation_body" msgid="6581985716241928135">"ଆପଣଙ୍କ ଡିଭାଇସରେ ଯାହା ହୁଏ ତାହା ଡିଭାଇସ ଲଗଗୁଡ଼ିକ ରେକର୍ଡ କରେ। ସମସ୍ୟାଗୁଡ଼ିକୁ ଖୋଜି ସମାଧାନ କରିବାକୁ ଆପ୍ସ ଏହି ଲଗଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିପାରିବ।\n\nକିଛି ଲଗରେ ସମ୍ବେଦନଶୀଳ ସୂଚନା ଥାଇପାରେ, ତେଣୁ ସମସ୍ତ ଡିଭାଇସ ଲଗକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଆପଣ ବିଶ୍ୱାସ କରୁଥିବା ଆପ୍ସକୁ ହିଁ ଅନୁମତି ଦିଅନ୍ତୁ। \n\nଯଦି ଆପଣ ସମସ୍ତ ଡିଭାଇସ ଲଗକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଏହି ଆପକୁ ଅନୁମତି ଦିଅନ୍ତି ନାହିଁ, ତେବେ ବି ଏହା ନିଜର ଡିଭାଇସ ଲଗଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିପାରିବ। ଆପଣଙ୍କ ଡିଭାଇସର ନିର୍ମାତା ଏବେ ବି ଆପଣଙ୍କର ଡିଭାଇସରେ କିଛି ଲଗ କିମ୍ବା ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ସକ୍ଷମ ହୋଇପାରନ୍ତି। ଅଧିକ ଜାଣନ୍ତୁ"</string>
     <string name="log_access_do_not_show_again" msgid="1058690599083091552">"ପୁଣି ଦେଖାନ୍ତୁ ନାହିଁ"</string>
     <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g>, <xliff:g id="APP_2">%2$s</xliff:g> ସ୍ଲାଇସ୍‌କୁ ଦେଖାଇବା ପାଇଁ ଚାହେଁ"</string>
-    <string name="screenshot_edit" msgid="7408934887203689207">"ଏଡିଟ୍ କରନ୍ତୁ"</string>
+    <string name="screenshot_edit" msgid="7408934887203689207">"ଏଡିଟ କରନ୍ତୁ"</string>
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"କଲ୍ ଓ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଭାଇବ୍ରେଟ୍ ହେବ"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"କଲ୍ ଓ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ନିଃଶବ୍ଦ କରିଦିଆଯିବ"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"ସିଷ୍ଟମ୍‌ରେ ପରିବର୍ତ୍ତନ"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ଆପଣଙ୍କ <xliff:g id="DEVICE">%1$s</xliff:g>ରୁ ଫୋନର କ୍ୟାମେରାକୁ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ଆପଣଙ୍କ <xliff:g id="DEVICE">%1$s</xliff:g>ରୁ ଟାବଲେଟର କ୍ୟାମେରାକୁ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ"</string>
     <string name="system_locale_title" msgid="711882686834677268">"ସିଷ୍ଟମ ଡିଫଲ୍ଟ"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 2f3294e..ce8d323 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"ਐਪ ਨੂੰ ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਜਟਿਲਤਾ ਦੇ ਪੱਧਰ ਬਾਰੇ ਜਾਣਨ ਦਿਓ (ਉੱਚ, ਮੱਧਮ, ਘੱਟ ਜਾਂ ਕੋਈ ਨਹੀਂ), ਜੋ ਲੰਬਾਈ ਦੀ ਸੰਭਵ ਰੇਂਜ ਅਤੇ ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਕਿਸਮ ਦਾ ਸੰਕੇਤ ਦਿੰਦਾ ਹੈ। ਐਪ ਵਰਤੋਂਕਾਰਾਂ ਨੂੰ ਇੱਕ ਖਾਸ ਪੱਧਰ ਤੱਕ ਸਕ੍ਰੀਨ ਲਾਕ ਅੱਪਡੇਟ ਕਰਨ ਲਈ ਸੁਝਾਅ ਵੀ ਦੇ ਸਕਦੀ ਹੈ ਪਰ ਵਰਤੋਂਕਾਰ ਇਸਨੂੰ ਅਣਡਿੱਠ ਕਰ ਸਕਦੇ ਹਨ। ਨੋਟ ਕਰੋ ਕਿ ਸਕ੍ਰੀਨ ਲਾਕ ਸਧਾਰਨ ਲਿਖਤ ਵਿੱਚ ਸਟੋਰ ਨਹੀਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ ਇਸ ਲਈ ਐਪ ਸਹੀ ਪਾਸਵਰਡ ਬਾਰੇ ਨਹੀਂ ਜਾਣਦੀ ਹੈ।"</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"ਸੂਚਨਾਵਾਂ ਦਿਖਾਓ"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"ਇਸ ਨਾਲ ਐਪ ਨੂੰ ਸੂਚਨਾਵਾਂ ਦਿਖਾਉਣ ਦੀ ਆਗਿਆ ਮਿਲਦੀ ਹੈ"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"ਸਕ੍ਰੀਨ ਚਾਲੂ ਕਰੋ"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"ਐਪ ਨੂੰ ਸਕ੍ਰੀਨ ਚਾਲੂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ।"</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"ਬਾਇਓਮੈਟ੍ਰਿਕ ਹਾਰਡਵੇਅਰ ਵਰਤੋ"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"ਐਪ ਨੂੰ ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਬਾਇਓਮੈਟ੍ਰਿਕ ਹਾਰਡਵੇਅਰ ਵਰਤਣ ਦਿੰਦਾ ਹੈ"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਹਾਰਡਵੇਅਰ ਵਿਵਸਥਿਤ ਕਰੋ"</string>
@@ -1267,7 +1269,7 @@
     <string name="volume_ringtone" msgid="134784084629229029">"ਰਿੰਗਰ ਵੌਲਿਊਮ"</string>
     <string name="volume_music" msgid="7727274216734955095">"ਮੀਡੀਆ ਦੀ ਅਵਾਜ਼"</string>
     <string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Bluetooth ਰਾਹੀਂ ਪਲੇ ਕਰ ਰਿਹਾ ਹੈ"</string>
-    <string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"ਖਾਮੋਸ਼ ਰਿੰਗਟੋਨ ਸੈੱਟ ਕੀਤੀ"</string>
+    <string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"ਸ਼ਾਂਤ ਰਿੰਗਟੋਨ ਸੈੱਟ ਕੀਤੀ"</string>
     <string name="volume_call" msgid="7625321655265747433">"ਇਨ-ਕਾਲ ਅਵਾਜ਼"</string>
     <string name="volume_bluetooth_call" msgid="2930204618610115061">"ਬਲੂਟੁੱਥ ਇਨ-ਕਾਲ ਅਵਾਜ਼"</string>
     <string name="volume_alarm" msgid="4486241060751798448">"ਅਲਾਰਮ ਦੀ ਅਵਾਜ਼"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> ਤੋਂ ਫ਼ੋਨ ਦੇ ਕੈਮਰੇ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> ਤੋਂ ਟੈਬਲੈੱਟ ਦੇ ਕੈਮਰੇ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string>
     <string name="system_locale_title" msgid="711882686834677268">"ਸਿਸਟਮ ਪੂਰਵ-ਨਿਰਧਾਰਿਤ"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 55c4574..6fc0696 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -555,6 +555,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Zezwala aplikacji na poznanie stopnia złożoności blokady ekranu (wysoki, średni, niski lub brak), który wskazuje na możliwy zakres długości oraz typ blokady ekranu. Aplikacja może też zasugerować zaktualizowanie blokady ekranu pod kątem określonego stopnia trudności, ale użytkownik może to zignorować i zamknąć komunikat. Pamiętaj, że blokada ekranu nie jest zapisywana jako tekst jawny, więc aplikacja nie pozna dokładnego hasła."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"pokazuj powiadomienia"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Zezwala aplikacji na pokazywanie powiadomień"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"włączanie ekranu"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Zezwala aplikacji na włączanie ekranu."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"używanie sprzętu biometrycznego"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Zezwala aplikacji na używanie sprzętu biometrycznego na potrzeby autoryzacji"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"zarządzanie czytnikiem linii papilarnych"</string>
@@ -2286,4 +2288,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nie można korzystać z aparatu telefonu na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nie można korzystać z aparatu tabletu na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Ustawienie domyślne systemu"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index a02c200..caa8cd1 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Permite que o app saiba o nível de complexidade do bloqueio de tela (alto, médio, baixo ou nenhum), que indica o intervalo possível de comprimento e o tipo de bloqueio de tela. O app também pode sugerir a atualização do bloqueio de tela até um certo nível, mas os usuários podem ignorar a sugestão. O bloqueio de tela não é armazenado em texto simples, então o app não tem acesso à senha exata."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"mostrar notificações"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Permite que o app mostre notificações"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"ligar a tela"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Permite que o app ligue a tela."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"Usar hardware de biometria"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Permite que o app use hardware de biometria para autenticação"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"gerenciar hardware de impressão digital"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Não é possível acessar a câmera do smartphone pelo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Não é possível acessar a câmera do tablet pelo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Padrão do sistema"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index d804c23..3b7c162 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Permite que a app aprenda o nível de complexidade do bloqueio de ecrã (elevado, médio, baixo ou nenhum), que indica o intervalo de comprimento e o tipo de bloqueio de ecrã possíveis. A app também pode sugerir aos utilizadores que atualizem o bloqueio de ecrã para um determinado nível, mas estes podem ignorar livremente a sugestão e continuar a navegação. Tenha em atenção que o bloqueio de ecrã não é armazenado em texto simples, pelo que a app desconhece a palavra-passe exata."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"mostrar notificações"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Permite à app mostrar notificações"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"ativar o ecrã"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Permite que a app ative o ecrã."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"Utilizar hardware biométrico"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Permite que a app utilize hardware biométrico para autenticação."</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"gerir o hardware de impressão digital"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Não é possível aceder à câmara do telemóvel a partir do dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Não é possível aceder à câmara do tablet a partir do dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Predefinição do sistema"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index a02c200..caa8cd1 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Permite que o app saiba o nível de complexidade do bloqueio de tela (alto, médio, baixo ou nenhum), que indica o intervalo possível de comprimento e o tipo de bloqueio de tela. O app também pode sugerir a atualização do bloqueio de tela até um certo nível, mas os usuários podem ignorar a sugestão. O bloqueio de tela não é armazenado em texto simples, então o app não tem acesso à senha exata."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"mostrar notificações"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Permite que o app mostre notificações"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"ligar a tela"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Permite que o app ligue a tela."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"Usar hardware de biometria"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Permite que o app use hardware de biometria para autenticação"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"gerenciar hardware de impressão digital"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Não é possível acessar a câmera do smartphone pelo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Não é possível acessar a câmera do tablet pelo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Padrão do sistema"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 55ba527..1b74fd8 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -554,6 +554,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Permite aplicației să învețe nivelul de complexitate al blocării ecranului (ridicat, mediu, scăzut sau fără), fapt ce indică intervalul posibil de lungime a parolei și tipul de blocare a ecranului. Aplicația le poate sugera utilizatorilor să își actualizeze blocarea ecranului la un anumit nivel, dar utilizatorii pot ignora sugestia și pot naviga în continuare. Rețineți că blocarea ecranului nu este stocată ca text simplu, astfel încât aplicația să nu cunoască parola exactă."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"să afișeze notificări"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Permite aplicației să afișeze notificări"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"să activeze ecranul"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Permite aplicației să activeze ecranul."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"utilizați hardware biometric"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Permite aplicației să folosească hardware biometric pentru autentificare"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"gestionează hardware-ul pentru amprentă"</string>
@@ -2285,4 +2287,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nu se poate accesa camera foto a telefonului de pe <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nu se poate accesa camera foto a tabletei de pe <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Prestabilit de sistem"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 1ef3c0c..16a8e16 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -555,6 +555,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Приложение получит доступ к сведениям об уровне сложности блокировки экрана (высокий, средний, низкий или отсутствует), в том числе о типе блокировки и длине пароля. Кроме того, оно сможет предлагать пользователям повысить уровень сложности блокировки. Эти рекомендации необязательны. Обратите внимание, что пароль не хранится в виде открытого текста и недоступен приложению."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"показ уведомлений"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Приложение сможет показывать уведомления."</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"Включение экрана"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Приложение сможет включать экран."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"Использование биометрического оборудования"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Приложение сможет использовать биометрическое оборудование для аутентификации"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"управление сканером отпечатков пальцев"</string>
@@ -2077,10 +2079,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Подробнее"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"В Android 12 доступны улучшенные уведомления. Эта функция упорядочивает все ваши уведомления и подсказывает ответы и действия.\n\nЕй доступно содержимое всех уведомлений, в том числе имена контактов, сообщения и другие личные данные. Также эта функция может закрывать уведомления и нажимать кнопки в них, например отвечать на звонки и управлять режимом \"Не беспокоить\"."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Уведомление о батарее"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Включен режим энергосбережения"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Экономия заряда продлит время работы от батареи."</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Режим энергосбережения"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Режим энергосбережения отключен"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Телефон заряжен достаточно. Функции больше не ограничены."</string>
@@ -2288,4 +2288,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"У устройства \"<xliff:g id="DEVICE">%1$s</xliff:g>\" нет доступа к камере телефона."</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"У устройства \"<xliff:g id="DEVICE">%1$s</xliff:g>\" нет доступа к камере планшета."</string>
     <string name="system_locale_title" msgid="711882686834677268">"Системные настройки по умолчанию"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 3f0d0e5..4cc1370 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"යෙදුමට තිර අගුලෙහි තිබිය හැකි දිගෙහි පරාසය සහ වර්ගය පිළිබිඹු කරන, තිර අඟුලු සංකීර්ණතා මට්ටම (ඉහළ, මධ්‍යම, අඩු හෝ රහිත) දැන ගැනීමට ඉඩ දෙයි. යෙදුම පරිශීලකයින්ට තිර අඟුල නිශ්චිත මට්ටමකට යාවත්කාලීන කිරීමට යෝජනා කළ හැකි නමුත් ඔවුන්ට නිදහසේ නොසලකා හැර ඉවතට සංචලන කළ හැක. තිර අඟුල සරල පෙළින් ගබඩා කර නැති බැවින් යෙදුම නිවැරදි මුරපදය නොදන්නා බව සලකන්න."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"දැනුම්දීම් පෙන්වන්න"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"දැනුම්දීම් පෙන්වීමට යෙදුමට ඉඩ දෙයි"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"තිරය ක්‍රියාත්මක කරන්න"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"තිරය ක්‍රියාත්මක කිරීමට යෙදුමට ඉඩ දෙයි."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"ජීවමිතික දෘඪාංග භාවිත කරන්න"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"සත්‍යාපනය සඳහා ජීවමිතික දෘඪාංග භාවිත කිරීමට යෙදුමට ඉඩ දෙයි"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"ඇඟිලි සලකුණු දෘඩාංග කළමනාකරණය කිරීම."</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ඔබගේ <xliff:g id="DEVICE">%1$s</xliff:g> වෙතින් දුරකථනයේ කැමරාවට ප්‍රවේශ විය නොහැකිය"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ඔබගේ <xliff:g id="DEVICE">%1$s</xliff:g> වෙතින් ටැබ්ලටයේ කැමරාවට ප්‍රවේශ විය නොහැකිය"</string>
     <string name="system_locale_title" msgid="711882686834677268">"පද්ධති පෙරනිමිය"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index fa4f98a..92e0d82 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -555,6 +555,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Umožňuje aplikácii zapamätať si úroveň zložitosti zámky obrazovky (vysoká, stredná, nízka alebo žiadna), ktorá udáva pravdepodobný rozsah dĺžky a typu zámky obrazovky. Aplikácia tiež navrhuje používateľom aktualizáciu zámky obrazovky na určitú úroveň, používatelia sa však môžu na základe vlastného uváženia rozhodnúť tento návrh ignorovať a prejsť inam. Upozorňujeme, že zámka obrazovky nie je uložená vo forme obyčajného textu, takže aplikácia nepozná presné heslo."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"zobrazovať upozornenia"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Povolí aplikácii zobrazovať upozornenia"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"zapnúť obrazovku"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Umožňuje aplikácii zapnúť obrazovku."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"používať biometrický hardvér"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Umožňuje aplikácii používať na overenie totožnosti biometrický hardvér"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"spravovať hardvér na snímanie odtlačkov prstov"</string>
@@ -2062,7 +2064,7 @@
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Zavrieť"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Systém"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Nastavenia"</string>
-    <string name="notification_appops_camera_active" msgid="8177643089272352083">"Fotoaparát"</string>
+    <string name="notification_appops_camera_active" msgid="8177643089272352083">"Kamera"</string>
     <string name="notification_appops_microphone_active" msgid="581333393214739332">"Mikrofón"</string>
     <string name="notification_appops_overlay_active" msgid="5571732753262836481">"sa zobrazuje cez ďalšie aplikácie na obrazovke"</string>
     <string name="notification_feedback_indicator" msgid="663476517711323016">"Poskytnúť spätnú väzbu"</string>
@@ -2286,4 +2288,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> nemáte prístup ku kamere telefónu"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> nemáte prístup ku kamere tabletu"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Predvolené systémom"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 7cbd93e..aec8232 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -555,6 +555,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Aplikaciji dovoljuje, da pridobi raven zapletenosti zaklepanja zaslona (visoka, srednja, nizka ali brez), ki označuje možen obseg dolžine in vrsto zaklepanja zaslona. Aplikacija lahko tudi predlaga uporabnikom, da posodobijo zaklepanje zaslona na določeno raven, vendar lahko uporabniki to opozorilo prezrejo in ga zaprejo tako, da se pomaknejo stran. Upoštevajte, da zaklepanje zaslona ni shranjeno v golem besedilu, tako da aplikacija ne pozna točnega gesla."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"prikaz obvestil"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Aplikaciji dovoli prikaz obvestil."</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"vklop zaslona"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Aplikaciji dovoli vklop zaslona."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"uporaba strojne opreme za biometrične podatke"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Aplikaciji omogoča uporabo strojne opreme za biometrične podatke za preverjanje pristnosti"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"upravljanje strojne opreme za prstne odtise"</string>
@@ -2077,10 +2079,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Več o tem"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Pametna obvestila so v Androidu 12 zamenjala prilagodljiva obvestila Android. Ta funkcija prikazuje predlagana dejanja in odgovore ter organizira vaša obvestila.\n\nPametna obvestila lahko preberejo vso vsebino obvestil, vključno z osebnimi podatki, kot so imena in sporočila stikov. Ta funkcija lahko tudi opusti obvestila ali se odziva nanje (npr. sprejema telefonske klice in upravlja način Ne moti)."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Rutinsko informativno obvestilo o načinu delovanja"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Varčevanje z energijo baterije je vklopljeno"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Manjša poraba energije baterije za podaljšanje časa delovanja baterije"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Varčevanje z energijo baterije"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Varčevanje z energijo baterije je izklopljeno"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Baterija v telefonu je dovolj napolnjena. Funkcije niso več omejene."</string>
@@ -2288,4 +2288,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ni mogoče dostopati do fotoaparata telefona prek naprave <xliff:g id="DEVICE">%1$s</xliff:g>."</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ni mogoče dostopati do fotoaparata tabličnega računalnika prek naprave <xliff:g id="DEVICE">%1$s</xliff:g>."</string>
     <string name="system_locale_title" msgid="711882686834677268">"Sistemsko privzeto"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 37092da..6554eb8 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Lejo që aplikacioni të mësojë nivelin e kompleksitetit të kyçjes së ekranit (i lartë, i mesëm, i ulët ose asnjë), që tregon gamën e mundshme të gjatësisë dhe llojin e kyçjes së ekranit. Aplikacioni mund t\'u sugjerojë gjithashtu përdoruesve që të përditësojnë kyçjen e ekranit në një nivel të caktuar, por përdoruesit mund ta shpërfillin lirshëm dhe të navigojnë më tej. Ki parasysh se kyçja e ekranit nuk ruhet në tekst të thjeshtë, prandaj aplikacioni nuk e di fjalëkalimin e saktë."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"shfaq njoftimet"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Lejon që aplikacioni të shfaqë njoftime"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"aktivizo ekranin"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Lejon që aplikacioni të aktivizojë ekranin."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"përdor harduerin biometrik"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"E lejon aplikacionin që të përdorë harduerin biometrik për vërtetimin"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"të menaxhojë harduerin e gjurmës së gishtit"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nuk mund të qasesh në kamerën e telefonit tënd nga <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nuk mund të qasesh në kamerën e tabletit tënd nga <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Parazgjedhja e sistemit"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index a9cd089..cb1f34d 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -554,6 +554,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Дозвољава апликацији да сазна ниво сложености закључавања екрана (висока, средња, ниска или ниједна), што указује на могући опсег трајања и тип закључавања екрана. Апликација може и да предлаже корисницима да ажурирају закључавање екрана на одређени ниво, али корисници слободно могу да занемаре то и да иду на друге странице. Имајте на уму да се подаци за закључавање екрана не чувају као обичан текст, па апликација не зна тачну лозинку."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"приказивање обавештења"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Дозвољава апликацији да приказује обавештења"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"укључивање екрана"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Дозвољава апликацији да укључи екран."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"користи биометријски хардвер"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Дозвољава апликацији да користи биометријски хардвер за потврду идентитета"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"управљај хардвером за отиске прстију"</string>
@@ -2285,4 +2287,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Не може да се приступи камери телефона са <xliff:g id="DEVICE">%1$s</xliff:g> уређаја"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Не може да се приступи камери таблета са <xliff:g id="DEVICE">%1$s</xliff:g> уређаја"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Подразумевани системски"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index c8d982d..a8d0cce 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Tillåter att appen får reda på komplexitetsnivån för skärmlåset (hög, mellan, låg eller ingen). Detta ger en indikation på skärmlåsets möjliga längd och typ. Appen kan även föreslå att skärmlåset uppdateras till en viss nivå, men användare kan ignorera förslaget och fortsätta navigera. Observera att skärmlåset inte lagras i vanlig text så appen får inte reda på det exakta lösenordet."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"visa aviseringar"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Tillåter att appen visar aviseringar"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"Slå på skärmen"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Tillåter att appen slår på skärmen."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"använd biometrisk maskinvara"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Tillåter att appen använder biometrisk maskinvara vid autentisering"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"hantera maskinvara för fingeravtryck"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Läs mer"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Förbättrade aviseringar har ersatt Anpassade aviseringar för Android i Android 12. Den här funktionen visar förslag på åtgärder och svar och organiserar dina aviseringar.\n\nFörbättrade aviseringar har åtkomst till allt innehåll i aviseringar, inklusive personliga uppgifter som namn på kontakter och meddelanden. Funktionen kan även ignorera aviseringar eller utföra åtgärder utifrån dem, till exempel svara på telefonsamtal och styra Stör ej."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Avisering om rutinläge"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Batterisparläget har aktiverats"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Minskar batteriförbrukning för att förlänga batteritiden"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Batterisparläge"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Batterisparläget har inaktiverats"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Telefonen har laddats tillräckligt. Funktioner begränsas inte längre."</string>
@@ -2269,7 +2269,7 @@
     <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Återaktivera enhetens mikrofon"</string>
     <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Återaktivera enhetens kamera"</string>
     <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"För &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; och alla appar och tjänster"</string>
-    <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Återaktivera"</string>
+    <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Avblockera"</string>
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensorintegritet"</string>
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Appikon"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Appens varumärkesbild"</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Telefonens kamera kan inte användas från <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Surfplattans kamera kan inte användas från <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Systemets standardinställning"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 2d7ef7c..9f10d91 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Huruhusu programu kupata maelezo kuhusu kiwango cha uchangamano wa kufunga skrini (juu, wastani, chini au hakuna), ambacho huashiria urefu unaowezekana na aina ya kufunga skrini. Programu pia inaweza kumpendekezea mtumiaji asasishe mbinu ya kufunga skrini iwe ya kiwango fulani lakini mtumiaji anaweza kuamua kupuuza na kuendelea. Kumbuka kuwa maelezo ya kufunga skrini hayahifadhiwi kama maandishi, hivyo programu haitambui nenosiri mahususi."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"kuonyesha arifa"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Huruhusu programu kuonyesha arifa"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"washa skrini"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Huruhusu programu iwashe skrini."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"tumia maunzi ya kibiolojia"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Huruhusu programu itumie maunzi ya kibiolojia katika uthibitishaji"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"dhibiti maunzi ya alama ya kidole"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Pata maelezo zaidi"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Kipengele cha Arifa Zilizoboreshwa kilichukua nafasi ya Arifa Zinazojirekebisha za Android katika Android 12. Kipengele hiki kinaonyesha majibu na vitendo vinavyopendekezwa na kupanga arifa zako.\n\nKipengele cha Arifa zilizoboreshwa kinaweza kufikia maudhui ya arifa, ikiwa ni pamoja na taarifa binafsi kama vile majina ya anwani na ujumbe. Kipengele hiki kinaweza pia kuondoa au kujibu arifa, kama vile kujibu simu na kudhibiti kipengele cha Usinisumbue."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Arifa ya maelezo ya Hali ya Kawaida"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Kiokoa Betri kimewashwa"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Inapunguza matumizi ya betri ili kuongeza muda wa matumizi ya betri"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Kiokoa betri"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Kiokoa Betri kimezimwa"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Simu ina chaji ya kutosha. Vipengele havizuiliwi tena."</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Haiwezi kufikia kamera ya simu kutoka kwenye <xliff:g id="DEVICE">%1$s</xliff:g> yako"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Haiwezi kufikia kamera ya kompyuta kibao kutoka kwenye <xliff:g id="DEVICE">%1$s</xliff:g> yako"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Chaguomsingi la mfumo"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 5acfd93..fbb4884 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"திரைப் பூட்டு தொடர்பான சிக்கலின் தன்மையை (அதிகம், நடுத்தரம், குறைவு அல்லது ஏதுமில்லை) அறிந்துகொள்ள ஆப்ஸை அனுமதிக்கிறது. இதன் மூலம் திரைப் பூட்டின் அளவு வரம்பையும் வகையையும் தெரிந்துகொள்ளலாம். மேலும் திரைப் பூட்டைக் குறிப்பிட்ட நிலைக்கு மாற்றிக் கொள்ளலாம் என்பதையும் பயனர்களுக்கு ஆப்ஸ் பரிந்துரைக்க முடியும். ஆனால் தங்கள் விருப்பப்படி அவற்றைப் பயனர்கள் நிராகரிக்கவோ ஏற்கவோ இயலும். கவனத்திற்கு: திரைப் பூட்டு எளிய உரையிலானதாக சேமிக்கப்படுவதில்லை என்பதால் சரியான கடவுச்சொல்லை ஆப்ஸால் அறிய இயலாது."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"அறிவிப்புகளைக் காட்டுதல்"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"அறிவிப்புகளைக் காட்ட ஆப்ஸை அனுமதிக்கும்"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"திரையைக் காட்டுதல்"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"திரையைக் காட்ட ஆப்ஸை அனுமதிக்கும்."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"பயோமெட்ரிக் வன்பொருளைப் பயன்படுத்து"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"பயோமெட்ரிக் வன்பொருளைப் பயன்படுத்தி அங்கீகரிப்பதற்கு, ஆப்ஸை அனுமதிக்கும்"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"கைரேகை வன்பொருளை நிர்வகி"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"மேலும் அறிக"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 பதிப்பில் \'Android சூழலுக்கேற்ற அறிவிப்புகள்\' அம்சத்திற்குப் பதிலாக \'மேம்பட்ட அறிவிப்புகள்\' மாற்றப்பட்டுள்ளது. இந்த அம்சம், பரிந்துரைக்கப்படும் செயல்களையும் பதில்களையும் காட்டுவதுடன் உங்கள் அறிவிப்புகளையும் ஒழுங்கமைக்கும்.\n\nதொடர்புகளின் பெயர்கள், மெசேஜ்கள் போன்ற தனிப்பட்ட தகவல்கள் உட்பட அனைத்து அறிவிப்பு உள்ளடக்கத்தையும் \'மேம்பட்ட அறிவிப்புகள்\' அணுக முடியும். மேலும் இந்த அம்சத்தால் அறிவிப்புகளை நிராகரிக்கவும் அவற்றுக்குப் பதிலளிக்கவும் முடியும் (அழைப்புகளுக்குப் பதிலளிப்பது, \'தொந்தரவு செய்ய வேண்டாம்\' அம்சத்தைக் கட்டுப்படுத்துவது போன்றவை)."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"வழக்கமான பேட்டரி சேமிப்பானுக்கான விவர அறிவிப்பு"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"பேட்டரி சேமிப்பு இயக்கப்பட்டுள்ளது"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"பேட்டரி ஆயுளை நீட்டிக்க, பேட்டரி உபயோகத்தைக் குறைக்கிறது"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"பேட்டரி சேமிப்பு"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"பேட்டரி சேமிப்பான் ஆஃப் செய்யப்பட்டுள்ளது"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"மொபைலில் போதுமான சார்ஜ் உள்ளது. அம்சங்கள் இனி தடையின்றி இயங்கும்."</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"உங்கள் <xliff:g id="DEVICE">%1$s</xliff:g> சாதனத்திலிருந்து மொபைலின் கேமராவை அணுக முடியாது"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"உங்கள் <xliff:g id="DEVICE">%1$s</xliff:g> சாதனத்திலிருந்து டேப்லெட்டின் கேமராவை அணுக முடியாது"</string>
     <string name="system_locale_title" msgid="711882686834677268">"சிஸ்டத்தின் இயல்பு"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 6882e3d..390cdcf 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -466,7 +466,7 @@
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS కాల్ సేవ యాక్సెస్ అనుమతి"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"మీ ప్రమేయం లేకుండా కాల్స్‌ చేయడం కోసం IMS సేవను ఉపయోగించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"ఫోన్ స్టేటస్‌ మరియు గుర్తింపుని చదవడం"</string>
-    <string name="permdesc_readPhoneState" msgid="7229063553502788058">"పరికరం యొక్క ఫోన్ ఫీచర్‌లను యాక్సెస్ చేయడానికి యాప్‌ను అనుమతిస్తుంది. ఈ అనుమతి ఫోన్ నంబర్ మరియు పరికరం IDలను, కాల్ సక్రియంగా ఉందా లేదా అనే విషయాన్ని మరియు కాల్ ద్వారా కనెక్ట్ చేయబడిన రిమోట్ నంబర్‌ను కనుగొనడానికి యాప్‌ను అనుమతిస్తుంది."</string>
+    <string name="permdesc_readPhoneState" msgid="7229063553502788058">"పరికరం యొక్క ఫోన్ ఫీచర్‌లను యాక్సెస్ చేయడానికి యాప్‌ను అనుమతిస్తుంది. ఈ అనుమతి ఫోన్ నంబర్ మరియు పరికరం IDలను, కాల్ యాక్టివ్‌గా ఉందా లేదా అనే విషయాన్ని మరియు కాల్ ద్వారా కనెక్ట్ చేయబడిన రిమోట్ నంబర్‌ను కనుగొనడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_readBasicPhoneState" msgid="3214853233263871347">"ప్రాథమిక టెలిఫోన్ స్టేటస్, గుర్తింపును చదవండి"</string>
     <string name="permdesc_readBasicPhoneState" msgid="828185691675460520">"పరికరం తాలూకు ప్రాథమిక టెలిఫోన్ ఫీచర్‌లను యాక్సెస్ చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_manageOwnCalls" msgid="9033349060307561370">"కాల్స్‌ను సిస్టమ్ ద్వారా వెళ్లేలా చేయి"</string>
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"ఇది మీ స్క్రీన్ లాక్ పాస్‌వర్డ్‌ సంక్లిష్టత స్థాయి (తీవ్రంగా ఉండాలా, ఓ మోస్తరుగా ఉండాలా, తక్కువ తీవ్రంగా ఉండాలా లేదా అస్సలు తీవ్రత ఉండకూడదా) తెలుసుకోవడానికి యాప్‌ను అనుమతిస్తుంది, అంటే పొడుగు ఎంత ఉండాలి, ఏ రకమైన స్క్రీన్ లాక్ పధ్ధతి అనుసరించాలో సూచిస్తుంది. అలాగే, స్క్రీన్ లాక్‌ పాస్‌వర్డ్‌ సంక్లిష్టతను ఏ స్థాయికి సెట్ చేసుకుంటే బాగుంటుందో కూడా వినియోగదారులకు యాప్ సూచించగలదు, కానీ వినియోగదారులు నిరభ్యంతరంగా ఆ సూచనలను పట్టించుకోకుండా వారి ఇష్టం మేరకు చక్కగా సెట్ చేసుకోవచ్చు. ఇంకో ముఖ్య విషయం, స్క్రీన్ లాక్‌ అన్నది సాదా వచన రూపంలో నిల్వ చేయబడదు, కనుక ఖచ్చితమైన పాస్‌వర్డ్‌ ఏమిటనేది యాప్‌కు తెలియదు."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"నోటిఫికేషన్‌లను చూపండి"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"నోటిఫికేషన్‌లను చూపించడానికి యాప్‌ను అనుమతించండి"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"స్క్రీన్‌ను ఆన్ చేయండి"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"స్క్రీన్‌ను ఆన్ చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"బయోమెట్రిక్ హార్డ్‌వేర్‌ని ఉపయోగించు"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"ప్రమాణీకరణ కోసం బయోమెట్రిక్ హార్డ్‌వేర్‌ను ఉపయోగించడానికి యాప్‌ని అనుమతిస్తుంది"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"వేలిముద్ర హార్డ్‌వేర్‌ని నిర్వహించడానికి అనుమతి"</string>
@@ -1136,7 +1138,7 @@
     <string name="copyUrl" msgid="6229645005987260230">"URLని కాపీ చేయి"</string>
     <string name="selectTextMode" msgid="3225108910999318778">"వచనాన్ని ఎంచుకోండి"</string>
     <string name="undo" msgid="3175318090002654673">"చర్య రద్దు చేయి"</string>
-    <string name="redo" msgid="7231448494008532233">"చర్యను పునరావృతం చేయి"</string>
+    <string name="redo" msgid="7231448494008532233">"చర్యను రిపీట్‌ చేయి"</string>
     <string name="autofill" msgid="511224882647795296">"ఆటోఫిల్"</string>
     <string name="textSelectionCABTitle" msgid="5151441579532476940">"వచన ఎంపిక"</string>
     <string name="addToDictionary" msgid="8041821113480950096">"నిఘంటువుకు జోడించు"</string>
@@ -1329,7 +1331,7 @@
     <string name="sim_added_title" msgid="7930779986759414595">"సిమ్ కార్డు జోడించబడింది"</string>
     <string name="sim_added_message" msgid="6602906609509958680">"మొబైల్ నెట్‌వర్క్‌ను యాక్సెస్ చేయడానికి మీ పరికరాన్ని పునఃప్రారంభించండి."</string>
     <string name="sim_restart_button" msgid="8481803851341190038">"రీస్టార్ట్ చేయండి"</string>
-    <string name="install_carrier_app_notification_title" msgid="5712723402213090102">"మొబైల్ సేవను సక్రియం చేయండి"</string>
+    <string name="install_carrier_app_notification_title" msgid="5712723402213090102">"మొబైల్ సేవను యాక్టివేట్ చేయండి"</string>
     <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"మీ కొత్త SIMని సక్రియం చేయడానికి క్యారియర్ యాప్‌ను డౌన్‌లోడ్ చేయండి"</string>
     <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"మీ కొత్త SIMని సక్రియం చేయడం కోసం <xliff:g id="APP_NAME">%1$s</xliff:g> యాప్‌ని డౌన్‌లోడ్ చేయండి"</string>
     <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"యాప్‌ని డౌన్‌లోడ్ చేయి"</string>
@@ -1378,7 +1380,7 @@
     <string name="share_remote_bugreport_action" msgid="7630880678785123682">"షేర్ చేయి"</string>
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"తిరస్కరిస్తున్నాను"</string>
     <string name="select_input_method" msgid="3971267998568587025">"ఇన్‌పుట్ పద్ధతిని ఎంచుకోండి"</string>
-    <string name="show_ime" msgid="6406112007347443383">"దీన్ని భౌతిక కీబోర్డ్ సక్రియంగా ఉన్నప్పుడు స్క్రీన్‌పై ఉంచుతుంది"</string>
+    <string name="show_ime" msgid="6406112007347443383">"దీన్ని భౌతిక కీబోర్డ్ యాక్టివ్‌గా ఉన్నప్పుడు స్క్రీన్‌పై ఉంచుతుంది"</string>
     <string name="hardware" msgid="1800597768237606953">"వర్చువల్ కీబోర్డ్‌ను చూపు"</string>
     <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"భౌతిక కీబోర్డుని కాన్ఫిగర్ చేయండి"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"భాష మరియు లేఅవుట్‌ను ఎంచుకోవడానికి నొక్కండి"</string>
@@ -1642,7 +1644,7 @@
     <string name="kg_password_wrong_pin_code" msgid="9013856346870572451">"చెల్లని పిన్‌ కోడ్."</string>
     <string name="kg_invalid_sim_pin_hint" msgid="4821601451222564077">"4 నుండి 8 సంఖ్యలు ఉండే పిన్‌ను టైప్ చేయండి."</string>
     <string name="kg_invalid_sim_puk_hint" msgid="2539364558870734339">"PUK కోడ్ 8 సంఖ్యలు ఉండాలి."</string>
-    <string name="kg_invalid_puk" msgid="4809502818518963344">"సరైన PUK కోడ్‌ను మళ్లీ నమోదు చేయండి. పునరావృత ప్రయత్నాల వలన సిమ్ శాశ్వతంగా నిలిపివేయబడుతుంది."</string>
+    <string name="kg_invalid_puk" msgid="4809502818518963344">"సరైన PUK కోడ్‌ను మళ్లీ నమోదు చేయండి. రిపీట్ ప్రయత్నాల వలన సిమ్ శాశ్వతంగా నిలిపివేయబడుతుంది."</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"పిన్‌ కోడ్‌లు సరిపోలలేదు"</string>
     <string name="kg_login_too_many_attempts" msgid="699292728290654121">"చాలా ఎక్కువ ఆకృతి ప్రయత్నాలు చేశారు"</string>
     <string name="kg_login_instructions" msgid="3619844310339066827">"అన్‌లాక్ చేయడానికి, మీ Google ఖాతాతో సైన్ ఇన్ చేయండి."</string>
@@ -1684,7 +1686,7 @@
     <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"స్క్రీన్‌పై ఉండే కంటెంట్‌ మొత్తాన్ని చదవగలుగుతుంది మరియు ఇతర యాప్‌లలో కూడా ఈ కంటెంట్‌ను ప్రదర్శిస్తుంది."</string>
     <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"చర్యలను చూసి, అమలు చేయగలగడం"</string>
     <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"మీరు ఒక యాప్‌‌తో చేసే ఇంటరాక్షన్‌లను లేదా హార్డ్‌వేర్ సెన్సార్‌ను ట్రాక్ చేస్తూ మీ త‌ర‌ఫున యాప్‌లతో ఇంటరాక్ట్ చేయగలదు."</string>
-    <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"అనుమతించు"</string>
+    <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"అనుమతించండి"</string>
     <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"నిరాకరించు"</string>
     <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"ఫీచర్‌ని ఉపయోగించడం ప్రారంభించడానికి, దాన్ని ట్యాప్ చేయండి:"</string>
     <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"యాక్సెసిబిలిటీ బటన్‌తో ఉపయోగించడానికి ఫీచర్లను ఎంచుకోండి"</string>
@@ -1972,7 +1974,7 @@
     <string name="tooltip_popup_title" msgid="7863719020269945722">"సాధనం చిట్కా"</string>
     <string name="app_category_game" msgid="4534216074910244790">"గేమ్‌లు"</string>
     <string name="app_category_audio" msgid="8296029904794676222">"సంగీతం &amp; ఆడియో"</string>
-    <string name="app_category_video" msgid="2590183854839565814">"చలనచిత్రాలు &amp; వీడియో"</string>
+    <string name="app_category_video" msgid="2590183854839565814">"సినిమాలు &amp; వీడియో"</string>
     <string name="app_category_image" msgid="7307840291864213007">"ఫోటోలు, ఇమేజ్‌లు"</string>
     <string name="app_category_social" msgid="2278269325488344054">"సామాజికం &amp; కమ్యూనికేషన్"</string>
     <string name="app_category_news" msgid="1172762719574964544">"వార్తలు &amp; వార్తాపత్రికలు"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"మీ <xliff:g id="DEVICE">%1$s</xliff:g> నుండి ఫోన్ కెమెరాను యాక్సెస్ చేయడం సాధ్యపడదు"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"మీ <xliff:g id="DEVICE">%1$s</xliff:g> నుండి టాబ్లెట్ కెమెరాను యాక్సెస్ చేయడం సాధ్యపడదు"</string>
     <string name="system_locale_title" msgid="711882686834677268">"సిస్టమ్ ఆటోమేటిక్ సెట్టింగ్"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 34d2dbf..e43f84d 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"อนุญาตให้แอปเรียนรู้ระดับความซับซ้อนของการล็อกหน้าจอ (สูง ปานกลาง ต่ำ หรือไม่มี) ซึ่งแสดงให้เห็นช่วงความยาวและประเภทของการล็อกหน้าจอที่เป็นไปได้ นอกจากนี้แอปยังแนะนำให้ผู้ใช้อัปเดตการล็อกหน้าจอเป็นระดับหนึ่งๆ ได้ด้วย แต่ผู้ใช้จะปฏิเสธและไปยังส่วนต่างๆ ต่อได้ โปรดทราบว่าระบบไม่ได้จัดเก็บการล็อกหน้าจอไว้เป็นข้อความธรรมดา เพื่อให้แอปไม่รู้รหัสผ่าน"</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"แสดงการแจ้งเตือน"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"อนุญาตให้แอปแสดงการแจ้งเตือน"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"เปิดหน้าจอ"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"อนุญาตให้แอปเปิดหน้าจอ"</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"ใช้ฮาร์ดแวร์ชีวมิติ"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"อนุญาตให้แอปใช้ฮาร์ดแวร์ชีวมิติเพื่อตรวจสอบสิทธิ์"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"จัดการฮาร์ดแวร์ลายนิ้วมือ"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ดูข้อมูลเพิ่มเติม"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"การแจ้งเตือนที่เพิ่มประสิทธิภาพมาแทนที่การแจ้งเตือนแบบปรับอัตโนมัติของ Android ใน Android 12 ฟีเจอร์นี้จะแสดงการดำเนินการและการตอบกลับที่แนะนำ ตลอดจนจัดระเบียบการแจ้งเตือน\n\nการแจ้งเตือนที่เพิ่มประสิทธิภาพจะเข้าถึงเนื้อหาของการแจ้งเตือนได้ ซึ่งรวมถึงข้อมูลส่วนบุคคล เช่น ชื่อผู้ติดต่อและข้อความ ฟีเจอร์นี้ยังปิดหรือตอบสนองต่อการแจ้งเตือนได้ด้วย เช่น การรับสายโทรศัพท์และการควบคุมโหมดห้ามรบกวน"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"การแจ้งเตือนข้อมูลโหมดกิจวัตร"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"เปิดโหมดประหยัดแบตเตอรี่แล้ว"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"ลดการใช้งานแบตเตอรี่เพื่อยืดอายุการใช้งานแบตเตอรี่"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"โหมดประหยัดแบตเตอรี่"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"ปิดโหมดประหยัดแบตเตอรี่แล้ว"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"โทรศัพท์มีแบตเตอรี่เพียงพอ ไม่มีการจำกัดฟีเจอร์แล้ว"</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"เข้าถึงกล้องของโทรศัพท์จาก <xliff:g id="DEVICE">%1$s</xliff:g> ไม่ได้"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"เข้าถึงกล้องของแท็บเล็ตจาก <xliff:g id="DEVICE">%1$s</xliff:g> ไม่ได้"</string>
     <string name="system_locale_title" msgid="711882686834677268">"ค่าเริ่มต้นของระบบ"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 21c18be..bbafd02 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Pinapayagan ang app na malaman ang antas ng pagiging kumplikado ng lock ng screen (mataas, katamtaman, mababa, o wala), na nagsasaad ng posibleng hanay ng haba at uri ng lock ng screen. Puwede ring imungkahi ng app sa mga user na i-update nila ang lock ng screen sa isang partikular na antas ngunit malaya ang mga user na balewalain ito at mag-navigate palayo. Tandaang hindi naka-store bilang plaintext ang lock ng screen kaya hindi alam ng app ang eksaktong password."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"magpakita ng mga notification"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Pinapayagan ang app na magpakita ng mga notification"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"i-on ang screen"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Nagpapahintulot sa app na i-on ang screen."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"gumamit ng biometric hardware"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Pinapayagan ang app na gumamit ng biometric hardware para sa pag-authenticate"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"pamahalaan ang hardware ng fingerprint"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Matuto pa"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Pinalitan ng Mga pinahusay na notification ang Mga Adaptive na Notification ng Android sa Android 12. Nagpapakita ng mga iminumungkahing pagkilos at sagot ang feature na ito, at isinasaayos nito ang iyong mga notification.\n\nMaa-access ng Mga pinahusay na notification ang content ng notification, kabilang ang personal na impormasyon gaya ng mga pangalan ng contact at mensahe. Magagawa rin ng feature na ito na i-dismiss o tugunan ang mga notification, gaya ng pagsagot sa mga tawag sa telepono, at kontrolin ang Huwag Istorbohin."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notification ng impormasyon ng Routine Mode"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Na-on ang Pantipid ng Baterya"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Binabawasan ang paggamit sa baterya para mapatagal ang baterya"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Pantipid ng Baterya"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Na-off ang Pantipid ng Baterya"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"May sapat na charge ang telepono. Hindi na pinaghihigpitan ang mga feature."</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Hindi ma-access ang camera ng telepono mula sa iyong <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Hindi ma-access ang camera ng tablet mula sa iyong <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Default ng system"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 29e6811..3499478 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Uygulamanın, ekran kilidi karmaşıklık seviyesini (yüksek, orta, düşük veya yok) öğrenmesini sağlar. Ekran kilidi karmaşıklık seviyesi, ekran kilidinin olası uzunluk aralığını ve türünü gösterir. Uygulama, kullanıcılara ekran kilidini belirli bir seviyeye güncellemelerini de önerebilir, ancak kullanıcılar bunu istedikleri gibi yoksayabilir ve geçebilirler. Ekran kilidi şifrelenmemiş metin olarak saklanmadığı için uygulamanın şifreyi tam olarak bilmediğini unutmayın."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"bildirimleri göster"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Uygulamanın bildirimleri göstermesine izin verir"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"ekranı aç"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Uygulamaya ekranı açma izni verir."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"biyometrik donanım kullan"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Uygulamanın kimlik doğrulama için biyometrik donanım kullanmasına izin verir"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"parmak izi donanımını yönetme"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Daha fazla bilgi"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Gelişmiş bildirimler, Android 12\'de Android Uyarlanabilir Bildirimler\'in yerini aldı. Bu özellik, önerilen işlem ve yanıtları gösterir ve bildirimlerinizi organize eder.\n\nGelişmiş bildirimler, kişiler ve mesajlar gibi kişisel bilgiler dahil olmak üzere tüm bildirim içeriklerine erişebilir. Bu özellik ayrıca bildirimleri kapatabilir veya telefon aramalarını yanıtlamak ve Rahatsız Etmeyin modunu kontrol etmek gibi işlemlerle bildirimlere yanıt verebilir."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Rutin Modu bilgi bildirimi"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Pil Tasarrufu açıldı"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Pil ömrünü uzatmak için pil kullanımını azaltma"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Pil Tasarrufu"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Pil Tasarrufu kapatıldı"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Telefon yeterince şarj oldu. Özellikler artık kısıtlanmış değil."</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan telefonun kamerasına erişilemiyor"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan tabletin kamerasına erişilemiyor"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Sistem varsayılanı"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 72b90b2..2b7d9cc 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -555,6 +555,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Дозволяє додатку визначати рівень складності способу блокування екрана (високий, середній, низький або нульовий). Враховуються кількість символів і тип блокування. Додаток також може пропонувати вибрати складніший тип блокування екрана, але це не обов’язково робити. Примітка: оскільки пароль зашифровано, додаток його не знає."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"показувати сповіщення"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Дозволяє додатку показувати сповіщення"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"вмикати екран"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Дозволяє додатку вмикати екран."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"використовувати біометричне апаратне забезпечення"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Додаток може використовувати біометричне апаратне забезпечення для автентифікації"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"керувати сканером відбитків пальців"</string>
@@ -2077,10 +2079,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Докладніше"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"В Android 12 адаптивні сповіщення замінено на покращені. Ця функція допомагає впорядковувати сповіщення й показує в них пропоновані дії та відповіді.\n\nПокращені сповіщення надають доступ до вмісту сповіщень, зокрема до такої особистої інформації, як повідомлення й імена контактів. Ця функція може автоматично закривати сповіщення чи реагувати на них, наприклад відповідати на телефонні дзвінки або керувати режимом \"Не турбувати\"."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Сповіщення про послідовнсть дій"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Режим енергозбереження ввімкнено"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Заряд використовується економно, щоб подовжити час роботи акумулятора"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Режим енергозбереження"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Режим енергозбереження вимкнено."</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Телефон має достатньо заряду акумулятора. Функції вже не обмежено."</string>
@@ -2288,4 +2288,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Не вдається отримати доступ до камери телефона з пристрою <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Не вдається отримати доступ до камери планшета з пристрою <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Налаштування системи за умовчанням"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 221c5b0..90f8d60 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"اپپ کو اسکرین لاک کی پیچیدگی (بہت زیادہ، درمیانی، کم یا کوئی بھی نہیں) کو جاننے کی اجازت دیتی ہے، جو طوالت کی ممکنہ حد اور اسکرین لاک کی قسم کو بتاتی ہے۔ اپپ صارفین کو یہ مشوره بھی دے سکتی ہے کہ وہ اسکرین لاک کو مخصوص لیول تک اپ ڈیٹ کریں لیکن صارفین آزادانہ طور پر نظر انداز اور نیویگیٹ کر سکتے ہیں۔ نوٹ کریں کہ اسکرین لاک پلین ٹیکسٹ میں اسٹور نہیں کیا جاتا ہے اس لیے اپپ کو صحیح پاس ورڈ نہیں معلوم ہوتا ہے۔"</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"اطلاعات دکھائیں"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"ایپ کو اطلاعات دکھانے کی اجازت دیتا ہے"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"سکرین آن کریں"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"ایپ کو اسکرین آن کرنے کی اجازت دیتا ہے۔"</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"بایومیٹرک ہارڈ ویئر استعمال کریں"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"ایپ کو توثیق کے لیے بایومیٹرک ہارڈ ویئر استعمال کرنے کی اجازت دیتا ہے"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"فنگر پرنٹ ہارڈ ویئر کا نظم کریں"</string>
@@ -2075,10 +2077,8 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"مزید جانیں"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"‏Android 12 میں بہتر کردہ اطلاعات کو Android اڈاپٹیو کی اطلاعات سے تبدیل کیا گیا۔ یہ خصوصیت تجویز کردہ کارروائیاں اور جوابات دکھاتی ہے اور آپ کی اطلاعات کا نظم کرتی ہے۔\n\nبہتر کردہ اطلاعات رابطوں کے نام اور پیغامات جیسی ذاتی معلومات سمیت اطلاعات کے مواد تک رسائی حاصل کر سکتی ہیں۔ یہ خصوصیت اطلاعات کو برخاست کر سکتی ہے یا ان کا جواب بھی دے سکتی ہے جیسے فون کالز کا جواب دینا اور ڈسٹرب نہ کریں کو کنٹرول کرنا۔"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"روٹین موڈ معلومات کی اطلاع"</string>
-    <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
-    <skip />
-    <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
-    <skip />
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"بیٹری سیور کو آن کیا گیا"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"بیٹری لائف کو بڑھانے کے لیے بیٹری کے استعمال کو کم کیا جا رہا ہے"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"بیٹری سیور"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"بیٹری سیور کو آف کر دیا گیا"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"فون میں کافی چارج ہے۔ خصوصیات پر اب پابندی نہیں ہے۔"</string>
@@ -2286,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"آپ کے <xliff:g id="DEVICE">%1$s</xliff:g> سے فون کے کیمرا تک رسائی حاصل نہیں کی جا سکتی"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"آپ کے <xliff:g id="DEVICE">%1$s</xliff:g> سے ٹیبلیٹ کے کیمرا تک رسائی حاصل نہیں کی جا سکتی"</string>
     <string name="system_locale_title" msgid="711882686834677268">"سسٹم ڈیفالٹ"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 8cba718..fc140bb 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Ilova ekran qulfining qiyinlik darajasi (yuqori, oʻrta, past yoki hech qanday), jumladan, qulf turi va parol uzunligi haqida axborotga ruxsat oladi. Bundan tashqari, foydalanuvchilarga qulflash qiyinligi darajasini oshirish taklif etiladi. Bu tavsiyalar majburiy emas. Parollar ochiq matn sifatida saqlanmaydi va ilova uni ocha olmaydi."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"bildirishnomalarni chiqarish"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Ilovaga bildirishnomalarni chiqarish uchun ruxsat beradi"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"ekranni yoqish"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Ilovaga ekranni yoqish ruxsatini beradi."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"biometrik sensordan foydalanish"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Haqiqiylikni tekshirish uchun biometrik sensordan foydalanish imkonini beradi"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"barmoq izi skanerini boshqarish"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> qurilmasidan telefonning kamerasiga kirish imkonsiz"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> qurilmasidan planshetning kamerasiga kirish imkonsiz"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Tizim standarti"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index ce0b715..b658c9f 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Cho phép ứng dụng nắm được độ phức tạp của khóa màn hình (cao, trung bình, thấp hoặc không có). Mức độ này cho biết độ dài và loại khóa màn hình có thể có. Ngoài ra, ứng dụng có thể gợi ý người dùng cập nhật khóa màn hình lên một mức độ nhất định, nhưng người dùng có thể tùy ý bỏ qua và chuyển sang phần khác. Lưu ý rằng khóa màn hình không được lưu dưới dạng văn bản thuần túy, vì vậy, ứng dụng sẽ không biết mật khẩu chính xác."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"hiển thị thông báo"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Cho phép ứng dụng hiển thị thông báo"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"bật màn hình"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Cho phép ứng dụng bật màn hình."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"sử dụng phần cứng sinh trắc học"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Cho phép ứng dụng dùng phần cứng sinh trắc học để xác thực"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"quản lý phần cứng vân tay"</string>
@@ -2076,7 +2078,7 @@
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Thông báo nâng cao đã thay thế Thông báo thích ứng trên Android trong Android 12. Tính năng này hiển thị những thao tác và câu trả lời đề xuất, đồng thời sắp xếp các thông báo của bạn.\n\nThông báo nâng cao có thể đọc mọi nội dung thông báo, bao gồm cả thông tin cá nhân như tên liên hệ và tin nhắn. Tính năng này cũng có thể đóng hoặc phản hồi các thông báo, chẳng hạn như trả lời cuộc gọi điện thoại, đồng thời có thể kiểm soát chế độ Không làm phiền."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Thông báo cung cấp thông tin về chế độ sạc thông thường"</string>
     <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Đã bật Trình tiết kiệm pin"</string>
-    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Giảm mức sử dụng pin để kéo dài tuổi thọ pin"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Giảm mức sử dụng pin để kéo dài thời lượng pin"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Trình tiết kiệm pin"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Trình tiết kiệm pin đã tắt"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Điện thoại còn đủ pin. Các tính năng không bị hạn chế nữa."</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Không truy cập được vào máy ảnh trên điện thoại từ <xliff:g id="DEVICE">%1$s</xliff:g> của bạn"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Không truy cập được vào máy ảnh trên máy tính bảng từ <xliff:g id="DEVICE">%1$s</xliff:g> của bạn"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Theo chế độ mặc định của hệ thống"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 4257f78..129c583 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"允许应用了解屏幕锁定复杂度(高、中、低或无),即屏幕锁定的可能长度范围和类型。应用还可以建议用户将屏幕锁定更新为特定复杂度,但用户可以随意选择忽略该建议并离开应用。请注意,系统不会以纯文字形式存储屏幕锁定选项的内容,因此应用不会知道确切密码。"</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"显示通知"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"允许该应用显示通知"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"唤醒屏幕"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"允许应用唤醒屏幕。"</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"使用生物特征硬件"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"允许该应用使用生物特征硬件进行身份验证"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"管理指纹硬件"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"无法从<xliff:g id="DEVICE">%1$s</xliff:g>上访问手机的摄像头"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"无法从<xliff:g id="DEVICE">%1$s</xliff:g>上访问平板电脑的摄像头"</string>
     <string name="system_locale_title" msgid="711882686834677268">"系统默认设置"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 6374db5..ef886c9 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"允許應用程式瞭解螢幕鎖定的複雜程度 (高、中、低或無),這項資料說明了螢幕鎖定的可能長度範圍和類型。應用程式亦能建議使用者將螢幕鎖定更新至某個複雜程度,但使用者可以隨意忽略並離開。請注意,螢幕鎖定並非以純文字儲存,因此應用程式不知道確切的密碼。"</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"顯示通知"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"允許應用程式顯示通知"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"開啟螢幕"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"允許應用程式開啟螢幕。"</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"使用生物識別硬件"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"允許應用程式使用生物識別硬件驗證"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"管理指紋硬件"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"無法從 <xliff:g id="DEVICE">%1$s</xliff:g> 存取手機的相機"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"無法從 <xliff:g id="DEVICE">%1$s</xliff:g> 存取平板電腦的相機"</string>
     <string name="system_locale_title" msgid="711882686834677268">"系統預設"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index aaa05f0..9dbcd44 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"允許應用程式記住螢幕鎖定的複雜度 (高、中、低或無),即螢幕鎖定的可能長度範圍和類型。這樣一來,應用程式還能建議使用者將螢幕鎖定更新為特定複雜度,但使用者可選擇忽略建議並離開應用程式。請注意,系統不會以純文字格式儲存螢幕鎖定選項的內容,因此應用程式不會知道確切密碼。"</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"顯示通知"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"允許應用程式顯示通知"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"開啟螢幕"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"允許應用程式開啟螢幕。"</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"使用生物特徵硬體"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"允許應用程式使用生物特徵硬體進行驗證"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"管理指紋硬體"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"無法從 <xliff:g id="DEVICE">%1$s</xliff:g> 存取手機的相機"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"無法從 <xliff:g id="DEVICE">%1$s</xliff:g> 存取平板電腦的相機"</string>
     <string name="system_locale_title" msgid="711882686834677268">"系統預設"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 20b8b58..6a4a448 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -553,6 +553,8 @@
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Ivumela uhlelo lokusebenza ukuthi lifunde ileveli yobunkimbinkimbi bokukhiya isikrini (okuphezulu, okuphakathi nendawo, okuphansi noma lutho), obubonisa ibanga elingaba khona lobude nohlobo lokukhiya isikrini Uhlelo lokusebenza lungaphinda luphakamise kubasebenzisi ukuthi babuyekeze ukukhiya isikrini kuleveli elithile kodwa abasebenzisi bangaziba ngokukhululekile baphinde bazulazule nje. Qaphela ukuthi ukukhiya isikrini akugcinwa kumbhalo osobala ukuze uhlelo lokusebenza lungayazi iphasiwedi enembile."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"bonisa izaziso"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Kuvumela i-app ibonise izaziso"</string>
+    <string name="permlab_turnScreenOn" msgid="219344053664171492">"vula isikrini"</string>
+    <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Ivumela i-app ukuthi ivule isikrini."</string>
     <string name="permlab_useBiometric" msgid="6314741124749633786">"sebenzisa izingxenyekazi zekhompyutha ze-biometric"</string>
     <string name="permdesc_useBiometric" msgid="7502858732677143410">"Ivumela uhlelo lokusebenza ukuthi lusebenzise izingxenyekazi zekhompyutha ze-biometric ukuze kuqinisekiswe"</string>
     <string name="permlab_manageFingerprint" msgid="7432667156322821178">"phatha izingxenyekazi zekhompyutha zezigxivizo zeminwe"</string>
@@ -2284,4 +2286,6 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ayikwazi ukufinyelela ikhamera yefoni kusuka ku-<xliff:g id="DEVICE">%1$s</xliff:g> yakho"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ayikwazi ukufinyelela ikhamera yethebulethi kusuka ku-<xliff:g id="DEVICE">%1$s</xliff:g> yakho"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Okuzenzakalelayo kwesistimu"</string>
+    <!-- no translation found for default_card_name (9198284935962911468) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 3daf033..f0b86e3 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3467,6 +3467,22 @@
     <!-- Specify if the fingerprint hardware support gestures-->
     <bool name="config_fingerprintSupportsGestures">false</bool>
 
+    <!-- The time (in millis) to wait for a power button before sending
+         a successful auth in biometric prompt(for side fingerprint) -->
+    <integer name="config_sidefpsBpPowerPressWindow">300</integer>
+
+    <!-- The time (in millis) to wait for a power button before sending a
+         successful auth in to keyguard(for side fingerprint) -->
+    <integer name="config_sidefpsKeyguardPowerPressWindow">300</integer>
+
+    <!-- The time (in millis) that a power event will ignore future authentications
+         (for side fingerprint) -->
+    <integer name="config_sidefpsPostAuthDowntime">400</integer>
+
+    <!-- The time (in millis) that a finger tap will wait for a power button
+         before dismissing the power dialog during enrollment(for side fingerprint) -->
+    <integer name="config_sidefpsEnrollPowerPressWindow">300</integer>
+
     <!-- This config is used to force VoiceInteractionService to start on certain low ram devices.
          It declares the package name of VoiceInteractionService that should be started. -->
     <string translatable="false" name="config_forceVoiceInteractionServicePackage"></string>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 557706f..1997261 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -684,7 +684,7 @@
 
     <!-- Lighting and shadow properties -->
     <dimen name="light_y">0dp</dimen>
-    <dimen name="light_z">600dp</dimen>
+    <dimen name="light_z">500dp</dimen>
     <dimen name="light_radius">800dp</dimen>
     <item type="dimen" format="float" name="ambient_shadow_alpha">0.039</item>
     <item type="dimen" format="float" name="spot_shadow_alpha">0.19</item>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index aef71e43..d031de4 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1744,6 +1744,8 @@
     <string name="fingerprint_error_security_update_required">Sensor temporarily disabled.</string>
     <!-- Generic error message shown when fingerprint needs calibration [CHAR LIMIT=150] -->
     <string name="fingerprint_error_bad_calibration">Can\u2019t use fingerprint sensor. Visit a repair provider</string>
+    <!-- Generic error message shown when the power button has been pressed. [CHAR LIMIT=150] -->
+    <string name="fingerprint_error_power_pressed">Power button pressed</string>
 
     <!-- Template to be used to name enrolled fingerprints by default. -->
     <string name="fingerprint_name_template">Finger <xliff:g id="fingerId" example="1">%d</xliff:g></string>
@@ -6324,4 +6326,7 @@
 
     <!-- Title for preference of the system default locale. [CHAR LIMIT=50]-->
     <string name="system_locale_title">System default</string>
+
+    <!-- Display content to tell the user the sim card name and number-->
+    <string name="default_card_name">CARD <xliff:g id="cardNumber" example="1">%d</xliff:g></string>
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index e55496d..66dd760 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2616,10 +2616,15 @@
   <java-symbol type="string" name="fingerprint_recalibrate_notification_name" />
   <java-symbol type="string" name="fingerprint_recalibrate_notification_title" />
   <java-symbol type="string" name="fingerprint_recalibrate_notification_content" />
+  <java-symbol type="string" name="fingerprint_error_power_pressed" />
 
   <!-- Fingerprint config -->
   <java-symbol type="integer" name="config_fingerprintMaxTemplatesPerUser"/>
   <java-symbol type="bool" name="config_fingerprintSupportsGestures"/>
+  <java-symbol type="integer" name="config_sidefpsBpPowerPressWindow"/>
+  <java-symbol type="integer" name="config_sidefpsKeyguardPowerPressWindow"/>
+  <java-symbol type="integer" name="config_sidefpsPostAuthDowntime"/>
+  <java-symbol type="integer" name="config_sidefpsEnrollPowerPressWindow"/>
 
   <!-- Face authentication messages -->
   <java-symbol type="string" name="face_recalibrate_notification_name" />
@@ -4814,4 +4819,5 @@
   <java-symbol type="dimen" name="status_bar_height_default" />
 
   <java-symbol type="bool" name="system_server_plays_face_haptics" />
+  <java-symbol type="string" name="default_card_name"/>
 </resources>
diff --git a/core/tests/coretests/src/android/text/TextLineTest.java b/core/tests/coretests/src/android/text/TextLineTest.java
index 412d6ec..e3bcc8d 100644
--- a/core/tests/coretests/src/android/text/TextLineTest.java
+++ b/core/tests/coretests/src/android/text/TextLineTest.java
@@ -26,6 +26,7 @@
 import android.graphics.Typeface;
 import android.platform.test.annotations.Presubmit;
 import android.text.Layout.TabStops;
+import android.text.style.AbsoluteSizeSpan;
 import android.text.style.ReplacementSpan;
 import android.text.style.TabStopSpan;
 
@@ -97,7 +98,7 @@
             InstrumentationRegistry.getInstrumentation().getTargetContext().getAssets(),
             "fonts/StaticLayoutLineBreakingTestFont.ttf");
 
-    private TextLine getTextLine(String str, TextPaint paint, TabStops tabStops) {
+    private TextLine getTextLine(CharSequence str, TextPaint paint, TabStops tabStops) {
         Layout layout =
                 StaticLayout.Builder.obtain(str, 0, str.length(), paint, Integer.MAX_VALUE)
                     .build();
@@ -109,7 +110,7 @@
         return tl;
     }
 
-    private TextLine getTextLine(String str, TextPaint paint) {
+    private TextLine getTextLine(CharSequence str, TextPaint paint) {
         return getTextLine(str, paint, null);
     }
 
@@ -316,14 +317,275 @@
         assertTrue(span.mIsUsed);
     }
 
+    @Test
+    public void testMeasureAllBounds_LTR() {
+        final TextPaint paint = new TextPaint();
+        paint.setTypeface(TYPEFACE);
+        paint.setTextSize(10.0f);  // make 1em = 10px
+
+        TextLine tl = getTextLine("IIIIIV", paint);
+        float[] bounds = new float[12];
+        float[] advances = new float[6];
+        tl.measureAllBounds(bounds, advances);
+        assertArrayEquals(new float[] {0.0f, 10.0f, 10.0f, 20.0f, 20.0f, 30.0f, 30.0f, 40.0f,
+                40.0f, 50.0f, 50.0f, 100.0f}, bounds, 0.0f);
+        assertArrayEquals(new float[] {10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 50.0f}, advances, 0.0f);
+    }
+
+    @Test
+    public void testMeasureAllBounds_LTR_StyledText() {
+        final TextPaint paint = new TextPaint();
+        paint.setTypeface(TYPEFACE);
+        paint.setTextSize(10.0f);  // make 1em = 10px
+        SpannableString text = new SpannableString("IIIIIV");
+        text.setSpan(new AbsoluteSizeSpan(5), 1, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+        TextLine tl = getTextLine(text, paint);
+        float[] bounds = new float[12];
+        float[] advances = new float[6];
+        tl.measureAllBounds(bounds, advances);
+        assertArrayEquals(new float[] {0.0f, 10.0f, 10.0f, 15.0f, 15.0f, 20.0f, 20.0f, 30.0f,
+                30.0f, 40.0f, 40.0f, 90.0f}, bounds, 0.0f);
+        assertArrayEquals(new float[] {10.0f, 5.0f, 5.0f, 10.0f, 10.0f, 50.0f}, advances, 0.0f);
+    }
+
+    @Test
+    public void testMeasureAllBounds_RTL() {
+        final TextPaint paint = new TextPaint();
+        paint.setTypeface(TYPEFACE);
+        paint.setTextSize(10.0f);  // make 1em = 10px
+
+        TextLine tl = getTextLine("\u05D0\u05D0\u05D0\u05D0\u05D0\u05D1", paint);
+        float[] bounds = new float[12];
+        float[] advances = new float[6];
+        tl.measureAllBounds(bounds, advances);
+        assertArrayEquals(new float[] {-10.0f, 0.0f, -20.0f, -10.0f, -30.0f, -20.0f, -40.0f, -30.0f,
+                -50.0f, -40.0f, -100.0f, -50.0f}, bounds, 0.0f);
+        assertArrayEquals(new float[] {10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 50.0f}, advances, 0.0f);
+    }
+
+
+    @Test
+    public void testMeasureAllBounds_RTL_StyledText() {
+        final TextPaint paint = new TextPaint();
+        paint.setTypeface(TYPEFACE);
+        paint.setTextSize(10.0f);  // make 1em = 10px
+        SpannableString text = new SpannableString("\u05D0\u05D0\u05D0\u05D0\u05D0\u05D1");
+        text.setSpan(new AbsoluteSizeSpan(5), 1, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+        TextLine tl = getTextLine(text, paint);
+        float[] bounds = new float[12];
+        float[] advances = new float[6];
+        tl.measureAllBounds(bounds, advances);
+        assertArrayEquals(new float[] {-10.0f, 0.0f, -15.0f, -10.0f, -20.0f, -15.0f,
+                -30.0f, -20.0f, -40.0f, -30.0f, -90.0f, -40.0f}, bounds, 0.0f);
+        assertArrayEquals(new float[] {10.0f, 5.0f, 5.0f, 10.0f, 10.0f, 50.0f}, advances, 0.0f);
+    }
+
+    @Test
+    public void testMeasureAllBounds_BiDi() {
+        final TextPaint paint = new TextPaint();
+        paint.setTypeface(TYPEFACE);
+        paint.setTextSize(10.0f);  // make 1em = 10px
+
+        TextLine tl = getTextLine("II\u05D0\u05D0II", paint);
+        float[] bounds = new float[12];
+        float[] advances = new float[6];
+        tl.measureAllBounds(bounds, advances);
+        assertArrayEquals(new float[] {0.0f, 10.0f, 10.0f, 20.0f, 30.0f, 40.0f, 20.0f, 30.0f,
+                40.0f, 50.0f, 50.0f, 60.0f}, bounds, 0.0f);
+        assertArrayEquals(new float[] {10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f}, advances, 0.0f);
+    }
+
+    @Test
+    public void testMeasureAllBounds_BiDi2() {
+        final TextPaint paint = new TextPaint();
+        paint.setTypeface(TYPEFACE);
+        paint.setTextSize(10.0f);  // make 1em = 10px
+
+        TextLine tl = getTextLine("I" + RLI + "I\u05D0\u05D0" + PDI + "I", paint);
+        float[] bounds = new float[14];
+        float[] advances = new float[7];
+        tl.measureAllBounds(bounds, advances);
+        assertArrayEquals(new float[] {0.0f, 10.0f, 10.0f, 10.0f, 30.0f, 40.0f, 20.0f, 30.0f,
+                10.0f, 20.0f, 40.0f, 40.0f, 40.0f, 50.0f}, bounds, 0.0f);
+        assertArrayEquals(new float[] {10.0f, 0.0f, 10.0f, 10.0f, 10.0f, 0.0f, 10.0f}, advances,
+                0.0f);
+    }
+
+    @Test
+    public void testMeasureAllBounds_BiDi3() {
+        final TextPaint paint = new TextPaint();
+        paint.setTypeface(TYPEFACE);
+        paint.setTextSize(10.0f);  // make 1em = 10px
+
+        TextLine tl = getTextLine("\u05D0" + LRI + "\u05D0II" + PDI + "\u05D0", paint);
+        float[] bounds = new float[14];
+        float[] advances = new float[7];
+        tl.measureAllBounds(bounds, advances);
+        assertArrayEquals(new float[] {-10.0f, 0.0f, -10.0f, -10.0f, -40.0f, -30.0f,
+                -30.0f, -20.0f, -20.0f, -10.0f, -40.0f, -40.0f, -50.0f, -40.0f}, bounds, 0.0f);
+        assertArrayEquals(new float[] {10.0f, 0.0f, 10.0f, 10.0f, 10.0f, 0.0f, 10.0f}, advances,
+                0.0f);
+    }
+
+    @Test
+    public void testMeasureAllBounds_styled_BiDi() {
+        final TextPaint paint = new TextPaint();
+        paint.setTypeface(TYPEFACE);
+        paint.setTextSize(10.0f);  // make 1em = 10px
+
+        SpannableString text = new SpannableString("II\u05D0\u05D0II");
+        text.setSpan(new AbsoluteSizeSpan(5), 1, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+        TextLine tl = getTextLine(text, paint);
+        float[] bounds = new float[12];
+        float[] advances = new float[6];
+        tl.measureAllBounds(bounds, advances);
+        assertArrayEquals(new float[] {0.0f, 10.0f, 10.0f, 15.0f, 25.0f, 30.0f,
+                15.0f, 25.0f, 30.0f, 40.0f, 40.0f, 50.0f}, bounds, 0.0f);
+        assertArrayEquals(new float[] {10.0f, 5.0f, 5.0f, 10.0f, 10.0f, 10.0f}, advances, 0.0f);
+    }
+
+    @Test
+    public void testMeasureAllBounds_Tab_LTR() {
+        final Object[] spans = { new TabStopSpan.Standard(100) };
+        final TabStops stops = new TabStops(100, spans);
+        final TextPaint paint = new TextPaint();
+        paint.setTypeface(TYPEFACE);
+        paint.setTextSize(10.0f);  // make 1em = 10px
+
+        TextLine tl = getTextLine("II\tII", paint, stops);
+        float[] bounds = new float[10];
+        float[] advances = new float[5];
+        tl.measureAllBounds(bounds, advances);
+        assertArrayEquals(new float[] {0.0f, 10.0f, 10.0f, 20.0f, 20.0f, 100.0f, 100.0f, 110.0f,
+                110.0f, 120.0f}, bounds, 0.0f);
+        assertArrayEquals(new float[] {10.0f, 10.0f, 80.0f, 10.0f, 10.0f}, advances, 0.0f);
+    }
+
+    @Test
+    public void testMeasureAllBounds_Tab_RTL() {
+        final Object[] spans = { new TabStopSpan.Standard(100) };
+        final TabStops stops = new TabStops(100, spans);
+        final TextPaint paint = new TextPaint();
+        paint.setTypeface(TYPEFACE);
+        paint.setTextSize(10.0f);  // make 1em = 10px
+
+        TextLine tl = getTextLine("\u05D0\u05D0\t\u05D0\u05D0", paint, stops);
+        float[] bounds = new float[10];
+        float[] advances = new float[5];
+        tl.measureAllBounds(bounds, advances);
+        assertArrayEquals(new float[] {-10.0f, 0.0f, -20.0f, -10.0f, -100.0f, -20.0f,
+                -110.0f, -100.0f, -120.0f, -110.0f}, bounds, 0.0f);
+        assertArrayEquals(new float[] {10.0f, 10.0f, 80.0f, 10.0f, 10.0f}, advances, 0.0f);
+    }
+
+    @Test
+    public void testMeasureAllBounds_Tab_BiDi() {
+        final Object[] spans = { new TabStopSpan.Standard(100) };
+        final TabStops stops = new TabStops(100, spans);
+        final TextPaint paint = new TextPaint();
+        paint.setTypeface(TYPEFACE);
+        paint.setTextSize(10.0f);  // make 1em = 10px
+
+        TextLine tl = getTextLine("I\u05D0\tI\u05D0", paint, stops);
+        float[] bounds = new float[10];
+        float[] advances = new float[5];
+        tl.measureAllBounds(bounds, advances);
+        assertArrayEquals(new float[] {0.0f, 10.0f, 10.0f, 20.0f, 20.0f, 100.0f,
+                100.0f, 110.0f, 110.0f, 120.0f}, bounds, 0.0f);
+        assertArrayEquals(new float[] {10.0f, 10.0f, 80.0f, 10.0f, 10.0f}, advances, 0.0f);
+    }
+
+    @Test
+    public void testMeasureAllBounds_Tab_BiDi2() {
+        final Object[] spans = { new TabStopSpan.Standard(100) };
+        final TabStops stops = new TabStops(100, spans);
+        final TextPaint paint = new TextPaint();
+        paint.setTypeface(TYPEFACE);
+        paint.setTextSize(10.0f);  // make 1em = 10px
+
+        TextLine tl = getTextLine("\u05D0I\t\u05D0I", paint, stops);
+        float[] bounds = new float[10];
+        float[] advances = new float[5];
+        tl.measureAllBounds(bounds, advances);
+        assertArrayEquals(new float[] {-10.0f, 0.0f, -20.0f, -10.0f, -100.0f, -20.0f,
+                -110.0f, -100.0f, -120.0f, -110.0f}, bounds, 0.0f);
+        assertArrayEquals(new float[] {10.0f, 10.0f, 80.0f, 10.0f, 10.0f}, advances, 0.0f);
+    }
+
+    @Test
+    public void testMeasureAllBounds_replacement_LTR() {
+        final TextPaint paint = new TextPaint();
+        paint.setTypeface(TYPEFACE);
+        paint.setTextSize(10.0f);  // make 1em = 10px
+
+        SpannableString text = new SpannableString("IIIII");
+        text.setSpan(new TestReplacementSpan(5), 1, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+        TextLine tl = getTextLine(text, paint);
+        float[] bounds = new float[10];
+        float[] advances = new float[5];
+        tl.measureAllBounds(bounds, advances);
+        assertArrayEquals(new float[] {0.0f, 10.0f, 10.0f, 15.0f, 15.0f, 15.0f,
+                15.0f, 25.0f, 25.0f, 35.0f}, bounds, 0.0f);
+        assertArrayEquals(new float[] {10.0f, 5.0f, 0.0f, 10.0f, 10.0f}, advances, 0.0f);
+    }
+
+    @Test
+    public void testMeasureAllBounds_replacement_RTL() {
+        final TextPaint paint = new TextPaint();
+        paint.setTypeface(TYPEFACE);
+        paint.setTextSize(10.0f);  // make 1em = 10px
+
+        SpannableString text = new SpannableString("\u05D0\u05D0\u05D0\u05D0\u05D0");
+        text.setSpan(new TestReplacementSpan(5), 1, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+        TextLine tl = getTextLine(text, paint);
+        float[] bounds = new float[10];
+        float[] advances = new float[5];
+        tl.measureAllBounds(bounds, advances);
+        assertArrayEquals(new float[] {-10.0f, 0.0f, -15.0f, -10.0f, -15.0f, -15.0f,
+                -25.0f, -15.0f, -35.0f, -25.0f}, bounds, 0.0f);
+        assertArrayEquals(new float[] {10.0f, 5.0f, 0.0f, 10.0f, 10.0f}, advances, 0.0f);
+    }
+
+    @Test
+    public void testMeasureAllBounds_replacement_BiDi() {
+        final TextPaint paint = new TextPaint();
+        paint.setTypeface(TYPEFACE);
+        paint.setTextSize(10.0f);  // make 1em = 10px
+
+        SpannableString text = new SpannableString("II\u05D0\u05D0II");
+        text.setSpan(new TestReplacementSpan(5), 1, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+        TextLine tl = getTextLine(text, paint);
+        float[] bounds = new float[12];
+        float[] advances = new float[6];
+        tl.measureAllBounds(bounds, advances);
+        assertArrayEquals(new float[] {0.0f, 10.0f, 10.0f, 15.0f, 15.0f, 15.0f,
+                15.0f, 25.0f, 25.0f, 35.0f, 35.0f, 45.0f}, bounds, 0.0f);
+        assertArrayEquals(new float[] {10.0f, 5.0f, 0.0f, 10.0f, 10.0f, 10.0f}, advances, 0.0f);
+    }
+
     private static class TestReplacementSpan extends ReplacementSpan {
         boolean mIsUsed;
+        private final int mWidth;
+
+        TestReplacementSpan() {
+            mWidth = 0;
+        }
+
+        TestReplacementSpan(int width) {
+            mWidth = width;
+        }
 
         @Override
         public int getSize(Paint paint, CharSequence text, int start, int end,
                 Paint.FontMetricsInt fm) {
             mIsUsed = true;
-            return 0;
+            return mWidth;
         }
 
         @Override
diff --git a/core/tests/coretests/src/android/util/XmlTest.java b/core/tests/coretests/src/android/util/XmlTest.java
index 4e10ea9..1cd4d13 100644
--- a/core/tests/coretests/src/android/util/XmlTest.java
+++ b/core/tests/coretests/src/android/util/XmlTest.java
@@ -224,7 +224,7 @@
         doVerifyRead(in);
     }
 
-    private static final String TEST_STRING = "com.example";
+    private static final String TEST_STRING = "com☃example😀typical☃package😀name";
     private static final String TEST_STRING_EMPTY = "";
     private static final byte[] TEST_BYTES = new byte[] { 0, 1, 2, 3, 4, 3, 2, 1, 0 };
     private static final byte[] TEST_BYTES_EMPTY = new byte[0];
diff --git a/core/tests/coretests/src/android/view/WindowInfoTest.java b/core/tests/coretests/src/android/view/WindowInfoTest.java
index afc2c00..f9e3f43 100644
--- a/core/tests/coretests/src/android/view/WindowInfoTest.java
+++ b/core/tests/coretests/src/android/view/WindowInfoTest.java
@@ -30,6 +30,7 @@
 import android.os.IBinder;
 import android.os.Parcel;
 import android.platform.test.annotations.Presubmit;
+import android.text.TextUtils;
 import android.view.accessibility.AccessibilityNodeInfo;
 
 import androidx.test.filters.SmallTest;
@@ -82,22 +83,7 @@
     public void testDefaultValues() {
         WindowInfo w = WindowInfo.obtain();
 
-        assertEquals(0, w.type);
-        assertEquals(0, w.layer);
-        assertEquals(AccessibilityNodeInfo.UNDEFINED_NODE_ID, w.accessibilityIdOfAnchor);
-        assertEquals(Display.INVALID_DISPLAY, w.displayId);
-        assertEquals(ActivityTaskManager.INVALID_TASK_ID, w.taskId);
-        assertNull(w.title);
-        assertNull(w.token);
-        assertNull(w.childTokens);
-        assertNull(w.parentToken);
-        assertNull(w.activityToken);
-        assertFalse(w.focused);
-        assertFalse(w.inPictureInPicture);
-        assertFalse(w.hasFlagWatchOutsideTouch);
-        assertTrue(w.regionInScreen.isEmpty());
-        assertEquals(w.mTransformMatrix.length, 9);
-        assertTrue(w.mMagnificationSpec.isNop());
+        assertDefaultValue(w);
     }
 
     @SmallTest
@@ -114,6 +100,37 @@
         }
     }
 
+    @SmallTest
+    @Test
+    public void testRecycle_fallbackToDefaultValues() {
+        WindowInfo w = WindowInfo.obtain();
+        initTestWindowInfo(w);
+        w.recycle();
+
+        assertDefaultValue(w);
+    }
+
+    private static void assertDefaultValue(WindowInfo windowinfo) {
+        assertEquals(0, windowinfo.type);
+        assertEquals(0, windowinfo.layer);
+        assertEquals(AccessibilityNodeInfo.UNDEFINED_NODE_ID, windowinfo.accessibilityIdOfAnchor);
+        assertEquals(Display.INVALID_DISPLAY, windowinfo.displayId);
+        assertEquals(ActivityTaskManager.INVALID_TASK_ID, windowinfo.taskId);
+        assertNull(windowinfo.title);
+        assertNull(windowinfo.token);
+        if (windowinfo.childTokens != null) {
+            assertTrue(windowinfo.childTokens.isEmpty());
+        }
+        assertNull(windowinfo.parentToken);
+        assertNull(windowinfo.activityToken);
+        assertFalse(windowinfo.focused);
+        assertFalse(windowinfo.inPictureInPicture);
+        assertFalse(windowinfo.hasFlagWatchOutsideTouch);
+        assertTrue(windowinfo.regionInScreen.isEmpty());
+        assertEquals(windowinfo.mTransformMatrix.length, 9);
+        assertTrue(windowinfo.mMagnificationSpec.isNop());
+    }
+
     private boolean areWindowsEqual(WindowInfo w1, WindowInfo w2) {
         boolean equality = w1.toString().contentEquals(w2.toString());
         equality &= w1.token == w2.token;
@@ -123,6 +140,7 @@
         equality &= w1.regionInScreen.equals(w2.regionInScreen);
         equality &= w1.mMagnificationSpec.equals(w2.mMagnificationSpec);
         equality &= Arrays.equals(w1.mTransformMatrix, w2.mTransformMatrix);
+        equality &= TextUtils.equals(w1.title, w2.title);
         return equality;
     }
 
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityWindowAttributesTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityWindowAttributesTest.java
new file mode 100644
index 0000000..a6abee5
--- /dev/null
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityWindowAttributesTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 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.view.accessibility;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotSame;
+
+import android.os.Parcel;
+import android.platform.test.annotations.Presubmit;
+import android.view.WindowManager;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Class for testing {@link AccessibilityWindowAttributes}.
+ */
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityWindowAttributesTest {
+    private static final String TEST_WINDOW_TITLE = "test window title";
+
+    @SmallTest
+    @Test
+    public void testParceling() {
+        final AccessibilityWindowAttributes windowAttributes = createInstance(TEST_WINDOW_TITLE);
+        Parcel parcel = Parcel.obtain();
+        windowAttributes.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        final AccessibilityWindowAttributes attributes2 =
+                AccessibilityWindowAttributes.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+
+        assertNotSame(windowAttributes, attributes2);
+        assertEquals(windowAttributes, attributes2);
+    }
+
+    @SmallTest
+    @Test
+    public void testNonequality() {
+        final AccessibilityWindowAttributes windowAttributes = createInstance(null);
+        final AccessibilityWindowAttributes windowAttributes2 = createInstance(TEST_WINDOW_TITLE);
+        assertNotEquals(windowAttributes, windowAttributes2);
+    }
+
+    private static AccessibilityWindowAttributes createInstance(String windowTitle) {
+        final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
+        layoutParams.accessibilityTitle = windowTitle;
+        return new AccessibilityWindowAttributes(layoutParams);
+    }
+}
diff --git a/core/tests/coretests/src/android/widget/TextViewTest.java b/core/tests/coretests/src/android/widget/TextViewTest.java
index 47ce2d8..cc4fbab 100644
--- a/core/tests/coretests/src/android/widget/TextViewTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewTest.java
@@ -304,6 +304,23 @@
         assertFalse(mTextView.isCursorVisible());
     }
 
+    @Test(expected = NullPointerException.class)
+    @UiThreadTest
+    public void setTextCharArrayNullThrows() {
+        mTextView = new TextView(mActivity);
+        mTextView.setText((char[]) null, 0, 0);
+    }
+
+    @Test
+    @UiThreadTest
+    public void setTextCharArrayValidAfterSetTextString() {
+        mTextView = new TextView(mActivity);
+        mTextView.setText(new char[] { 'h', 'i'}, 0, 2);
+        CharSequence charWrapper = mTextView.getText();
+        mTextView.setText("null out char wrapper");
+        assertEquals("hi", charWrapper.toString());
+    }
+
     private String createLongText() {
         int size = 600 * 1000;
         final StringBuilder builder = new StringBuilder(size);
diff --git a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
index f448cb3..b5194f6 100644
--- a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
+++ b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
@@ -66,6 +66,7 @@
         MockitoAnnotations.initMocks(this);
         mDispatcher = new WindowOnBackInvokedDispatcher(true /* applicationCallbackEnabled */);
         mDispatcher.attachToWindow(mWindowSession, mWindow);
+        mDispatcher.onWindowFocusChanged(true);
     }
 
     private void waitForIdle() {
@@ -152,4 +153,31 @@
         waitForIdle();
         verify(mCallback2).onBackStarted();
     }
+
+    @Test
+    public void skipBackInvokeWhenNoFocus() throws RemoteException {
+        ArgumentCaptor<OnBackInvokedCallbackInfo> captor =
+                ArgumentCaptor.forClass(OnBackInvokedCallbackInfo.class);
+
+        mDispatcher.registerOnBackInvokedCallback(
+                OnBackInvokedDispatcher.PRIORITY_DEFAULT, mCallback1);
+
+        verify(mWindowSession, times(1)).setOnBackInvokedCallbackInfo(
+                Mockito.eq(mWindow),
+                captor.capture());
+
+        verify(mWindowSession).setOnBackInvokedCallbackInfo(Mockito.eq(mWindow), captor.capture());
+
+        // Should invoke back if it's still in focused.
+        captor.getValue().getCallback().onBackInvoked();
+        waitForIdle();
+        verify(mCallback1).onBackInvoked();
+
+        // In case the focus has lost during back gesture.
+        mDispatcher.onWindowFocusChanged(false);
+
+        captor.getValue().getCallback().onBackInvoked();
+        waitForIdle();
+        verifyZeroInteractions(mCallback1);
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index 8214842..e8c7ce0 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -266,6 +266,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
         final IChooserWrapper activity = (IChooserWrapper) mActivityRule.launchActivity(
@@ -289,6 +290,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
         mActivityRule.launchActivity(Intent.createChooser(sendIntent, "chooser test"));
@@ -309,6 +311,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
@@ -329,6 +332,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
@@ -352,6 +356,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
@@ -378,6 +383,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
@@ -403,6 +409,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
@@ -424,6 +431,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
 
@@ -478,6 +486,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
 
@@ -518,6 +527,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
 
@@ -552,6 +562,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(null);
         Intent sendIntent = createSendTextIntent();
@@ -587,6 +598,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
 
@@ -649,6 +661,7 @@
         when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent(
                 Mockito.anyBoolean(),
                 Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
         when(ChooserActivityOverrideData.getInstance().resolverListController.getLastChosen())
                 .thenReturn(resolvedComponentInfos.get(0).getResolveInfoAt(0));
@@ -688,6 +701,7 @@
         when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent(
                 Mockito.anyBoolean(),
                 Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
 
         final IChooserWrapper activity = (IChooserWrapper)
@@ -720,6 +734,7 @@
         when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent(
             Mockito.anyBoolean(),
             Mockito.anyBoolean(),
+            Mockito.anyBoolean(),
             Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
 
         final ChooserActivity activity =
@@ -747,6 +762,7 @@
         when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent(
             Mockito.anyBoolean(),
             Mockito.anyBoolean(),
+            Mockito.anyBoolean(),
             Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
 
         MetricsLogger mockLogger = ChooserActivityOverrideData.getInstance().metricsLogger;
@@ -776,6 +792,7 @@
         when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent(
                 Mockito.anyBoolean(),
                 Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
 
         final IChooserWrapper activity = (IChooserWrapper)
@@ -846,6 +863,7 @@
         when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent(
                 Mockito.anyBoolean(),
                 Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
 
         final IChooserWrapper activity = (IChooserWrapper)
@@ -922,6 +940,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
@@ -958,6 +977,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
@@ -997,6 +1017,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
@@ -1091,6 +1112,7 @@
         when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent(
             Mockito.anyBoolean(),
             Mockito.anyBoolean(),
+            Mockito.anyBoolean(),
             Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
 
         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
@@ -1124,6 +1146,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
 
@@ -1157,6 +1180,7 @@
                     .getResolversForIntent(
                             Mockito.anyBoolean(),
                             Mockito.anyBoolean(),
+                            Mockito.anyBoolean(),
                             Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
@@ -1189,6 +1213,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
@@ -1218,6 +1243,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
 
@@ -1250,6 +1276,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
 
@@ -1284,6 +1311,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
         when(
@@ -1323,6 +1351,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
 
@@ -1365,6 +1394,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
 
@@ -1409,6 +1439,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
 
@@ -1485,6 +1516,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
 
@@ -1566,6 +1598,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
         // Create direct share target
@@ -1638,6 +1671,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
         // Create direct share target
@@ -1745,6 +1779,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
 
@@ -2060,6 +2095,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
 
@@ -2142,6 +2178,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
 
@@ -2229,6 +2266,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
 
@@ -2298,6 +2336,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
 
@@ -2446,6 +2485,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
         Intent sendIntent = createSendTextIntent();
@@ -2475,6 +2515,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
         Intent sendIntent = createSendTextIntent();
@@ -2528,6 +2569,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
         Intent chooserIntent = createChooserIntent(createSendTextIntent(),
@@ -2664,6 +2706,7 @@
         when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent(
                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
         // Create caller target which is duplicate with one of app targets
@@ -3057,6 +3100,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
         when(
@@ -3066,6 +3110,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(new ArrayList<>(workResolvedComponentInfos));
         when(
@@ -3075,6 +3120,7 @@
                         .getResolversForIntentAsUser(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class),
                                 eq(UserHandle.SYSTEM)))
                 .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
@@ -3131,6 +3177,7 @@
                         .getResolversForIntent(
                                 Mockito.anyBoolean(),
                                 Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
                                 Mockito.isA(List.class)))
                 .thenReturn(resolvedComponentInfos);
     }
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
index 43fba52..92c05b0 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
@@ -96,6 +96,7 @@
 
         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
                 Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
 
         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
@@ -127,6 +128,7 @@
 
         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
                 Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
         waitForIdle();
 
@@ -171,6 +173,7 @@
 
         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
                 Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
         waitForIdle();
 
@@ -203,6 +206,7 @@
 
         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
                 Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
         when(sOverrides.resolverListController.getLastChosen())
                 .thenReturn(resolvedComponentInfos.get(0).getResolveInfoAt(0));
@@ -273,6 +277,7 @@
 
         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
                 Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
 
         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
@@ -317,6 +322,7 @@
 
         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
                 Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
         when(sOverrides.resolverListController.getLastChosen())
                 .thenReturn(resolvedComponentInfos.get(1).getResolveInfoAt(0));
@@ -807,6 +813,7 @@
                 createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10);
         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
                 Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
                 Mockito.isA(List.class)))
                 .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
         Intent sendIntent = createSendImageIntent();
@@ -831,6 +838,7 @@
                 createResolvedComponentsForTest(1);
         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
                 Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
                 Mockito.isA(List.class)))
                 .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
         Intent sendIntent = createSendImageIntent();
@@ -888,6 +896,7 @@
 
         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
                 Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
                 Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
         when(sOverrides.resolverListController.getLastChosen())
                 .thenReturn(resolvedComponentInfos.get(1).getResolveInfoAt(0));
@@ -965,13 +974,16 @@
             List<ResolvedComponentInfo> workResolvedComponentInfos) {
         when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
                 Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
                 Mockito.isA(List.class)))
                 .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
         when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
                 Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
                 Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos);
         when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
                 Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
                 Mockito.isA(List.class),
                 eq(UserHandle.SYSTEM)))
                 .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverListControllerTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverListControllerTest.java
index e16d448..42593f6 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverListControllerTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverListControllerTest.java
@@ -20,11 +20,14 @@
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
+import static org.mockito.ArgumentMatchers.intThat;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyLong;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.usage.IUsageStatsManager;
@@ -48,6 +51,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatcher;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.mockito.invocation.InvocationOnMock;
@@ -78,6 +82,8 @@
         Configuration config = new Configuration();
         config.locale = Locale.getDefault();
         List<ResolveInfo> services = new ArrayList<>();
+        mUsm = new UsageStatsManager(mMockContext, mMockService);
+        when(mMockContext.getSystemService(Context.USAGE_STATS_SERVICE)).thenReturn(mUsm);
         when(mMockPackageManager.queryIntentServices(any(), anyInt())).thenReturn(services);
         when(mMockResources.getConfiguration()).thenReturn(config);
         when(mMockContext.getResources()).thenReturn(mMockResources);
@@ -112,8 +118,6 @@
         doAnswer(answer).when(mMockService).reportChooserSelection(
                 anyString(), anyInt(), anyString(), any(), anyString());
         when(mMockContext.getOpPackageName()).thenReturn(refererPackage);
-        mUsm = new UsageStatsManager(mMockContext, mMockService);
-        when(mMockContext.getSystemService(Context.USAGE_STATS_SERVICE)).thenReturn(mUsm);
         mController = new ResolverListController(mMockContext, mMockPackageManager, sendIntent,
                 refererPackage, UserHandle.USER_CURRENT, /* userHandle */ UserHandle.SYSTEM);
         mController.sort(new ArrayList<ResolvedComponentInfo>());
@@ -129,8 +133,6 @@
         Intent sendIntent = createSendImageIntent(annotation);
         String refererPackage = "test_referer_package";
         List<ResolvedComponentInfo> resolvedComponents = createResolvedComponentsForTest(10);
-        mUsm = new UsageStatsManager(mMockContext, mMockService);
-        when(mMockContext.getSystemService(Context.USAGE_STATS_SERVICE)).thenReturn(mUsm);
         mController = new ResolverListController(mMockContext, mMockPackageManager, sendIntent,
                 refererPackage, UserHandle.USER_CURRENT, /* userHandle */ UserHandle.SYSTEM);
         List<ResolvedComponentInfo> topKList = new ArrayList<>(resolvedComponents);
@@ -151,6 +153,102 @@
                 sortList, topKList);
     }
 
+    @Test
+    public void getResolversForIntent_usesResultsFromPackageManager() {
+        mockStats();
+        List<ResolveInfo> infos = new ArrayList<>();
+        infos.add(ResolverDataProvider.createResolveInfo(0, UserHandle.USER_CURRENT));
+        when(mMockPackageManager.queryIntentActivitiesAsUser(any(), anyInt(),
+                any(UserHandle.class))).thenReturn(infos);
+        mController = new ResolverListController(mMockContext, mMockPackageManager,
+                createSendImageIntent("test"), null, UserHandle.USER_CURRENT,
+                /* userHandle= */ UserHandle.SYSTEM);
+        List<Intent> intents = new ArrayList<>();
+        intents.add(createActionMainIntent());
+
+        List<ResolvedComponentInfo> resolvers = mController
+                .getResolversForIntent(
+                        /* shouldGetResolvedFilter= */ true,
+                        /* shouldGetActivityMetadata= */ true,
+                        /* shouldGetOnlyDefaultActivities= */ true,
+                        intents);
+
+        assertThat(resolvers, hasSize(1));
+        assertThat(resolvers.get(0).getResolveInfoAt(0), is(infos.get(0)));
+    }
+
+    @Test
+    public void getResolversForIntent_shouldGetOnlyDefaultActivitiesTrue_addsFlag() {
+        mockStats();
+        List<ResolveInfo> infos = new ArrayList<>();
+        infos.add(ResolverDataProvider.createResolveInfo(0, UserHandle.USER_CURRENT));
+        when(mMockPackageManager.queryIntentActivitiesAsUser(any(), anyInt(),
+                any(UserHandle.class))).thenReturn(infos);
+        mController = new ResolverListController(mMockContext, mMockPackageManager,
+                createSendImageIntent("test"), null, UserHandle.USER_CURRENT,
+                /* userHandle= */ UserHandle.SYSTEM);
+        List<Intent> intents = new ArrayList<>();
+        intents.add(createActionMainIntent());
+
+        mController
+                .getResolversForIntent(
+                        /* shouldGetResolvedFilter= */ true,
+                        /* shouldGetActivityMetadata= */ true,
+                        /* shouldGetOnlyDefaultActivities= */ true,
+                        intents);
+
+        verify(mMockPackageManager).queryIntentActivitiesAsUser(any(),
+                containsFlag(PackageManager.MATCH_DEFAULT_ONLY), any());
+    }
+
+    @Test
+    public void getResolversForIntent_shouldGetOnlyDefaultActivitiesFalse_doesNotAddFlag() {
+        mockStats();
+        List<ResolveInfo> infos = new ArrayList<>();
+        infos.add(ResolverDataProvider.createResolveInfo(0, UserHandle.USER_CURRENT));
+        when(mMockPackageManager.queryIntentActivitiesAsUser(any(), anyInt(),
+                any(UserHandle.class))).thenReturn(infos);
+        mController = new ResolverListController(mMockContext, mMockPackageManager,
+                createSendImageIntent("test"), null, UserHandle.USER_CURRENT,
+                /* userHandle= */ UserHandle.SYSTEM);
+        List<Intent> intents = new ArrayList<>();
+        intents.add(createActionMainIntent());
+
+        mController
+                .getResolversForIntent(
+                        /* shouldGetResolvedFilter= */ true,
+                        /* shouldGetActivityMetadata= */ true,
+                        /* shouldGetOnlyDefaultActivities= */ false,
+                        intents);
+
+        verify(mMockPackageManager).queryIntentActivitiesAsUser(any(),
+                doesNotContainFlag(PackageManager.MATCH_DEFAULT_ONLY), any());
+    }
+
+    private int containsFlag(int flag) {
+        return intThat(new FlagMatcher(flag, /* contains= */ true));
+    }
+
+    private int doesNotContainFlag(int flag) {
+        return intThat(new FlagMatcher(flag, /* contains= */ false));
+    }
+
+    public static class FlagMatcher implements ArgumentMatcher<Integer> {
+
+        private final int mFlag;
+        private final boolean mContains;
+
+        public FlagMatcher(int flag, boolean contains) {
+            mFlag = flag;
+            mContains = contains;
+        }
+
+        @Override
+        public boolean matches(Integer integer) {
+            return ((integer & mFlag) != 0) == mContains;
+        }
+    }
+
     private UsageStats initStats(String packageName, String action,
                                  String annotation, int count) {
         ArrayMap<String, ArrayMap<String, Integer>> chooserCounts = new ArrayMap<>();
@@ -174,6 +272,24 @@
         return sendIntent;
     }
 
+    private Intent createActionMainIntent() {
+        Intent sendIntent = new Intent();
+        sendIntent.setAction(Intent.ACTION_MAIN);
+        sendIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+        return sendIntent;
+    }
+
+    private void mockStats() {
+        final List<UsageStats> slices = new ArrayList<>();
+        ParceledListSlice<UsageStats> stats = new ParceledListSlice<>(slices);
+        try {
+            when(mMockService.queryUsageStats(anyInt(), anyLong(), anyLong(), anyString(),
+                    anyInt())).thenReturn(stats);
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+    }
+
     private Integer getCount(
             UsageStatsManager usm, String packageName, String action, String annotation) {
         if (usm == null) {
diff --git a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
index 09fc7ea..e068730 100644
--- a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
@@ -36,6 +36,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.only;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -83,6 +84,7 @@
     private StatsLogWrapper mStatsLog;
     private ArgumentCaptor<OnJankDataListener> mListenerCapture;
     private SurfaceControl mSurfaceControl;
+    private ArgumentCaptor<Runnable> mRunnableArgumentCaptor;
 
     @Before
     public void setup() {
@@ -99,6 +101,8 @@
         mSurfaceControl = new SurfaceControl.Builder().setName("Surface").build();
         mViewRootWrapper = mock(ViewRootWrapper.class);
         when(mViewRootWrapper.getSurfaceControl()).thenReturn(mSurfaceControl);
+        doNothing().when(mViewRootWrapper).addSurfaceChangedCallback(any());
+        doNothing().when(mViewRootWrapper).removeSurfaceChangedCallback(any());
         mSurfaceControlWrapper = mock(SurfaceControlWrapper.class);
 
         mListenerCapture = ArgumentCaptor.forClass(OnJankDataListener.class);
@@ -109,23 +113,29 @@
 
         mChoreographer = mock(ChoreographerWrapper.class);
         mStatsLog = mock(StatsLogWrapper.class);
+        mRunnableArgumentCaptor = ArgumentCaptor.forClass(Runnable.class);
     }
 
     private FrameTracker spyFrameTracker(int cuj, String postfix, boolean surfaceOnly) {
+        InteractionJankMonitor monitor = mock(InteractionJankMonitor.class);
         Handler handler = mRule.getActivity().getMainThreadHandler();
         Session session = new Session(cuj, postfix);
         Configuration config = mock(Configuration.class);
         when(config.isSurfaceOnly()).thenReturn(surfaceOnly);
         when(config.getSurfaceControl()).thenReturn(mSurfaceControl);
         when(config.shouldDeferMonitor()).thenReturn(true);
+        View view = mRule.getActivity().getWindow().getDecorView();
+        Handler spyHandler = spy(new Handler(handler.getLooper()));
+        when(config.getView()).thenReturn(surfaceOnly ? null : view);
+        when(config.getHandler()).thenReturn(spyHandler);
         FrameTracker frameTracker = Mockito.spy(
-                new FrameTracker(session, handler, mRenderer, mViewRootWrapper,
+                new FrameTracker(monitor, session, spyHandler, mRenderer, mViewRootWrapper,
                         mSurfaceControlWrapper, mChoreographer, mWrapper, mStatsLog,
                         /* traceThresholdMissedFrames= */ 1,
                         /* traceThresholdFrameTimeMillis= */ -1,
                         /* FrameTrackerListener= */ null, config));
         doNothing().when(frameTracker).triggerPerfetto();
-        doNothing().when(frameTracker).postTraceStartMarker();
+        doNothing().when(frameTracker).postTraceStartMarker(mRunnableArgumentCaptor.capture());
         return frameTracker;
     }
 
@@ -140,6 +150,7 @@
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
+        mRunnableArgumentCaptor.getValue().run();
         verify(mRenderer, only()).addObserver(any());
 
         // send first frame with a long duration - should not be taken into account
@@ -173,6 +184,7 @@
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
+        mRunnableArgumentCaptor.getValue().run();
         verify(mRenderer, only()).addObserver(any());
 
         // send first frame - not janky
@@ -208,6 +220,7 @@
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
+        mRunnableArgumentCaptor.getValue().run();
         verify(mRenderer, only()).addObserver(any());
 
         // send first frame - janky
@@ -243,6 +256,7 @@
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
+        mRunnableArgumentCaptor.getValue().run();
         verify(mRenderer, only()).addObserver(any());
 
         // send first frame - not janky
@@ -278,6 +292,7 @@
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
+        mRunnableArgumentCaptor.getValue().run();
         verify(mRenderer, only()).addObserver(any());
 
         // send first frame - not janky
@@ -319,6 +334,7 @@
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
+        mRunnableArgumentCaptor.getValue().run();
         verify(mRenderer, only()).addObserver(any());
 
         // send first frame - not janky
@@ -332,7 +348,7 @@
         tracker.end(FrameTracker.REASON_END_NORMAL);
 
         // Send incomplete callback for 102L
-        sendSfFrame(102L, JANK_NONE);
+        sendSfFrame(tracker, 102L, JANK_NONE);
 
         // Send janky but complete callbck fo 103L
         sendFrame(tracker, 50, JANK_APP_DEADLINE_MISSED, 103L);
@@ -356,6 +372,7 @@
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
+        mRunnableArgumentCaptor.getValue().run();
         verify(mRenderer).addObserver(any());
 
         // First frame - not janky
@@ -380,6 +397,7 @@
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
+        mRunnableArgumentCaptor.getValue().run();
         verify(mRenderer, only()).addObserver(any());
 
         // end the trace session
@@ -403,6 +421,7 @@
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
+        mRunnableArgumentCaptor.getValue().run();
         verify(mRenderer, only()).addObserver(any());
 
         // end the trace session at the same vsync id, end vsync id will less than the begin one.
@@ -444,6 +463,7 @@
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
+        mRunnableArgumentCaptor.getValue().run();
         verify(mSurfaceControlWrapper).addJankStatsListener(any(), any());
 
         // First frame - not janky
@@ -479,6 +499,7 @@
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
+        mRunnableArgumentCaptor.getValue().run();
         verify(mSurfaceControlWrapper).addJankStatsListener(any(), any());
 
         // First frame - janky
@@ -514,6 +535,7 @@
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
+        mRunnableArgumentCaptor.getValue().run();
         verify(mSurfaceControlWrapper).addJankStatsListener(any(), any());
 
         // First frame - not janky
@@ -548,6 +570,7 @@
                 CUJ_WALLPAPER_TRANSITION, CUJ_POSTFIX, /* surfaceOnly= */ true);
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
+        mRunnableArgumentCaptor.getValue().run();
         verify(mSurfaceControlWrapper).addJankStatsListener(any(), any());
         sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 100L);
         sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 101L);
@@ -594,7 +617,7 @@
         if (!tracker.mSurfaceOnly) {
             sendHwuiFrame(tracker, durationMillis, vsyncId, firstWindowFrame);
         }
-        sendSfFrame(vsyncId, jankType);
+        sendSfFrame(tracker, vsyncId, jankType);
     }
 
     private void sendHwuiFrame(FrameTracker tracker, long durationMillis, long vsyncId,
@@ -604,12 +627,18 @@
                 .getMetric(FrameMetrics.FIRST_DRAW_FRAME);
         doReturn(TimeUnit.MILLISECONDS.toNanos(durationMillis))
                 .when(mWrapper).getMetric(FrameMetrics.TOTAL_DURATION);
+        final ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
+        doNothing().when(tracker).postCallback(captor.capture());
         tracker.onFrameMetricsAvailable(0);
+        captor.getValue().run();
     }
 
-    private void sendSfFrame(long vsyncId, @JankType int jankType) {
+    private void sendSfFrame(FrameTracker tracker, long vsyncId, @JankType int jankType) {
+        final ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
+        doNothing().when(tracker).postCallback(captor.capture());
         mListenerCapture.getValue().onJankDataAvailable(new JankData[] {
                 new JankData(vsyncId, jankType)
         });
+        captor.getValue().run();
     }
 }
diff --git a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
index 5a6fd53..d96f041 100644
--- a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
@@ -93,7 +93,7 @@
     @Test
     public void testBeginEnd() {
         InteractionJankMonitor monitor = createMockedInteractionJankMonitor();
-        FrameTracker tracker = createMockedFrameTracker(null);
+        FrameTracker tracker = createMockedFrameTracker(monitor, null);
         doReturn(tracker).when(monitor).createFrameTracker(any(), any());
         doNothing().when(tracker).begin();
         doReturn(true).when(tracker).end(anyInt());
@@ -134,7 +134,7 @@
     public void testBeginTimeout() {
         ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
         InteractionJankMonitor monitor = createMockedInteractionJankMonitor();
-        FrameTracker tracker = createMockedFrameTracker(null);
+        FrameTracker tracker = createMockedFrameTracker(monitor, null);
         doReturn(tracker).when(monitor).createFrameTracker(any(), any());
         doNothing().when(tracker).begin();
         doReturn(true).when(tracker).cancel(anyInt());
@@ -180,7 +180,8 @@
         return monitor;
     }
 
-    private FrameTracker createMockedFrameTracker(FrameTracker.FrameTrackerListener listener) {
+    private FrameTracker createMockedFrameTracker(InteractionJankMonitor monitor,
+            FrameTracker.FrameTrackerListener listener) {
         Session session = spy(new Session(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, CUJ_POSTFIX));
         doReturn(false).when(session).logToStatsd();
 
@@ -190,6 +191,7 @@
 
         ViewRootWrapper viewRoot = spy(new ViewRootWrapper(mView.getViewRootImpl()));
         doNothing().when(viewRoot).addSurfaceChangedCallback(any());
+        doNothing().when(viewRoot).removeSurfaceChangedCallback(any());
 
         SurfaceControlWrapper surfaceControl = mock(SurfaceControlWrapper.class);
         doNothing().when(surfaceControl).addJankStatsListener(any(), any());
@@ -200,15 +202,18 @@
 
         Configuration configuration = mock(Configuration.class);
         when(configuration.isSurfaceOnly()).thenReturn(false);
+        when(configuration.getView()).thenReturn(mView);
+        when(configuration.getHandler()).thenReturn(mView.getHandler());
 
-        FrameTracker tracker = spy(new FrameTracker(session, mWorker.getThreadHandler(),
+        FrameTracker tracker = spy(new FrameTracker(monitor, session, mWorker.getThreadHandler(),
                 threadedRenderer, viewRoot, surfaceControl, choreographer,
                 new FrameMetricsWrapper(), new StatsLogWrapper(),
                 /* traceThresholdMissedFrames= */ 1,
                 /* traceThresholdFrameTimeMillis= */ -1, listener, configuration));
 
-        doNothing().when(tracker).postTraceStartMarker();
+        doNothing().when(tracker).postTraceStartMarker(any());
         doNothing().when(tracker).triggerPerfetto();
+        doReturn(configuration.getHandler()).when(tracker).getHandler();
 
         return tracker;
     }
diff --git a/core/tests/coretests/src/com/android/internal/util/FastDataTest.java b/core/tests/coretests/src/com/android/internal/util/FastDataTest.java
index 81fb39f..04dfd6e 100644
--- a/core/tests/coretests/src/com/android/internal/util/FastDataTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/FastDataTest.java
@@ -23,10 +23,13 @@
 import android.annotation.NonNull;
 import android.util.ExceptionUtils;
 
-import androidx.test.ext.junit.runners.AndroidJUnit4;
+import libcore.util.HexEncoding;
 
+import org.junit.Assume;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -38,22 +41,34 @@
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.function.Consumer;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 public class FastDataTest {
+    private final boolean use4ByteSequence;
+
     private static final String TEST_SHORT_STRING = "a";
-    private static final String TEST_LONG_STRING = "com☃example☃typical☃package☃name";
+    private static final String TEST_LONG_STRING = "com☃example😀typical☃package😀name";
     private static final byte[] TEST_BYTES = TEST_LONG_STRING.getBytes(StandardCharsets.UTF_16LE);
 
+    @Parameters(name = "use4ByteSequence={0}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] { {true}, {false} });
+    }
+
+    public FastDataTest(boolean use4ByteSequence) {
+        this.use4ByteSequence = use4ByteSequence;
+    }
+
     @Test
     public void testEndOfFile_Int() throws Exception {
         try (FastDataInput in = new FastDataInput(new ByteArrayInputStream(
-                new byte[] { 1 }), 1000)) {
+                new byte[] { 1 }), 1000, use4ByteSequence)) {
             assertThrows(EOFException.class, () -> in.readInt());
         }
         try (FastDataInput in = new FastDataInput(new ByteArrayInputStream(
-                new byte[] { 1, 1, 1, 1 }), 1000)) {
+                new byte[] { 1, 1, 1, 1 }), 1000, use4ByteSequence)) {
             assertEquals(1, in.readByte());
             assertThrows(EOFException.class, () -> in.readInt());
         }
@@ -62,11 +77,11 @@
     @Test
     public void testEndOfFile_String() throws Exception {
         try (FastDataInput in = new FastDataInput(new ByteArrayInputStream(
-                new byte[] { 1 }), 1000)) {
+                new byte[] { 1 }), 1000, use4ByteSequence)) {
             assertThrows(EOFException.class, () -> in.readUTF());
         }
         try (FastDataInput in = new FastDataInput(new ByteArrayInputStream(
-                new byte[] { 1, 1, 1, 1 }), 1000)) {
+                new byte[] { 1, 1, 1, 1 }), 1000, use4ByteSequence)) {
             assertThrows(EOFException.class, () -> in.readUTF());
         }
     }
@@ -74,12 +89,12 @@
     @Test
     public void testEndOfFile_Bytes_Small() throws Exception {
         try (FastDataInput in = new FastDataInput(new ByteArrayInputStream(
-                new byte[] { 1, 1, 1, 1 }), 1000)) {
+                new byte[] { 1, 1, 1, 1 }), 1000, use4ByteSequence)) {
             final byte[] tmp = new byte[10];
             assertThrows(EOFException.class, () -> in.readFully(tmp));
         }
         try (FastDataInput in = new FastDataInput(new ByteArrayInputStream(
-                new byte[] { 1, 1, 1, 1 }), 1000)) {
+                new byte[] { 1, 1, 1, 1 }), 1000, use4ByteSequence)) {
             final byte[] tmp = new byte[10_000];
             assertThrows(EOFException.class, () -> in.readFully(tmp));
         }
@@ -88,7 +103,8 @@
     @Test
     public void testUTF_Bounds() throws Exception {
         final char[] buf = new char[65_534];
-        try (FastDataOutput out = new FastDataOutput(new ByteArrayOutputStream(), BOUNCE_SIZE)) {
+        try (FastDataOutput out = new FastDataOutput(new ByteArrayOutputStream(),
+                BOUNCE_SIZE, use4ByteSequence)) {
             // Writing simple string will fit fine
             Arrays.fill(buf, '!');
             final String simple = new String(buf);
@@ -100,11 +116,15 @@
             final String complex = new String(buf);
             assertThrows(IOException.class, () -> out.writeUTF(complex));
             assertThrows(IOException.class, () -> out.writeInternedUTF(complex));
+
+            out.flush();
         }
     }
 
     @Test
     public void testTranscode() throws Exception {
+        Assume.assumeFalse(use4ByteSequence);
+
         // Verify that upstream data can be read by fast
         {
             final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
@@ -113,20 +133,22 @@
             out.flush();
 
             final FastDataInput in = new FastDataInput(
-                    new ByteArrayInputStream(outStream.toByteArray()), BOUNCE_SIZE);
-            doTransodeRead(in);
+                    new ByteArrayInputStream(outStream.toByteArray()),
+                    BOUNCE_SIZE, use4ByteSequence);
+            doTranscodeRead(in);
         }
 
         // Verify that fast data can be read by upstream
         {
             final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
-            final FastDataOutput out = new FastDataOutput(outStream, BOUNCE_SIZE);
+            final FastDataOutput out = new FastDataOutput(outStream,
+                    BOUNCE_SIZE, use4ByteSequence);
             doTranscodeWrite(out);
             out.flush();
 
             final DataInputStream in = new DataInputStream(
                     new ByteArrayInputStream(outStream.toByteArray()));
-            doTransodeRead(in);
+            doTranscodeRead(in);
         }
     }
 
@@ -144,7 +166,7 @@
         out.writeDouble(32d);
     }
 
-    private static void doTransodeRead(DataInput in) throws IOException {
+    private static void doTranscodeRead(DataInput in) throws IOException {
         assertEquals(true, in.readBoolean());
         assertEquals(false, in.readBoolean());
         assertEquals(1, in.readByte());
@@ -225,10 +247,12 @@
         doBounce((out) -> {
             out.writeUTF("");
             out.writeUTF("☃");
+            out.writeUTF("😀");
             out.writeUTF("example");
         }, (in) -> {
             assertEquals("", in.readUTF());
             assertEquals("☃", in.readUTF());
+            assertEquals("😀", in.readUTF());
             assertEquals("example", in.readUTF());
         });
     }
@@ -263,6 +287,35 @@
         }, 1);
     }
 
+    /**
+     * Verify that we encode every valid code-point identically to RI when
+     * running in 3-byte mode.
+     */
+    @Test
+    public void testBounce_UTF_Exhaustive() throws Exception {
+        Assume.assumeFalse(use4ByteSequence);
+
+        final ByteArrayOutputStream slowStream = new ByteArrayOutputStream();
+        final DataOutput slowData = new DataOutputStream(slowStream);
+
+        final ByteArrayOutputStream fastStream = new ByteArrayOutputStream();
+        final FastDataOutput fastData = FastDataOutput.obtainUsing3ByteSequences(fastStream);
+
+        for (int cp = Character.MIN_CODE_POINT; cp < Character.MAX_CODE_POINT; cp++) {
+            if (Character.isValidCodePoint(cp)) {
+                final String cpString = new String(Character.toChars(cp));
+                slowStream.reset();
+                slowData.writeUTF(cpString);
+                fastStream.reset();
+                fastData.writeUTF(cpString);
+                fastData.flush();
+                assertEquals("Bad encoding for code-point " + Integer.toHexString(cp),
+                        HexEncoding.encodeToString(slowStream.toByteArray()),
+                        HexEncoding.encodeToString(fastStream.toByteArray()));
+            }
+        }
+    }
+
     @Test
     public void testBounce_InternedUTF() throws Exception {
         doBounce((out) -> {
@@ -355,22 +408,24 @@
      * Verify that some common data can be written and read back, effectively
      * "bouncing" it through a serialized representation.
      */
-    private static void doBounce(@NonNull ThrowingConsumer<FastDataOutput> out,
+    private void doBounce(@NonNull ThrowingConsumer<FastDataOutput> out,
             @NonNull ThrowingConsumer<FastDataInput> in) throws Exception {
         doBounce(out, in, BOUNCE_REPEAT);
     }
 
-    private static void doBounce(@NonNull ThrowingConsumer<FastDataOutput> out,
+    private void doBounce(@NonNull ThrowingConsumer<FastDataOutput> out,
             @NonNull ThrowingConsumer<FastDataInput> in, int count) throws Exception {
         final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
-        final FastDataOutput outData = new FastDataOutput(outStream, BOUNCE_SIZE);
+        final FastDataOutput outData = new FastDataOutput(outStream,
+                BOUNCE_SIZE, use4ByteSequence);
         for (int i = 0; i < count; i++) {
             out.accept(outData);
         }
         outData.flush();
 
         final ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray());
-        final FastDataInput inData = new FastDataInput(inStream, BOUNCE_SIZE);
+        final FastDataInput inData = new FastDataInput(inStream,
+                BOUNCE_SIZE, use4ByteSequence);
         for (int i = 0; i < count; i++) {
             in.accept(inData);
         }
diff --git a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
index 8d3751e..47f70dd 100644
--- a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
+++ b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
@@ -207,8 +207,8 @@
         final Configuration currentConfig = new Configuration();
 
         assertFalse("Must not report change if no public diff",
-                shouldReportChange(0 /* publicDiff */, currentConfig, newConfig,
-                null /* sizeBuckets */, 0 /* handledConfigChanges */));
+                shouldReportChange(currentConfig, newConfig, null /* sizeBuckets */,
+                        0 /* handledConfigChanges */));
 
         final int[] verticalThresholds = {100, 400};
         final SizeConfigurationBuckets buckets = new SizeConfigurationBuckets(
@@ -221,25 +221,25 @@
         newConfig.screenHeightDp = 300;
 
         assertFalse("Must not report changes if the diff is small and not handled",
-                shouldReportChange(CONFIG_SCREEN_SIZE /* publicDiff */, currentConfig,
-                newConfig, buckets, CONFIG_FONT_SCALE /* handledConfigChanges */));
+                shouldReportChange(currentConfig, newConfig, buckets,
+                        CONFIG_FONT_SCALE /* handledConfigChanges */));
 
         assertTrue("Must report changes if the small diff is handled",
-                shouldReportChange(CONFIG_SCREEN_SIZE /* publicDiff */, currentConfig, newConfig,
-                buckets, CONFIG_SCREEN_SIZE /* handledConfigChanges */));
+                shouldReportChange(currentConfig, newConfig, buckets,
+                        CONFIG_SCREEN_SIZE /* handledConfigChanges */));
 
         currentConfig.fontScale = 0.8f;
         newConfig.fontScale = 1.2f;
 
         assertTrue("Must report handled changes regardless of small unhandled change",
-                shouldReportChange(CONFIG_SCREEN_SIZE | CONFIG_FONT_SCALE /* publicDiff */,
-                currentConfig, newConfig, buckets, CONFIG_FONT_SCALE /* handledConfigChanges */));
+                shouldReportChange(currentConfig, newConfig, buckets,
+                        CONFIG_FONT_SCALE /* handledConfigChanges */));
 
         newConfig.screenHeightDp = 500;
 
         assertFalse("Must not report changes if there's unhandled big changes",
-                shouldReportChange(CONFIG_SCREEN_SIZE | CONFIG_FONT_SCALE /* publicDiff */,
-                currentConfig, newConfig, buckets, CONFIG_FONT_SCALE /* handledConfigChanges */));
+                shouldReportChange(currentConfig, newConfig, buckets,
+                        CONFIG_FONT_SCALE /* handledConfigChanges */));
     }
 
     private void recreateAndVerifyNoRelaunch(ActivityThread activityThread, TestActivity activity) {
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 2ce8fac..d52c70b 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -577,12 +577,6 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
-    "-1521427940": {
-      "message": "commitVisibility: %s: visible=%b mVisibleRequested=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
     "-1517908912": {
       "message": "requestScrollCapture: caught exception dispatching to window.token=%s",
       "level": "WARN",
@@ -1519,6 +1513,12 @@
       "group": "WM_DEBUG_FOCUS_LIGHT",
       "at": "com\/android\/server\/wm\/DisplayContent.java"
     },
+    "-636553602": {
+      "message": "commitVisibility: %s: visible=%b visibleRequested=%b, isInTransition=%b, runningAnimation=%b, caller=%s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_APP_TRANSITIONS",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "-635082269": {
       "message": "******** booted=%b msg=%b haveBoot=%b haveApp=%b haveWall=%b wallEnabled=%b haveKeyguard=%b",
       "level": "INFO",
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index 84e949a..f8c015f 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -932,7 +932,7 @@
         <font weight="700" style="normal" fallbackFor="serif">NotoSerifLao-Bold.ttf</font>
     </family>
     <family lang="und-Laoo" variant="compact">
-        <font weight="400" style="normal">NotoSansLaoUI-Regular.ttf
+        <font weight="400" style="normal" postScriptName="NotoSansLaoUI">NotoSansLaoUI-Regular.ttf
         </font>
         <font weight="700" style="normal">NotoSansLaoUI-Bold.ttf</font>
     </family>
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 451b99e..1a80ab3 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -3136,6 +3136,128 @@
         return result;
     }
 
+
+    /**
+     * Measure the advance of each character within a run of text and also return the cursor
+     * position within the run.
+     *
+     * @see #getRunAdvance(char[], int, int, int, int, boolean, int) for more details.
+     *
+     * @param text the text to measure. Cannot be null.
+     * @param start the index of the start of the range to measure
+     * @param end the index + 1 of the end of the range to measure
+     * @param contextStart the index of the start of the shaping context
+     * @param contextEnd the index + 1 of the end of the shaping context
+     * @param isRtl whether the run is in RTL direction
+     * @param offset index of caret position
+     * @param advances the array that receives the computed character advances
+     * @param advancesIndex the start index from which the advances array is filled
+     * @return width measurement between start and offset
+     * @throws IndexOutOfBoundsException if a) contextStart or contextEnd is out of array's range
+     * or contextStart is larger than contextEnd,
+     * b) start or end is not within the range [contextStart, contextEnd), or start is larger than
+     * end,
+     * c) offset is not within the range [start, end),
+     * d) advances.length - advanceIndex is smaller than the length of the run, which equals to
+     * end - start.
+     *
+     */
+    public float getRunCharacterAdvance(@NonNull char[] text, int start, int end, int contextStart,
+            int contextEnd, boolean isRtl, int offset,
+            @Nullable float[] advances, int advancesIndex) {
+        if (text == null) {
+            throw new IllegalArgumentException("text cannot be null");
+        }
+        if (contextStart < 0 || contextEnd > text.length) {
+            throw new IndexOutOfBoundsException("Invalid Context Range: " + contextStart + ", "
+                    + contextEnd + " must be in 0, " + text.length);
+        }
+
+        if (start < contextStart || contextEnd < end) {
+            throw new IndexOutOfBoundsException("Invalid start/end range: " + start + ", " + end
+                    + " must be in " + contextStart + ", " + contextEnd);
+        }
+
+        if (offset < start || end < offset) {
+            throw new IndexOutOfBoundsException("Invalid offset position: " + offset
+                    + " must be in " + start + ", " + end);
+        }
+
+        if (advances != null && advances.length < advancesIndex - start + end) {
+            throw new IndexOutOfBoundsException("Given array doesn't have enough space to receive "
+                    + "the result, advances.length: " + advances.length + " advanceIndex: "
+                    + advancesIndex + " needed space: " + (offset - start));
+        }
+
+        if (end == start) {
+            return 0.0f;
+        }
+
+        return nGetRunCharacterAdvance(mNativePaint, text, start, end, contextStart, contextEnd,
+                isRtl, offset, advances, advancesIndex);
+    }
+
+    /**
+     * @see #getRunCharacterAdvance(char[], int, int, int, int, boolean, int, float[], int)
+     *
+     * @param text the text to measure. Cannot be null.
+     * @param start the index of the start of the range to measure
+     * @param end the index + 1 of the end of the range to measure
+     * @param contextStart the index of the start of the shaping context
+     * @param contextEnd the index + 1 of the end of the shaping context
+     * @param isRtl whether the run is in RTL direction
+     * @param offset index of caret position
+     * @param advances the array that receives the computed character advances
+     * @param advancesIndex the start index from which the advances array is filled
+     * @return width measurement between start and offset
+     * @throws IndexOutOfBoundsException if a) contextStart or contextEnd is out of array's range
+     * or contextStart is larger than contextEnd,
+     * b) start or end is not within the range [contextStart, contextEnd), or end is larger than
+     * start,
+     * c) offset is not within the range [start, end),
+     * d) advances.length - advanceIndex is smaller than the run length, which equals to
+     * end - start.
+     */
+    public float getRunCharacterAdvance(@NonNull CharSequence text, int start, int end,
+            int contextStart, int contextEnd, boolean isRtl, int offset,
+            @Nullable float[] advances, int advancesIndex) {
+        if (text == null) {
+            throw new IllegalArgumentException("text cannot be null");
+        }
+        if (contextStart < 0 || contextEnd > text.length()) {
+            throw new IndexOutOfBoundsException("Invalid Context Range: " + contextStart + ", "
+                    + contextEnd + " must be in 0, " + text.length());
+        }
+
+        if (start < contextStart || contextEnd < end) {
+            throw new IndexOutOfBoundsException("Invalid start/end range: " + start + ", " + end
+                    + " must be in " + contextStart + ", " + contextEnd);
+        }
+
+        if (offset < start || end < offset) {
+            throw new IndexOutOfBoundsException("Invalid offset position: " + offset
+                    + " must be in " + start + ", " + end);
+        }
+
+        if (advances != null && advances.length < advancesIndex - start + end) {
+            throw new IndexOutOfBoundsException("Given array doesn't have enough space to receive "
+                    + "the result, advances.length: " + advances.length + " advanceIndex: "
+                    + advancesIndex + " needed space: " + (offset - start));
+        }
+
+        if (end == start) {
+            return 0.0f;
+        }
+
+        char[] buf = TemporaryBuffer.obtain(contextEnd - contextStart);
+        TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
+        final float result = getRunCharacterAdvance(buf, start - contextStart, end - contextStart,
+                0, contextEnd - contextStart, isRtl, offset - contextStart,
+                advances, advancesIndex);
+        TemporaryBuffer.recycle(buf);
+        return result;
+    }
+
     /**
      * Get the character offset within the string whose position is closest to the specified
      * horizontal position.
@@ -3247,6 +3369,9 @@
     private static native boolean nHasGlyph(long paintPtr, int bidiFlags, String string);
     private static native float nGetRunAdvance(long paintPtr, char[] text, int start, int end,
             int contextStart, int contextEnd, boolean isRtl, int offset);
+    private static native float nGetRunCharacterAdvance(long paintPtr, char[] text, int start,
+            int end, int contextStart, int contextEnd, boolean isRtl, int offset, float[] advances,
+            int advancesIndex);
     private static native int nGetOffsetForAdvance(long paintPtr, char[] text, int start, int end,
             int contextStart, int contextEnd, boolean isRtl, float advance);
     private static native void nGetFontMetricsIntForText(long paintPtr, char[] text,
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index a2f5301..596d061 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -57,6 +57,7 @@
 import com.android.internal.util.Preconditions;
 
 import dalvik.annotation.optimization.CriticalNative;
+import dalvik.annotation.optimization.FastNative;
 
 import libcore.util.NativeAllocationRegistry;
 
@@ -1176,6 +1177,17 @@
         mWeight = nativeGetWeight(ni);
     }
 
+    /**
+     * Releases the underlying native object.
+     *
+     * <p>For testing only. Do not use the instance after this method is called.
+     * It is safe to call this method twice or more on the same instance.
+     * @hide
+     */
+    public void releaseNativeObjectForTest() {
+        mCleaner.run();
+    }
+
     private static Typeface getSystemDefaultTypeface(@NonNull String familyName) {
         Typeface tf = sSystemFontMap.get(familyName);
         return tf == null ? Typeface.DEFAULT : tf;
@@ -1395,6 +1407,9 @@
         FontConfig config = SystemFonts.getSystemPreinstalledFontConfig();
         for (int i = 0; i < config.getFontFamilies().size(); ++i) {
             FontConfig.FontFamily family = config.getFontFamilies().get(i);
+            if (!family.getLocaleList().isEmpty()) {
+                nativeRegisterLocaleList(family.getLocaleList().toLanguageTags());
+            }
             boolean loadFamily = false;
             for (int j = 0; j < family.getLocaleList().size(); ++j) {
                 String fontScript = ULocale.addLikelySubtags(
@@ -1425,7 +1440,7 @@
     public static void destroySystemFontMap() {
         synchronized (SYSTEM_FONT_MAP_LOCK) {
             for (Typeface typeface : sSystemFontMap.values()) {
-                typeface.mCleaner.run();
+                typeface.releaseNativeObjectForTest();
             }
             sSystemFontMap.clear();
             if (sSystemFontMapBuffer != null) {
@@ -1433,9 +1448,25 @@
             }
             sSystemFontMapBuffer = null;
             sSystemFontMapSharedMemory = null;
+            synchronized (sStyledCacheLock) {
+                destroyTypefaceCacheLocked(sStyledTypefaceCache);
+            }
+            synchronized (sWeightCacheLock) {
+                destroyTypefaceCacheLocked(sWeightTypefaceCache);
+            }
         }
     }
 
+    private static void destroyTypefaceCacheLocked(LongSparseArray<SparseArray<Typeface>> cache) {
+        for (int i = 0; i < cache.size(); i++) {
+            SparseArray<Typeface> array = cache.valueAt(i);
+            for (int j = 0; j < array.size(); j++) {
+                array.valueAt(j).releaseNativeObjectForTest();
+            }
+        }
+        cache.clear();
+    }
+
     /** @hide */
     public static void loadPreinstalledSystemFontMap() {
         final FontConfig fontConfig = SystemFonts.getSystemPreinstalledFontConfig();
@@ -1541,4 +1572,7 @@
     private static native void nativeAddFontCollections(long nativePtr);
 
     private static native void nativeWarmUpCache(String fileName);
+
+    @FastNative
+    private static native void nativeRegisterLocaleList(String locales);
 }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 2f79cae..da9fd0c2 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -16,6 +16,7 @@
 
 package androidx.window.extensions.embedding;
 
+import static android.app.ActivityManager.START_SUCCESS;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 
@@ -97,6 +98,7 @@
     private final List<SplitInfo> mLastReportedSplitStates = new ArrayList<>();
     private final Handler mHandler;
     private final Object mLock = new Object();
+    private final ActivityStartMonitor mActivityStartMonitor;
 
     public SplitController() {
         final MainThreadExecutor executor = new MainThreadExecutor();
@@ -108,7 +110,8 @@
                 new LifecycleCallbacks());
         // Intercept activity starts to route activities to new containers if necessary.
         Instrumentation instrumentation = activityThread.getInstrumentation();
-        instrumentation.addMonitor(new ActivityStartMonitor());
+        mActivityStartMonitor = new ActivityStartMonitor();
+        instrumentation.addMonitor(mActivityStartMonitor);
     }
 
     /** Updates the embedding rules applied to future activity launches. */
@@ -1385,6 +1388,11 @@
         return ActivityThread.currentActivityThread().getActivity(activityToken);
     }
 
+    @VisibleForTesting
+    ActivityStartMonitor getActivityStartMonitor() {
+        return mActivityStartMonitor;
+    }
+
     /**
      * Gets the token of the initial TaskFragment that embedded this activity. Do not rely on it
      * after creation because the activity could be reparented.
@@ -1536,7 +1544,10 @@
      * A monitor that intercepts all activity start requests originating in the client process and
      * can amend them to target a specific task fragment to form a split.
      */
-    private class ActivityStartMonitor extends Instrumentation.ActivityMonitor {
+    @VisibleForTesting
+    class ActivityStartMonitor extends Instrumentation.ActivityMonitor {
+        @VisibleForTesting
+        Intent mCurrentIntent;
 
         @Override
         public Instrumentation.ActivityResult onStartActivity(@NonNull Context who,
@@ -1564,11 +1575,29 @@
                     // the dedicated container.
                     options.putBinder(ActivityOptions.KEY_LAUNCH_TASK_FRAGMENT_TOKEN,
                             launchedInTaskFragment.getTaskFragmentToken());
+                    mCurrentIntent = intent;
                 }
             }
 
             return super.onStartActivity(who, intent, options);
         }
+
+        @Override
+        public void onStartActivityResult(int result, @NonNull Bundle bOptions) {
+            super.onStartActivityResult(result, bOptions);
+            if (mCurrentIntent != null && result != START_SUCCESS) {
+                // Clear the pending appeared intent if the activity was not started successfully.
+                final IBinder token = bOptions.getBinder(
+                        ActivityOptions.KEY_LAUNCH_TASK_FRAGMENT_TOKEN);
+                if (token != null) {
+                    final TaskFragmentContainer container = getContainer(token);
+                    if (container != null) {
+                        container.clearPendingAppearedIntentIfNeeded(mCurrentIntent);
+                    }
+                }
+            }
+            mCurrentIntent = null;
+        }
     }
 
     /**
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
index abf32a2..a188e2b 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
@@ -198,6 +198,22 @@
         return mPendingAppearedIntent;
     }
 
+    void setPendingAppearedIntent(@Nullable Intent intent) {
+        mPendingAppearedIntent = intent;
+    }
+
+    /**
+     * Clears the pending appeared Intent if it is the same as given Intent. Otherwise, the
+     * pending appeared Intent is cleared when TaskFragmentInfo is set and is not empty (has
+     * running activities).
+     */
+    void clearPendingAppearedIntentIfNeeded(@NonNull Intent intent) {
+        if (mPendingAppearedIntent == null || mPendingAppearedIntent != intent) {
+            return;
+        }
+        mPendingAppearedIntent = null;
+    }
+
     boolean hasActivity(@NonNull IBinder token) {
         if (mInfo != null && mInfo.getActivities().contains(token)) {
             return true;
@@ -230,13 +246,18 @@
 
     void setInfo(@NonNull TaskFragmentInfo info) {
         if (!mIsFinished && mInfo == null && info.isEmpty()) {
-            // onTaskFragmentAppeared with empty info. We will remove the TaskFragment if it is
-            // still empty after timeout.
+            // onTaskFragmentAppeared with empty info. We will remove the TaskFragment if no
+            // pending appeared intent/activities. Otherwise, wait and removing the TaskFragment if
+            // it is still empty after timeout.
             mAppearEmptyTimeout = () -> {
                 mAppearEmptyTimeout = null;
                 mController.onTaskFragmentAppearEmptyTimeout(this);
             };
-            mController.getHandler().postDelayed(mAppearEmptyTimeout, APPEAR_EMPTY_TIMEOUT_MS);
+            if (mPendingAppearedIntent != null || !mPendingAppearedActivities.isEmpty()) {
+                mController.getHandler().postDelayed(mAppearEmptyTimeout, APPEAR_EMPTY_TIMEOUT_MS);
+            } else {
+                mAppearEmptyTimeout.run();
+            }
         } else if (mAppearEmptyTimeout != null && !info.isEmpty()) {
             mController.getHandler().removeCallbacks(mAppearEmptyTimeout);
             mAppearEmptyTimeout = null;
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
index 18086f5..6bfb16a 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
@@ -25,8 +25,7 @@
 
 import android.annotation.Nullable;
 import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.ActivityManager.AppTask;
+import android.app.ActivityClient;
 import android.app.Application;
 import android.app.WindowConfiguration;
 import android.content.Context;
@@ -34,7 +33,6 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.util.ArrayMap;
-import android.util.Log;
 
 import androidx.annotation.NonNull;
 import androidx.window.common.CommonFoldingFeature;
@@ -179,57 +177,49 @@
     private List<DisplayFeature> getDisplayFeatures(
             @NonNull Activity activity, List<CommonFoldingFeature> storedFeatures) {
         List<DisplayFeature> features = new ArrayList<>();
-        int displayId = activity.getDisplay().getDisplayId();
-        if (displayId != DEFAULT_DISPLAY) {
-            Log.w(TAG, "This sample doesn't support display features on secondary displays");
-            return features;
-        } else if (isTaskInMultiWindowMode(activity)) {
-            // It is recommended not to report any display features in multi-window mode, since it
-            // won't be possible to synchronize the display feature positions with window movement.
-            return features;
-        } else {
-            for (CommonFoldingFeature baseFeature : storedFeatures) {
-                Integer state = convertToExtensionState(baseFeature.getState());
-                if (state == null) {
-                    continue;
-                }
-                Rect featureRect = baseFeature.getRect();
-                rotateRectToDisplayRotation(displayId, featureRect);
-                transformToWindowSpaceRect(activity, featureRect);
-
-                if (!isRectZero(featureRect)) {
-                    // TODO(b/228641877) Remove guarding if when fixed.
-                    features.add(new FoldingFeature(featureRect, baseFeature.getType(), state));
-                }
-            }
+        if (!shouldReportDisplayFeatures(activity)) {
             return features;
         }
+
+        int displayId = activity.getDisplay().getDisplayId();
+        for (CommonFoldingFeature baseFeature : storedFeatures) {
+            Integer state = convertToExtensionState(baseFeature.getState());
+            if (state == null) {
+                continue;
+            }
+            Rect featureRect = baseFeature.getRect();
+            rotateRectToDisplayRotation(displayId, featureRect);
+            transformToWindowSpaceRect(activity, featureRect);
+
+            if (!isRectZero(featureRect)) {
+                // TODO(b/228641877): Remove guarding when fixed.
+                features.add(new FoldingFeature(featureRect, baseFeature.getType(), state));
+            }
+        }
+        return features;
     }
 
     /**
-     * Checks whether the task associated with the activity is in multi-window. If task info is not
-     * available it defaults to {@code true}.
+     * Checks whether display features should be reported for the activity.
+     * TODO(b/238948678): Support reporting display features in all windowing modes.
      */
-    private boolean isTaskInMultiWindowMode(@NonNull Activity activity) {
-        final ActivityManager am = activity.getSystemService(ActivityManager.class);
-        if (am == null) {
-            return true;
+    private boolean shouldReportDisplayFeatures(@NonNull Activity activity) {
+        int displayId = activity.getDisplay().getDisplayId();
+        if (displayId != DEFAULT_DISPLAY) {
+            // Display features are not supported on secondary displays.
+            return false;
         }
-
-        final List<AppTask> appTasks = am.getAppTasks();
-        final int taskId = activity.getTaskId();
-        AppTask task = null;
-        for (AppTask t : appTasks) {
-            if (t.getTaskInfo().taskId == taskId) {
-                task = t;
-                break;
-            }
+        final int taskWindowingMode = ActivityClient.getInstance().getTaskWindowingMode(
+                activity.getActivityToken());
+        if (taskWindowingMode == -1) {
+            // If we cannot determine the task windowing mode for any reason, it is likely that we
+            // won't be able to determine its position correctly as well. DisplayFeatures' bounds
+            // in this case can't be computed correctly, so we should skip.
+            return false;
         }
-        if (task == null) {
-            // The task might be removed on the server already.
-            return true;
-        }
-        return WindowConfiguration.inMultiWindowMode(task.getTaskInfo().getWindowingMode());
+        // It is recommended not to report any display features in multi-window mode, since it
+        // won't be possible to synchronize the display feature positions with window movement.
+        return !WindowConfiguration.inMultiWindowMode(taskWindowingMode);
     }
 
     /**
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
index 042547f..4bc5033 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
@@ -16,6 +16,7 @@
 
 package androidx.window.extensions.embedding;
 
+import static android.app.ActivityManager.START_CANCELED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 
@@ -293,6 +294,26 @@
     }
 
     @Test
+    public void testOnStartActivityResultError() {
+        final Intent intent = new Intent();
+        final TaskContainer taskContainer = new TaskContainer(TASK_ID);
+        final TaskFragmentContainer container = new TaskFragmentContainer(null /* activity */,
+                intent, taskContainer, mSplitController);
+        final SplitController.ActivityStartMonitor monitor =
+                mSplitController.getActivityStartMonitor();
+
+        container.setPendingAppearedIntent(intent);
+        final Bundle bundle = new Bundle();
+        bundle.putBinder(ActivityOptions.KEY_LAUNCH_TASK_FRAGMENT_TOKEN,
+                container.getTaskFragmentToken());
+        monitor.mCurrentIntent = intent;
+        doReturn(container).when(mSplitController).getContainer(any());
+
+        monitor.onStartActivityResult(START_CANCELED, bundle);
+        assertNull(container.getPendingAppearedIntent());
+    }
+
+    @Test
     public void testOnActivityCreated() {
         mSplitController.onActivityCreated(mActivity);
 
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java
index 28c2773..44c7e6c 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java
@@ -209,21 +209,21 @@
 
         assertNull(container.mAppearEmptyTimeout);
 
-        // Not set if it is not appeared empty.
-        final TaskFragmentInfo info = mock(TaskFragmentInfo.class);
-        doReturn(new ArrayList<>()).when(info).getActivities();
-        doReturn(false).when(info).isEmpty();
-        container.setInfo(info);
-
-        assertNull(container.mAppearEmptyTimeout);
-
         // Set timeout if the first info set is empty.
+        final TaskFragmentInfo info = mock(TaskFragmentInfo.class);
         container.mInfo = null;
         doReturn(true).when(info).isEmpty();
         container.setInfo(info);
 
         assertNotNull(container.mAppearEmptyTimeout);
 
+        // Not set if it is not appeared empty.
+        doReturn(new ArrayList<>()).when(info).getActivities();
+        doReturn(false).when(info).isEmpty();
+        container.setInfo(info);
+
+        assertNull(container.mAppearEmptyTimeout);
+
         // Remove timeout after the container becomes non-empty.
         doReturn(false).when(info).isEmpty();
         container.setInfo(info);
@@ -232,6 +232,7 @@
 
         // Running the timeout will call into SplitController.onTaskFragmentAppearEmptyTimeout.
         container.mInfo = null;
+        container.setPendingAppearedIntent(mIntent);
         doReturn(true).when(info).isEmpty();
         container.setInfo(info);
         container.mAppearEmptyTimeout.run();
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index e7bc74a..6959a59 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Borrel"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Bestuur"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Borrel is toegemaak."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Tik om hierdie program te herbegin en maak volskerm oop."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Tik om hierdie program te herbegin vir ’n beter aansig."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kamerakwessies?\nTik om aan te pas"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nie opgelos nie?\nTik om terug te stel"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Geen kamerakwessies nie? Tik om toe te maak."</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index 8b2a892..fe22b2c 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"አረፋ"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"ያቀናብሩ"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"አረፋ ተሰናብቷል።"</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"ይህን መተግበሪያ ዳግም ለማስነሳት መታ ያድርጉ እና ወደ ሙሉ ማያ ገጽ ይሂዱ።"</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"ለተሻለ ዕይታ ይህን መተግበሪያ ዳግም ለማስነሳት መታ ያድርጉ።"</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"የካሜራ ችግሮች አሉ?\nዳግም ለማበጀት መታ ያድርጉ"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"አልተስተካከለም?\nለማህደር መታ ያድርጉ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ምንም የካሜራ ችግሮች የሉም? ለማሰናበት መታ ያድርጉ።"</string>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index 2afce7f..2be6f39 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"فقاعة"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"إدارة"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"تم إغلاق الفقاعة."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"انقر لإعادة تشغيل هذا التطبيق والانتقال إلى وضع ملء الشاشة."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"انقر لإعادة تشغيل هذا التطبيق للحصول على عرض أفضل."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"هل هناك مشاكل في الكاميرا؟\nانقر لإعادة الضبط."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ألم يتم حل المشكلة؟\nانقر للعودة"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"أليس هناك مشاكل في الكاميرا؟ انقر للإغلاق."</string>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index df97575..098ee84 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"বাবল"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"পৰিচালনা কৰক"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"বাবল অগ্ৰাহ্য কৰা হৈছে"</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"এপ্‌টো ৰিষ্টাৰ্ট কৰিবলৈ আৰু পূৰ্ণ স্ক্ৰীন ব্যৱহাৰ কৰিবলৈ টিপক।"</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"উন্নত ভিউৰ বাবে এপ্‌টো ৰিষ্টাৰ্ট কৰিবলৈ টিপক।"</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"কেমেৰাৰ কোনো সমস্যা হৈছে নেকি?\nপুনৰ খাপ খোৱাবলৈ টিপক"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"এইটো সমাধান কৰা নাই নেকি?\nপূৰ্বাৱস্থালৈ নিবলৈ টিপক"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"কেমেৰাৰ কোনো সমস্যা নাই নেকি? অগ্ৰাহ্য কৰিবলৈ টিপক।"</string>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index 892be93..2f49ae6 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Qabarcıq"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"İdarə edin"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Qabarcıqdan imtina edilib."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Bu tətbiqi sıfırlayaraq tam ekrana keçmək üçün toxunun."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Toxunaraq bu tətbiqi yenidən başladın ki, daha görüntü əldə edəsiniz."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kamera problemi var?\nBərpa etmək üçün toxunun"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Düzəltməmisiniz?\nGeri qaytarmaq üçün toxunun"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kamera problemi yoxdur? Qapatmaq üçün toxunun."</string>
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
index b34920e..0656fe1 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljajte"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić je odbačen."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Dodirnite da biste restartovali aplikaciju i prešli u režim celog ekrana."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Dodirnite da biste restartovali ovu aplikaciju radi boljeg prikaza."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Imate problema sa kamerom?\nDodirnite da biste ponovo uklopili"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problem nije rešen?\nDodirnite da biste vratili"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemate problema sa kamerom? Dodirnite da biste odbacili."</string>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index 525e46f..702f0ab 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Усплывальнае апавяшчэнне"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Кіраваць"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Усплывальнае апавяшчэнне адхілена."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Націсніце, каб перазапусціць гэту праграму і перайсці ў поўнаэкранны рэжым."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Націсніце, каб перазапусціць гэту праграму для лепшага прагляду."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Праблемы з камерай?\nНацісніце, каб пераабсталяваць"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Не ўдалося выправіць?\nНацісніце, каб аднавіць"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ніякіх праблем з камерай? Націсніце, каб адхіліць."</string>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index e27ec8e..0de16d3 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Балонче"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Управление"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Балончето е отхвърлено."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Докоснете, за да рестартирате това приложение в режим на цял екран."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Докоснете, за да рестартирате това приложение с цел по-добър изглед."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Имате проблеми с камерата?\nДокоснете за ремонтиране"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Проблемът не се отстрани?\nДокоснете за връщане в предишното състояние"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Нямате проблеми с камерата? Докоснете, за да отхвърлите."</string>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index 0a8b0b7..9a48d18 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"বাবল"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"ম্যানেজ করুন"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"বাবল বাতিল করা হয়েছে।"</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"এই অ্যাপ রিস্টার্ট করতে ট্যাপ করুন ও \'ফুল-স্ক্রিন\' মোড ব্যবহার করুন।"</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"আরও ভাল ভিউয়ের জন্য এই অ্যাপ রিস্টার্ট করতে ট্যাপ করুন।"</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ক্যামেরা সংক্রান্ত সমস্যা?\nরিফিট করতে ট্যাপ করুন"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"এখনও সমাধান হয়নি?\nরিভার্ট করার জন্য ট্যাপ করুন"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ক্যামেরা সংক্রান্ত সমস্যা নেই? বাতিল করতে ট্যাপ করুন।"</string>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index aadbfa4..31e906d 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljaj"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić je odbačen."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Dodirnite da ponovo pokrenete ovu aplikaciju i aktivirate prikaz preko cijelog ekrana."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Dodirnite da ponovo pokrenete ovu aplikaciju radi boljeg prikaza."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemi s kamerom?\nDodirnite da ponovo namjestite"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nije popravljeno?\nDodirnite da vratite"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nema problema s kamerom? Dodirnite da odbacite."</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index ab67246..ca0a421 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Bombolla"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestiona"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"La bombolla s\'ha ignorat."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Toca per reiniciar aquesta aplicació i passar a pantalla completa."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Toca per reiniciar aquesta aplicació i obtenir una millor visualització."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Tens problemes amb la càmera?\nToca per resoldre\'ls"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"El problema no s\'ha resolt?\nToca per desfer els canvis"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No tens cap problema amb la càmera? Toca per ignorar."</string>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index d7b1a38..e8772fe 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Bublina"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Spravovat"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bublina byla zavřena."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Klepnutím aplikaci restartujete a přejdete na režim celé obrazovky"</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Klepnutím tuto aplikaci kvůli lepšímu zobrazení restartujete."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problémy s fotoaparátem?\nKlepnutím vyřešíte"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nepomohlo to?\nKlepnutím se vrátíte"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Žádné problémy s fotoaparátem? Klepnutím zavřete."</string>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index c0acc08..2b55d4d 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Boble"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Administrer"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Boblen blev lukket."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Tryk for at genstarte denne app, og gå til fuld skærm."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Tryk for at genstarte denne app, så visningen forbedres."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Har du problemer med dit kamera?\nTryk for at gendanne det oprindelige format"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Løste det ikke problemet?\nTryk for at fortryde"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Har du ingen problemer med dit kamera? Tryk for at afvise."</string>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index e06bebd..03eee02 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Verwalten"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble verworfen."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Tippe, um die App im Vollbildmodus neu zu starten."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Tippe, um diese App neu zu starten und die Ansicht zu verbessern."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Probleme mit der Kamera?\nZum Anpassen tippen."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Das Problem ist nicht behoben?\nZum Rückgängigmachen tippen."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Keine Probleme mit der Kamera? Zum Schließen tippen."</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index 0d9d3ea..49bfdf1 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Συννεφάκι"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Διαχείριση"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Το συννεφάκι παραβλέφθηκε."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Πατήστε για επανεκκίνηση αυτής της εφαρμογής και ενεργοποίηση πλήρους οθόνης."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Πατήστε για να επανεκκινήσετε αυτή την εφαρμογή για καλύτερη προβολή."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Προβλήματα με την κάμερα;\nΠατήστε για επιδιόρθωση."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Δεν διορθώθηκε;\nΠατήστε για επαναφορά."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Δεν αντιμετωπίζετε προβλήματα με την κάμερα; Πατήστε για παράβλεψη."</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index 48525cd..081a01a 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Tap to restart this app for a better view."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index 48525cd..081a01a 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Tap to restart this app for a better view."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index 48525cd..081a01a 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Tap to restart this app for a better view."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index 48525cd..081a01a 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Tap to restart this app for a better view."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
index fb6db5f..afc14b8 100644
--- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‏‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‎‏‎‎Bubble‎‏‎‎‏‎"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‎‎‎‏‎‏‏‎‎‎‏‏‏‎‏‎‎‎‎‏‎‎‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‎‎‏‎‏‎‎‏‏‏‎‎‏‏‎Manage‎‏‎‎‏‎"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‏‎‏‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‏‏‏‏‎‏‎Bubble dismissed.‎‏‎‎‏‎"</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‏‎‎‏‏‏‎‏‏‏‏‎‏‏‏‎Tap to restart this app and go full screen.‎‏‎‎‏‎"</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‏‎‎‎‏‎‏‎‎‎‏‎‎‎‏‏‎‎‏‏‎‏‎‏‏‏‏‎‎‎‏‎‏‎‏‏‎‏‎‏‏‎‏‏‎‎Tap to restart this app for a better view.‎‏‎‎‏‎"</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‏‎‏‏‎‎‎‏‏‎‎‎‎‎‎‎‎‏‏‏‏‏‏‎‎‎‎‏‎‏‏‏‎‏‏‏‏‎‏‏‏‏‏‎Camera issues?‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Tap to refit‎‏‎‎‏‎"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‏‎‎‎‎‏‏‎‎‏‎Didn’t fix it?‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Tap to revert‎‏‎‎‏‎"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‎‏‎‎‎‎‏‎‎‏‎‎‏‎‎‎‏‎‎‏‏‎‎‏‏‎‎‎‎‎‏‏‎‎‎‏‏‏‏‎‎‏‎‎‏‏‏‎No camera issues? Tap to dismiss.‎‏‎‎‏‎"</string>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index 3db353a..b376b78 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Cuadro"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Administrar"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Se descartó el cuadro."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Presiona para reiniciar esta app y acceder al modo de pantalla completa."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Presiona para reiniciar esta app y tener una mejor vista."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"¿Tienes problemas con la cámara?\nPresiona para reajustarla"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"¿No se resolvió?\nPresiona para revertir los cambios"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"¿No tienes problemas con la cámara? Presionar para descartar."</string>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index c249328..79c1f90 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Burbuja"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestionar"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Burbuja cerrada."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Toca para reiniciar esta aplicación e ir a la pantalla completa."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Toca para reiniciar esta aplicación y obtener una mejor vista."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"¿Problemas con la cámara?\nToca para reajustar"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"¿No se ha solucionado?\nToca para revertir"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"¿No hay problemas con la cámara? Toca para cerrar."</string>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index 0133336e..a7fead6 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Mull"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Halda"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Mullist loobuti."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Puudutage rakenduse taaskäivitamiseks ja täisekraanrežiimi aktiveerimiseks."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Puudutage, et see rakendus parema vaate jaoks taaskäivitada."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kas teil on kaameraprobleeme?\nPuudutage ümberpaigutamiseks."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Kas probleemi ei lahendatud?\nPuudutage ennistamiseks."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kas kaameraprobleeme pole? Puudutage loobumiseks."</string>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index 71ccad5..e7530c9 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Burbuila"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Kudeatu"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Baztertu da globoa."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Saka ezazu aplikazioa berrabiarazteko, eta ezarri pantaila osoko modua."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Hobeto ikusteko, sakatu hau aplikazioa berrabiarazteko."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Arazoak dauzkazu kamerarekin?\nBerriro doitzeko, sakatu hau."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Ez al da konpondu?\nLeheneratzeko, sakatu hau."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ez daukazu arazorik kamerarekin? Baztertzeko, sakatu hau."</string>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index 20045ef..66a657e 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"حباب"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"مدیریت"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"حبابک رد شد."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"برای بازراه‌اندازی این برنامه و تغییر به حالت تمام‌صفحه، ضربه بزنید."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"برای داشتن نمایی بهتر، ضربه بزنید تا این برنامه بازراه‌اندازی شود."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"دوربین مشکل دارد؟\nبرای تنظیم مجدد اندازه ضربه بزنید"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"مشکل برطرف نشد؟\nبرای برگرداندن ضربه بزنید"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"دوربین مشکلی ندارد؟ برای بستن ضربه بزنید."</string>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index 2cd265e..eaf369a 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Kupla"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Ylläpidä"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Kupla ohitettu."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Napauta, niin sovellus käynnistyy uudelleen ja siirtyy koko näytön tilaan."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Napauta, niin sovellus käynnistyy uudelleen paremmin näytölle sopivana."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Onko kameran kanssa ongelmia?\nKorjaa napauttamalla"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Eikö ongelma ratkennut?\nKumoa napauttamalla"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ei ongelmia kameran kanssa? Hylkää napauttamalla."</string>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index eb25a8d..8f614c5 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Bulle"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Gérer"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulle ignorée."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Touchez pour redémarrer cette application et passer en plein écran."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Touchez pour redémarrer cette application afin d\'obtenir un meilleur affichage."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problèmes d\'appareil photo?\nTouchez pour réajuster"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problème non résolu?\nTouchez pour rétablir"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Aucun problème d\'appareil photo? Touchez pour ignorer."</string>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index 53358b7..ec3e1b3 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Bulle"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Gérer"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulle fermée."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Appuyez pour redémarrer cette application et activer le mode plein écran."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Appuyez pour redémarrer cette appli et avoir une meilleure vue."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problèmes d\'appareil photo ?\nAppuyez pour réajuster"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problème non résolu ?\nAppuyez pour rétablir"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Aucun problème d\'appareil photo ? Appuyez pour ignorer."</string>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index 09977a1..651353d 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Burbulla"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Xestionar"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ignorouse a burbulla."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Toca o botón para reiniciar esta aplicación e abrila en pantalla completa."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Toca o botón para reiniciar esta aplicación e gozar dunha mellor visualización."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Tes problemas coa cámara?\nToca para reaxustala"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Non se solucionaron os problemas?\nToca para reverter o seu tratamento"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Non hai problemas coa cámara? Tocar para ignorar."</string>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index 8e9f086..3543be0b 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"બબલ"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"મેનેજ કરો"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"બબલ છોડી દેવાયો."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"આ ઍપ ફરીથી ચાલુ કરવા માટે ટૅપ કરીને પૂર્ણ સ્ક્રીન કરો."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"વધુ સારા વ્યૂ માટે, આ ઍપને ફરી શરૂ કરવા ટૅપ કરો."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"કૅમેરામાં સમસ્યાઓ છે?\nફરીથી ફિટ કરવા માટે ટૅપ કરો"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"સુધારો નથી થયો?\nપહેલાંના પર પાછું ફેરવવા માટે ટૅપ કરો"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"કૅમેરામાં કોઈ સમસ્યા નથી? છોડી દેવા માટે ટૅપ કરો."</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index 3d83005..87ac5d6 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"मैनेज करें"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल खारिज किया गया."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"इस ऐप्लिकेशन को रीस्टार्ट करने और फ़ुल स्क्रीन पर देखने के लिए टैप करें."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"टैप करके ऐप्लिकेशन को रीस्टार्ट करें और बेहतर व्यू पाएं."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"क्या कैमरे से जुड़ी कोई समस्या है?\nफिर से फ़िट करने के लिए टैप करें"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"क्या समस्या ठीक नहीं हुई?\nपहले जैसा करने के लिए टैप करें"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"क्या कैमरे से जुड़ी कोई समस्या नहीं है? खारिज करने के लिए टैप करें."</string>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index 1c4116d..cb4f424 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljanje"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić odbačen."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Dodirnite da biste ponovo pokrenuli tu aplikaciju i prikazali je na cijelom zaslonu."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Dodirnite da biste ponovo pokrenuli tu aplikaciju kako biste bolje vidjeli."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemi s fotoaparatom?\nDodirnite za popravak"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problem nije riješen?\nDodirnite za vraćanje"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemate problema s fotoaparatom? Dodirnite za odbacivanje."</string>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index d749775..635f4da 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Buborék"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Kezelés"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Buborék elvetve."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Koppintson az alkalmazás újraindításához és a teljes képernyős mód elindításához."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"A jobb nézet érdekében koppintson az alkalmazás újraindításához."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kamerával kapcsolatos problémába ütközött?\nKoppintson a megoldáshoz."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nem sikerült a hiba kijavítása?\nKoppintson a visszaállításhoz."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nincsenek problémái kamerával? Koppintson az elvetéshez."</string>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index 160651c..da382c1 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Պղպջակ"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Կառավարել"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ամպիկը փակվեց։"</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Հպեք՝ հավելվածը վերագործարկելու և լիաէկրան ռեժիմին անցնելու համար։"</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Հպեք՝ հավելվածը վերագործարկելու և ավելի հարմար տեսք ընտրելու համար։"</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Տեսախցիկի հետ կապված խնդիրնե՞ր կան։\nՀպեք՝ վերակարգավորելու համար։"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Չհաջողվե՞ց շտկել։\nՀպեք՝ փոփոխությունները չեղարկելու համար։"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Տեսախցիկի հետ կապված խնդիրներ չկա՞ն։ Փակելու համար հպեք։"</string>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index fab3486..cd79539 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Balon"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Kelola"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balon ditutup."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Ketuk untuk memulai ulang aplikasi ini dan membuka layar penuh."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Ketuk untuk memulai ulang aplikasi ini agar mendapatkan tampilan yang lebih baik."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Masalah kamera?\nKetuk untuk memperbaiki"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Tidak dapat diperbaiki?\nKetuk untuk mengembalikan"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Tidak ada masalah kamera? Ketuk untuk menutup."</string>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index c22b881..37141b7 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Blaðra"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Stjórna"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Blöðru lokað."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Ýttu til að endurræsa forritið og sýna það á öllum skjánum."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Ýta til að endurræsa forritið og fá betri sýn."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Myndavélavesen?\nÝttu til að breyta stærð"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Ennþá vesen?\nÝttu til að afturkalla"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ekkert myndavélavesen? Ýttu til að hunsa."</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index 7ec13c4..b63e764 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -72,7 +72,8 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Fumetto"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestisci"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Fumetto ignorato."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Tocca per riavviare l\'app e passare alla modalità a schermo intero."</string>
+    <!-- no translation found for restart_button_description (6712141648865547958) -->
+    <skip />
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemi con la fotocamera?\nTocca per risolverli"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Il problema non si è risolto?\nTocca per ripristinare"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nessun problema con la fotocamera? Tocca per ignorare."</string>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index 8625a2a..0e500ea 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"בועה"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"ניהול"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"הבועה נסגרה."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"צריך להקיש כדי להפעיל מחדש את האפליקציה הזו ולעבור למסך מלא."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"כדי לראות טוב יותר יש להקיש ולהפעיל את האפליקציה הזו מחדש."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"בעיות במצלמה?\nאפשר להקיש כדי לבצע התאמה מחדש"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"הבעיה לא נפתרה?\nאפשר להקיש כדי לחזור לגרסה הקודמת"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"אין בעיות במצלמה? אפשר להקיש כדי לסגור."</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index 4d09b20..34ed9c7 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"バブル"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ふきだしが非表示になっています。"</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"タップしてこのアプリを再起動すると、全画面表示になります。"</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"タップしてこのアプリを再起動すると、表示が適切になります。"</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"カメラに関する問題の場合は、\nタップすると修正できます"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"修正されなかった場合は、\nタップすると元に戻ります"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"カメラに関する問題でない場合は、タップすると閉じます。"</string>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index 8cbc3d8..14b26c1 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"ბუშტი"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"მართვა"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ბუშტი დაიხურა."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"შეეხეთ ამ აპის გადასატვირთად და გადადით სრულ ეკრანზე."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"შეეხეთ, რომ გადატვირთოთ ეს აპი უკეთესი ხედისთვის."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"კამერად პრობლემები აქვს?\nშეეხეთ გამოსასწორებლად"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"არ გამოსწორდა?\nშეეხეთ წინა ვერსიის დასაბრუნებლად"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"კამერას პრობლემები არ აქვს? შეეხეთ უარყოფისთვის."</string>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index 22cf08b..c42efdc 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Көпіршік"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Басқару"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Қалқыма хабар жабылды."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Бұл қолданбаны қайта қосып, толық экранға өту үшін түртіңіз."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Ыңғайлы көріністі реттеу үшін қолданбаны түртіп, өшіріп қосыңыз."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Камерада қателер шықты ма?\nЖөндеу үшін түртіңіз."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Жөнделмеді ме?\nҚайтару үшін түртіңіз."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Камерада қателер шықпады ма? Жабу үшін түртіңіз."</string>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index 1e72d4f..302b25e 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"ពពុះ"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"គ្រប់គ្រង"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"បានច្រានចោល​សារលេចឡើង។"</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"ចុចដើម្បី​ចាប់ផ្ដើម​កម្មវិធី​នេះឡើងវិញ រួចចូលប្រើ​ពេញអេក្រង់។"</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"ចុចដើម្បី​ចាប់ផ្ដើម​កម្មវិធី​នេះឡើងវិញសម្រាប់ទិដ្ឋភាពកាន់តែប្រសើរ។"</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"មានបញ្ហា​ពាក់ព័ន្ធនឹង​កាមេរ៉ាឬ?\nចុចដើម្បី​ដោះស្រាយ"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"មិនបាន​ដោះស្រាយ​បញ្ហានេះទេឬ?\nចុចដើម្បី​ត្រឡប់"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"មិនមាន​បញ្ហាពាក់ព័ន្ធនឹង​កាមេរ៉ាទេឬ? ចុចដើម្បី​ច្រានចោល។"</string>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index 24d0c82..2b3aa07 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"ಬಬಲ್"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"ನಿರ್ವಹಿಸಿ"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ಬಬಲ್ ವಜಾಗೊಳಿಸಲಾಗಿದೆ."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"ಈ ಆ್ಯಪ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಲು ಮತ್ತು ಪೂರ್ಣ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿ ನೋಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"ಉತ್ತಮ ವೀಕ್ಷಣೆಗಾಗಿ ಈ ಆ್ಯಪ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ಕ್ಯಾಮರಾ ಸಮಸ್ಯೆಗಳಿವೆಯೇ?\nಮರುಹೊಂದಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ಅದನ್ನು ಸರಿಪಡಿಸಲಿಲ್ಲವೇ?\nಹಿಂತಿರುಗಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ಕ್ಯಾಮರಾ ಸಮಸ್ಯೆಗಳಿಲ್ಲವೇ? ವಜಾಗೊಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index 15e8a90..5505955 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"버블"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"관리"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"대화창을 닫았습니다."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"탭하여 이 앱을 다시 시작하고 전체 화면으로 이동합니다."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"보기를 개선하려면 탭하여 앱을 다시 시작합니다."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"카메라 문제가 있나요?\n해결하려면 탭하세요."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"해결되지 않았나요?\n되돌리려면 탭하세요."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"카메라에 문제가 없나요? 닫으려면 탭하세요."</string>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index 94ea9fb..d45a984 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Көбүк"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Башкаруу"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Калкып чыкма билдирме жабылды."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Бул колдонмону өчүрүп күйгүзүп, толук экранга өтүү үчүн таптап коюңуз."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Жакшыраак көрүү үчүн бул колдонмону өчүрүп күйгүзүңүз. Ал үчүн таптап коюңуз."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Камерада маселелер келип чыктыбы?\nОңдоо үчүн таптаңыз"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Оңдолгон жокпу?\nАртка кайтаруу үчүн таптаңыз"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Камерада маселе жокпу? Этибарга албоо үчүн таптаңыз."</string>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index be72d8e..0eeee90 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"ຟອງ"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"ຈັດການ"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ປິດ Bubble ໄສ້ແລ້ວ."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"ແຕະເພື່ອຣີສະຕາດແອັບນີ້ ແລະ ໃຊ້ແບບເຕັມຈໍ."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"ແຕະເພື່ອຣີສະຕາດແອັບນີ້ເພື່ອມຸມມອງທີ່ດີຂຶ້ນ."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ມີບັນຫາກ້ອງຖ່າຍຮູບບໍ?\nແຕະເພື່ອປັບໃໝ່"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ບໍ່ໄດ້ແກ້ໄຂມັນບໍ?\nແຕະເພື່ອແປງກັບຄືນ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ບໍ່ມີບັນຫາກ້ອງຖ່າຍຮູບບໍ? ແຕະເພື່ອ​ປິດ​ໄວ້."</string>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index 3fa163b..fc118e2 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Debesėlis"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Tvarkyti"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Debesėlio atsisakyta."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Palieskite, kad paleistumėte iš naujo šią programą ir įjungtumėte viso ekrano režimą."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Palieskite, kad iš naujo paleistumėte šią programą ir matytumėte aiškiau."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Iškilo problemų dėl kameros?\nPalieskite, kad pritaikytumėte iš naujo"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nepavyko pataisyti?\nPalieskite, kad grąžintumėte"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nėra jokių problemų dėl kameros? Palieskite, kad atsisakytumėte."</string>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index 90cd4be..cd2af07 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Burbulis"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Pārvaldīt"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Burbulis ir noraidīts."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Pieskarieties, lai restartētu šo lietotni un pārietu pilnekrāna režīmā."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Pieskarieties, lai restartētu šo lietotni un uzlabotu attēlojumu."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Vai ir problēmas ar kameru?\nPieskarieties, lai tās novērstu."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Vai problēma netika novērsta?\nPieskarieties, lai atjaunotu."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Vai nav problēmu ar kameru? Pieskarieties, lai nerādītu."</string>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index 56e9b40..c0dff00 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Балонче"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Управувајте"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Балончето е отфрлено."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Допрете за да ја рестартирате апликацијава и да ја отворите на цел екран."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Допрете за да ја рестартирате апликацијава за подобар приказ."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Проблеми со камерата?\nДопрете за да се совпадне повторно"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Не се поправи?\nДопрете за враќање"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Нема проблеми со камерата? Допрете за отфрлање."</string>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index 88e49e7..52ea1c7 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"ബബിൾ"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"മാനേജ് ചെയ്യുക"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ബബിൾ ഡിസ്മിസ് ചെയ്തു."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"ഈ ആപ്പ് റീസ്‌റ്റാർട്ട് ചെയ്‌ത് പൂർണ്ണ സ്ക്രീനിലേക്ക് മാറാൻ ടാപ്പ് ചെയ്യുക."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"മികച്ച കാഴ്‌ചയ്‌ക്കായി ഈ ആപ്പ് റീസ്‌റ്റാർട്ട് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ക്യാമറ പ്രശ്നങ്ങളുണ്ടോ?\nശരിയാക്കാൻ ടാപ്പ് ചെയ്യുക"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"അത് പരിഹരിച്ചില്ലേ?\nപുനഃസ്ഥാപിക്കാൻ ടാപ്പ് ചെയ്യുക"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ക്യാമറാ പ്രശ്നങ്ങളൊന്നുമില്ലേ? നിരസിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index 7a6f625..fd4c4aa 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Бөмбөлөг"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Удирдах"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Бөмбөлгийг үл хэрэгссэн."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Энэ аппыг дахин эхлүүлж, бүтэн дэлгэцэд орохын тулд товшино уу."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Харагдах байдлыг сайжруулахын тулд энэ аппыг товшиж, дахин эхлүүлнэ үү."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Камерын асуудал гарсан уу?\nДахин тааруулахын тулд товшино уу"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Үүнийг засаагүй юу?\nБуцаахын тулд товшино уу"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Камерын асуудал байхгүй юу? Хаахын тулд товшино уу."</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index c2a9475..b9a165e 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"व्यवस्थापित करा"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल डिसमिस केला."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"हे अ‍ॅप रीस्टार्ट करण्यासाठी आणि फुल स्क्रीन करण्यासाठी टॅप करा."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"अधिक चांगल्या व्ह्यूसाठी हे अ‍ॅप रीस्टार्ट करण्याकरिता टॅप करा."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"कॅमेराशी संबंधित काही समस्या आहेत का?\nपुन्हा फिट करण्यासाठी टॅप करा"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"निराकरण झाले नाही?\nरिव्हर्ट करण्यासाठी कृपया टॅप करा"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"कॅमेराशी संबंधित कोणत्याही समस्या नाहीत का? डिसमिस करण्‍यासाठी टॅप करा."</string>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index 35512c1..3d81c9a 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Gelembung"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Urus"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Gelembung diketepikan."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Ketik untuk memulakan semula apl ini dan menggunakan skrin penuh."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Ketik untuk memulakan semula apl ini untuk mendapatkan paparan yang lebih baik."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Isu kamera?\nKetik untuk memuatkan semula"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Isu tidak dibetulkan?\nKetik untuk kembali"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Tiada isu kamera? Ketik untuk mengetepikan."</string>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index 5aea49f..50adfe9 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"ပူဖောင်းဖောက်သံ"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"စီမံရန်"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ပူဖောင်းကွက် ဖယ်လိုက်သည်။"</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"ဤအက်ပ်ကို ပြန်စပြီး ဖန်သားပြင်အပြည့်လုပ်ရန် တို့ပါ။"</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"ပိုကောင်းသောမြင်ကွင်းအတွက် ဤအက်ပ်ပြန်စရန် တို့နိုင်သည်။"</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ကင်မရာပြဿနာလား။\nပြင်ဆင်ရန် တို့ပါ"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ကောင်းမသွားဘူးလား။\nပြန်ပြောင်းရန် တို့ပါ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ကင်မရာပြဿနာ မရှိဘူးလား။ ပယ်ရန် တို့ပါ။"</string>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index 8e87bc10..74e066e 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Boble"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Administrer"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Boblen er avvist."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Trykk for å starte denne appen på nytt og vise den i fullskjerm."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Trykk for å starte denne appen på nytt for bedre visning."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Har du kameraproblemer?\nTrykk for å tilpasse"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Ble ikke problemet løst?\nTrykk for å gå tilbake"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Har du ingen kameraproblemer? Trykk for å lukke."</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index 831f6e2..b257f9e 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"व्यवस्थापन गर्नुहोस्"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल हटाइयो।"</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"यो एप रिस्टार्ट गर्न ट्याप गर्नुहोस् र फुल स्क्रिन मोडमा जानुहोस्।"</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"यो एप अझ राम्रो हेर्न मिल्ने बनाउनका लागि यसलाई रिस्टार्ट गर्न ट्याप गर्नुहोस्।"</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"क्यामेरासम्बन्धी समस्या देखियो?\nसमस्या हल गर्न ट्याप गर्नुहोस्"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"समस्या हल भएन?\nपहिलेको जस्तै बनाउन ट्याप गर्नुहोस्"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"क्यामेरासम्बन्धी कुनै पनि समस्या छैन? खारेज गर्न ट्याप गर्नुहोस्।"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index affdd0e..6ea24a8 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Bubbel"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Beheren"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubbel gesloten."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Tik om deze app opnieuw te starten en te openen op het volledige scherm."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Tik om deze app opnieuw op te starten voor een betere weergave."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Cameraproblemen?\nTik om opnieuw passend te maken."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Is dit geen oplossing?\nTik om terug te zetten."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Geen cameraproblemen? Tik om te sluiten."</string>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index f150cb9..f8c9248 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"ବବଲ୍"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"ପରିଚାଳନା କରନ୍ତୁ"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ବବଲ୍ ଖାରଜ କରାଯାଇଛି।"</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"ଏହି ଆପକୁ ରିଷ୍ଟାର୍ଟ କରି ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"ଏକ ଆହୁରି ଭଲ ଭ୍ୟୁ ପାଇଁ ଏହି ଆପ ରିଷ୍ଟାର୍ଟ କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"କ୍ୟାମେରାରେ ସମସ୍ୟା ଅଛି?\nପୁଣି ଫିଟ କରିବାକୁ ଟାପ କରନ୍ତୁ"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ଏହାର ସମାଧାନ ହୋଇନାହିଁ?\nଫେରିଯିବା ପାଇଁ ଟାପ କରନ୍ତୁ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"କ୍ୟାମେରାରେ କିଛି ସମସ୍ୟା ନାହିଁ? ଖାରଜ କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index 62587e5..b80da0b 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"ਬੁਲਬੁਲਾ"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ਬਬਲ ਨੂੰ ਖਾਰਜ ਕੀਤਾ ਗਿਆ।"</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"ਇਸ ਐਪ ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ ਅਤੇ ਪੂਰੀ ਸਕ੍ਰੀਨ ਮੋਡ \'ਤੇ ਜਾਓ।"</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"ਬਿਹਤਰ ਦ੍ਰਿਸ਼ ਲਈ ਇਸ ਐਪ ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ਕੀ ਕੈਮਰੇ ਸੰਬੰਧੀ ਸਮੱਸਿਆਵਾਂ ਹਨ?\nਮੁੜ-ਫਿੱਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ਕੀ ਇਹ ਠੀਕ ਨਹੀਂ ਹੋਈ?\nਵਾਪਸ ਉਹੀ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ਕੀ ਕੈਮਰੇ ਸੰਬੰਧੀ ਕੋਈ ਸਮੱਸਿਆ ਨਹੀਂ ਹੈ? ਖਾਰਜ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index 363c851..bdd44dd 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Dymek"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Zarządzaj"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Zamknięto dymek"</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Kliknij, by uruchomić tę aplikację ponownie i przejść w tryb pełnoekranowy."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Kliknij, aby zrestartować aplikację i zyskać lepszą widoczność."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemy z aparatem?\nKliknij, aby dopasować"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Naprawa się nie udała?\nKliknij, aby cofnąć"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Brak problemów z aparatem? Kliknij, aby zamknąć"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index f328b6c..b9e41ea 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Bolha"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Gerenciar"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão dispensado."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Toque para reiniciar o app e usar tela cheia."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Toque para reiniciar o app e atualizar a visualização."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemas com a câmera?\nToque para ajustar o enquadramento"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"O problema não foi corrigido?\nToque para reverter"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Não tem problemas com a câmera? Toque para dispensar."</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index 67369b8..c1e57d8 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Balão"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Gerir"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão ignorado."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Toque para reiniciar esta app e ficar em ecrã inteiro."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Toque para reiniciar esta app e ficar com uma melhor visão."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemas com a câmara?\nToque aqui para reajustar"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Não foi corrigido?\nToque para reverter"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nenhum problema com a câmara? Toque para ignorar."</string>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index f328b6c..b9e41ea 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Bolha"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Gerenciar"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão dispensado."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Toque para reiniciar o app e usar tela cheia."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Toque para reiniciar o app e atualizar a visualização."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemas com a câmera?\nToque para ajustar o enquadramento"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"O problema não foi corrigido?\nToque para reverter"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Não tem problemas com a câmera? Toque para dispensar."</string>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index 8da1d67..c49bf9d 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Balon"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestionați"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balonul a fost respins."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Atingeți ca să reporniți aplicația și să treceți în modul ecran complet."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Atingeți ca să reporniți aplicația pentru o vizualizare mai bună."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Aveți probleme cu camera foto?\nAtingeți pentru a reîncadra"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nu ați remediat problema?\nAtingeți pentru a reveni"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nu aveți probleme cu camera foto? Atingeți pentru a închide."</string>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index 49efac6..ffe031d 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Всплывающая подсказка"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Настроить"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Всплывающий чат закрыт."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Нажмите, чтобы перезапустить приложение и перейти в полноэкранный режим."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Нажмите, чтобы перезапустить приложение и настроить удобный для просмотра вид"</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Проблемы с камерой?\nНажмите, чтобы исправить."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Не помогло?\nНажмите, чтобы отменить изменения."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Нет проблем с камерой? Нажмите, чтобы закрыть."</string>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index 1f8cba8..b27e1b9 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"බුබුළු"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"කළමනා කරන්න"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"බුබුල ඉවත දමා ඇත."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"මෙම යෙදුම යළි ඇරඹීමට සහ පූර්ණ තිරයට යාමට තට්ටු කරන්න."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"වඩා හොඳ දසුනක් ලබා ගැනීම සඳහා මෙම යෙදුම යළි ඇරඹීමට තට්ටු කරන්න."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"කැමරා ගැටලුද?\nයළි සවි කිරීමට තට්ටු කරන්න"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"එය විසඳුවේ නැතිද?\nප්‍රතිවර්තනය කිරීමට තට්ටු කරන්න"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"කැමරා ගැටලු නොමැතිද? ඉවත දැමීමට තට්ටු කරන්න"</string>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index ca14dd7..b5bedf7 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Bublina"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Spravovať"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bublina bola zavretá."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Klepnutím reštartujete túto aplikáciu a prejdete do režimu celej obrazovky."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Ak chcete zlepšiť zobrazenie, klepnutím túto aplikáciu reštartujte."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problémy s kamerou?\nKlepnutím znova upravte."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nevyriešilo sa to?\nKlepnutím sa vráťte."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemáte problémy s kamerou? Klepnutím zatvoríte."</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index 626be8b..ac926b9 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Mehurček"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljanje"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblaček je bil opuščen."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Dotaknite se za vnovični zagon te aplikacije in preklop v celozaslonski način."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Če želite boljši prikaz, se dotaknite za vnovični zagon te aplikacije."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Težave s fotoaparatom?\nDotaknite se za vnovično prilagoditev"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"To ni odpravilo težave?\nDotaknite se za povrnitev"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nimate težav s fotoaparatom? Dotaknite se za opustitev."</string>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index 591f4b7..07c52fe 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Flluskë"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Menaxho"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Flluska u hoq."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Trokit për ta rinisur këtë aplikacion dhe për të kaluar në ekranin e plotë."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Trokit për të rifilluar këtë aplikacion për një pamje më të mirë."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Ka probleme me kamerën?\nTrokit për ta ripërshtatur"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nuk u rregullua?\nTrokit për ta rikthyer"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nuk ka probleme me kamerën? Trokit për ta shpërfillur."</string>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index fdd49b5..0289dd1 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Облачић"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Управљајте"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Облачић је одбачен."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Додирните да бисте рестартовали апликацију и прешли у режим целог екрана."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Додирните да бисте рестартовали ову апликацију ради бољег приказа."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Имате проблема са камером?\nДодирните да бисте поново уклопили"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Проблем није решен?\nДодирните да бисте вратили"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Немате проблема са камером? Додирните да бисте одбацили."</string>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index 54384ca..cfdb1dd 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Bubbla"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Hantera"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubblan ignorerades."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Tryck för att starta om appen i helskärmsläge."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Tryck för att starta om appen och få en bättre vy."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problem med kameran?\nTryck för att anpassa på nytt"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Löstes inte problemet?\nTryck för att återställa"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Inga problem med kameran? Tryck för att ignorera."</string>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index 2f7d224..383e9bb 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Kiputo"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Dhibiti"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Umeondoa kiputo."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Gusa ili uzime na uwashe programu hii, kisha nenda kwenye skrini nzima."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Gusa ili uzime kisha uwashe programu hii, ili upate mwonekano bora."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Je, kuna hitilafu za kamera?\nGusa ili urekebishe"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Umeshindwa kurekebisha?\nGusa ili urejeshe nakala ya awali"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Je, hakuna hitilafu za kamera? Gusa ili uondoe."</string>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index b626994..cc512f3 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"பபிள்"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"நிர்வகி"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"குமிழ் நிராகரிக்கப்பட்டது."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"தட்டுவதன் மூலம் இந்த ஆப்ஸை மீண்டும் தொடங்கலாம், முழுத்திரையில் பார்க்கலாம்."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"இங்கு தட்டுவதன் மூலம் இந்த ஆப்ஸை மீண்டும் தொடங்கி, ஆப்ஸ் காட்டப்படும் விதத்தை இன்னும் சிறப்பாக்கலாம்."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"கேமரா தொடர்பான சிக்கல்களா?\nமீண்டும் பொருத்த தட்டவும்"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"சிக்கல்கள் சரிசெய்யப்படவில்லையா?\nமாற்றியமைக்க தட்டவும்"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"கேமரா தொடர்பான சிக்கல்கள் எதுவும் இல்லையா? நிராகரிக்க தட்டவும்."</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index f080350..cdbe021 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"బబుల్"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"మేనేజ్ చేయండి"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"బబుల్ విస్మరించబడింది."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"ఈ యాప్‌ను రీస్టార్ట్ చేయడానికి ట్యాప్ చేసి, ఆపై పూర్తి స్క్రీన్‌లోకి వెళ్లండి."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"మెరుగైన వీక్షణ కోసం ఈ యాప్‌ను రీస్టార్ట్ చేయడానికి ట్యాప్ చేయండి."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"కెమెరా సమస్యలు ఉన్నాయా?\nరీఫిట్ చేయడానికి ట్యాప్ చేయండి"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"దాని సమస్యను పరిష్కరించలేదా?\nపూర్వస్థితికి మార్చడానికి ట్యాప్ చేయండి"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"కెమెరా సమస్యలు లేవా? తీసివేయడానికి ట్యాప్ చేయండి."</string>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index 0d1f23b..136a81c 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"บับเบิล"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"จัดการ"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ปิดบับเบิลแล้ว"</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"แตะเพื่อรีสตาร์ทแอปนี้และแสดงแบบเต็มหน้าจอ"</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"แตะเพื่อรีสตาร์ทแอปนี้และรับมุมมองที่ดียิ่งขึ้น"</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"หากพบปัญหากับกล้อง\nแตะเพื่อแก้ไข"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"หากไม่ได้แก้ไข\nแตะเพื่อเปลี่ยนกลับ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"หากไม่พบปัญหากับกล้อง แตะเพื่อปิด"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index bfae45af..4d32af3 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Pamahalaan"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Na-dismiss na ang bubble."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"I-tap para i-restart ang app na ito at mag-full screen."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"I-tap para i-restart ang app na ito para sa mas magandang view."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"May mga isyu sa camera?\nI-tap para i-refit"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Hindi ito naayos?\nI-tap para i-revert"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Walang isyu sa camera? I-tap para i-dismiss."</string>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index 6a9be80..f3ab370 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Baloncuk"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Yönet"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balon kapatıldı."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Bu uygulamayı yeniden başlatmak ve tam ekrana geçmek için dokunun."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Bu uygulamayı yeniden başlatarak daha iyi bir görünüm elde etmek için dokunun."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kameranızda sorun mu var?\nDüzeltmek için dokunun"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Bu işlem sorunu düzeltmedi mi?\nİşlemi geri almak için dokunun"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kameranızda sorun yok mu? Kapatmak için dokunun."</string>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index 52f6d11..d7d82cb 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Спливаюче сповіщення"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Налаштувати"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Спливаюче сповіщення закрито."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Натисніть, щоб перезапустити додаток і перейти в повноекранний режим."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Натисніть, щоб перезапустити цей додаток для зручнішого перегляду."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Проблеми з камерою?\nНатисніть, щоб пристосувати"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Проблему не вирішено?\nНатисніть, щоб скасувати зміни"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Немає проблем із камерою? Торкніться, щоб закрити."</string>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index 3abfb0d..4a8476a 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"بلبلہ"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"نظم کریں"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"بلبلہ برخاست کر دیا گیا۔"</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"یہ ایپ دوبارہ شروع کرنے کے لیے تھپتھپائیں اور پوری اسکرین پر جائیں۔"</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"بہتر منظر کے لیے اس ایپ کو ری اسٹارٹ کرنے کی خاطر تھپتھپائیں۔"</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"کیمرے کے مسائل؟\nدوبارہ فٹ کرنے کیلئے تھپتھپائیں"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"یہ حل نہیں ہوا؟\nلوٹانے کیلئے تھپتھپائیں"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"کوئی کیمرے کا مسئلہ نہیں ہے؟ برخاست کرنے کیلئے تھپتھپائیں۔"</string>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 0c0771f..8a4eac3 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Pufaklar"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Boshqarish"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulutcha yopildi."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Bu ilovani qaytadan ishga tushirish va butun ekranda ochish uchun bosing."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Yaxshiroq koʻrish maqsadida bu ilovani qayta ishga tushirish uchun bosing."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kamera nosozmi?\nQayta moslash uchun bosing"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Tuzatilmadimi?\nQaytarish uchun bosing"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kamera muammosizmi? Yopish uchun bosing."</string>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index 8b692a71..2f8fe60 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Bong bóng"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Quản lý"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Đã đóng bong bóng."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Nhấn để khởi động lại ứng dụng này và xem ở chế độ toàn màn hình."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Nhấn để khởi động lại ứng dụng này để xem tốt hơn."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Có vấn đề với máy ảnh?\nHãy nhấn để sửa lỗi"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Bạn chưa khắc phục vấn đề?\nHãy nhấn để hủy bỏ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Không có vấn đề với máy ảnh? Hãy nhấn để đóng."</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index 8fed6bf..ab44fb1 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"气泡"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"已关闭对话泡。"</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"点按即可重启此应用并进入全屏模式。"</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"点按即可重启此应用,获得更好的视图体验。"</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"相机有问题?\n点按即可整修"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"没有解决此问题?\n点按即可恢复"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"相机没有问题?点按即可忽略。"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index add3291..8fb7ade 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"氣泡"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"對話氣泡已關閉。"</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"輕按即可重新開啟此應用程式並放大至全螢幕。"</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"輕按並重新啟動此應用程式,以取得更佳的觀看體驗。"</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"相機有問題?\n輕按即可修正"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"未能修正問題?\n輕按即可還原"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"相機冇問題?㩒一下就可以即可閂咗佢。"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index f2c2a29..45de415 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"泡泡"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"已關閉泡泡。"</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"輕觸即可重新啟動這個應用程式並進入全螢幕模式。"</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"請輕觸並重新啟動此應用程式,取得更良好的觀看體驗。"</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"相機有問題嗎?\n輕觸即可修正"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"未修正問題嗎?\n輕觸即可還原"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"相機沒問題嗎?輕觸即可關閉。"</string>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index 94e5b9b..7c31a16 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -72,7 +72,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Ibhamuza"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Phatha"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ibhamuza licashisiwe."</string>
-    <string name="restart_button_description" msgid="5887656107651190519">"Thepha ukuze uqale kabusha lolu hlelo lokusebenza uphinde uye kusikrini esigcwele."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Thepha ukuze uqale kabusha le app ukuze ibonakale kangcono."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Izinkinga zekhamera?\nThepha ukuze uyilinganise kabusha"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Akuyilungisanga?\nThepha ukuze ubuyele"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Azikho izinkinga zekhamera? Thepha ukuze ucashise."</string>
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index 68a08513..2a38766 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -30,6 +30,9 @@
     <!-- Title of menu shown over picture-in-picture. Used for accessibility. -->
     <string name="pip_menu_title">Menu</string>
 
+    <!-- accessibility Title of menu shown over picture-in-picture [CHAR LIMIT=NONE] -->
+    <string name="pip_menu_accessibility_title">Picture-in-Picture Menu</string>
+
     <!-- PiP BTW notification title. [CHAR LIMIT=50] -->
     <string name="pip_notification_title"><xliff:g id="name" example="Google Maps">%s</xliff:g> is in picture-in-picture</string>
 
@@ -73,8 +76,10 @@
     <!-- Warning message when we try to launch a non-resizeable activity on a secondary display and launch it on the primary instead. -->
     <string name="activity_launch_on_secondary_display_failed_text">App does not support launch on secondary displays.</string>
 
-    <!-- Accessibility label for the divider that separates the windows in split-screen mode [CHAR LIMIT=NONE] -->
+    <!-- Accessibility label and window tile for the divider that separates the windows in split-screen mode [CHAR LIMIT=NONE] -->
     <string name="accessibility_divider">Split-screen divider</string>
+    <!-- Accessibility window title for the split-screen divider window [CHAR LIMIT=NONE] -->
+    <string name="divider_title">Split-screen divider</string>
 
     <!-- Accessibility action for moving docked stack divider to make the left screen full screen [CHAR LIMIT=NONE] -->
     <string name="accessibility_action_divider_left_full">Left full screen</string>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/RootDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/RootDisplayAreaOrganizer.java
index 14ba9df..764e650 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/RootDisplayAreaOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/RootDisplayAreaOrganizer.java
@@ -85,6 +85,8 @@
         }
 
         mDisplayAreasInfo.remove(displayId);
+        mLeashes.get(displayId).release();
+        mLeashes.remove(displayId);
     }
 
     @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java
index 992f315..6694e44 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java
@@ -17,7 +17,16 @@
 package com.android.wm.shell;
 
 import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN;
+import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_INIT;
 
+import android.os.Build;
+import android.os.SystemClock;
+import android.util.Pair;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.activityembedding.ActivityEmbeddingController;
 import com.android.wm.shell.bubbles.BubbleController;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayImeController;
@@ -37,10 +46,12 @@
 import com.android.wm.shell.unfold.UnfoldAnimationController;
 import com.android.wm.shell.unfold.UnfoldTransitionHandler;
 
+import java.util.ArrayList;
 import java.util.Optional;
 
 /**
- * The entry point implementation into the shell for initializing shell internal state.
+ * The entry point implementation into the shell for initializing shell internal state.  Classes
+ * which need to setup on start should inject an instance of this class and add an init callback.
  */
 public class ShellInitImpl {
     private static final String TAG = ShellInitImpl.class.getSimpleName();
@@ -62,8 +73,12 @@
     private final Transitions mTransitions;
     private final StartingWindowController mStartingWindow;
     private final Optional<RecentTasksController> mRecentTasks;
+    private final Optional<ActivityEmbeddingController> mActivityEmbeddingOptional;
 
     private final InitImpl mImpl = new InitImpl();
+    // An ordered list of init callbacks to be made once shell is first started
+    private final ArrayList<Pair<String, Runnable>> mInitCallbacks = new ArrayList<>();
+    private boolean mHasInitialized;
 
     public ShellInitImpl(
             DisplayController displayController,
@@ -80,6 +95,7 @@
             Optional<UnfoldTransitionHandler> unfoldTransitionHandler,
             Optional<FreeformTaskListener<?>> freeformTaskListenerOptional,
             Optional<RecentTasksController> recentTasks,
+            Optional<ActivityEmbeddingController> activityEmbeddingOptional,
             Transitions transitions,
             StartingWindowController startingWindow,
             ShellExecutor mainExecutor) {
@@ -97,6 +113,7 @@
         mUnfoldTransitionHandler = unfoldTransitionHandler;
         mFreeformTaskListenerOptional = freeformTaskListenerOptional;
         mRecentTasks = recentTasks;
+        mActivityEmbeddingOptional = activityEmbeddingOptional;
         mTransitions = transitions;
         mMainExecutor = mainExecutor;
         mStartingWindow = startingWindow;
@@ -106,7 +123,7 @@
         return mImpl;
     }
 
-    private void init() {
+    private void legacyInit() {
         // Start listening for display and insets changes
         mDisplayController.initialize();
         mDisplayInsetsController.initialize();
@@ -126,6 +143,7 @@
 
         if (Transitions.ENABLE_SHELL_TRANSITIONS) {
             mTransitions.register(mShellTaskOrganizer);
+            mActivityEmbeddingOptional.ifPresent(ActivityEmbeddingController::init);
             mUnfoldTransitionHandler.ifPresent(UnfoldTransitionHandler::init);
             if (mSplitScreenOptional.isPresent() && mPipTouchHandlerOptional.isPresent()) {
                 final DefaultMixedHandler mixedHandler = new DefaultMixedHandler(mTransitions,
@@ -153,12 +171,52 @@
         mKidsModeTaskOrganizer.initialize(mStartingWindow);
     }
 
+    /**
+     * Adds a callback to the ordered list of callbacks be made when Shell is first started.  This
+     * can be used in class constructors when dagger is used to ensure that the initialization order
+     * matches the dependency order.
+     */
+    public <T extends Object> void addInitCallback(Runnable r, T instance) {
+        if (mHasInitialized) {
+            if (Build.isDebuggable()) {
+                // All callbacks must be added prior to the Shell being initialized
+                throw new IllegalArgumentException("Can not add callback after init");
+            }
+            return;
+        }
+        final String className = instance.getClass().getSimpleName();
+        mInitCallbacks.add(new Pair<>(className, r));
+        ProtoLog.v(WM_SHELL_INIT, "Adding init callback for %s", className);
+    }
+
+    /**
+     * Calls all the init callbacks when the Shell is first starting.
+     */
+    @VisibleForTesting
+    public void init() {
+        ProtoLog.v(WM_SHELL_INIT, "Initializing Shell Components: %d", mInitCallbacks.size());
+        // Init in order of registration
+        for (int i = 0; i < mInitCallbacks.size(); i++) {
+            final Pair<String, Runnable> info = mInitCallbacks.get(i);
+            final long t1 = SystemClock.uptimeMillis();
+            info.second.run();
+            final long t2 = SystemClock.uptimeMillis();
+            ProtoLog.v(WM_SHELL_INIT, "\t%s took %dms", info.first, (t2 - t1));
+        }
+        mInitCallbacks.clear();
+
+        // TODO: To be removed
+        legacyInit();
+
+        mHasInitialized = true;
+    }
+
     @ExternalThread
     private class InitImpl implements ShellInit {
         @Override
         public void init() {
             try {
-                mMainExecutor.executeBlocking(() -> ShellInitImpl.this.init());
+                mMainExecutor.executeBlocking(ShellInitImpl.this::init);
             } catch (InterruptedException e) {
                 throw new RuntimeException("Failed to initialize the Shell in 2s", e);
             }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index fb61861..4080b99 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -23,6 +23,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 
 import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG;
+import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -500,7 +501,9 @@
                     || (taskInfo.topActivityType == WindowConfiguration.ACTIVITY_TYPE_HOME
                     && taskInfo.isVisible);
             final boolean focusTaskChanged = (mLastFocusedTaskInfo == null
-                    || mLastFocusedTaskInfo.taskId != taskInfo.taskId) && isFocusedOrHome;
+                    || mLastFocusedTaskInfo.taskId != taskInfo.taskId
+                    || mLastFocusedTaskInfo.getWindowingMode() != taskInfo.getWindowingMode())
+                    && isFocusedOrHome;
             if (focusTaskChanged) {
                 for (int i = 0; i < mFocusListeners.size(); i++) {
                     mFocusListeners.valueAt(i).onFocusTaskChanged(taskInfo);
@@ -530,7 +533,8 @@
             }
 
             final int taskId = taskInfo.taskId;
-            final TaskListener listener = getTaskListener(mTasks.get(taskId).getTaskInfo());
+            final TaskAppearedInfo appearedInfo = mTasks.get(taskId);
+            final TaskListener listener = getTaskListener(appearedInfo.getTaskInfo());
             mTasks.remove(taskId);
             if (listener != null) {
                 listener.onTaskVanished(taskInfo);
@@ -540,6 +544,11 @@
             notifyCompatUI(taskInfo, null /* taskListener */);
             // Notify the recent tasks that a task has been removed
             mRecentTasks.ifPresent(recentTasks -> recentTasks.onTaskRemoved(taskInfo));
+
+            if (!ENABLE_SHELL_TRANSITIONS && (appearedInfo.getLeash() != null)) {
+                // Preemptively clean up the leash only if shell transitions are not enabled
+                appearedInfo.getLeash().release();
+            }
         }
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java
new file mode 100644
index 0000000..82b0270
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.activityembedding;
+
+import static android.window.TransitionInfo.FLAG_IS_EMBEDDED;
+
+import android.content.Context;
+import android.os.IBinder;
+import android.view.SurfaceControl;
+import android.window.TransitionInfo;
+import android.window.TransitionRequestInfo;
+import android.window.WindowContainerTransaction;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.wm.shell.transition.Transitions;
+
+/**
+ * Responsible for handling ActivityEmbedding related transitions.
+ */
+public class ActivityEmbeddingController implements Transitions.TransitionHandler {
+
+    private final Context mContext;
+    private final Transitions mTransitions;
+
+    public ActivityEmbeddingController(Context context, Transitions transitions) {
+        mContext = context;
+        mTransitions = transitions;
+    }
+
+    /** Registers to handle transitions. */
+    public void init() {
+        mTransitions.addHandler(this);
+    }
+
+    @Override
+    public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
+            @NonNull SurfaceControl.Transaction startTransaction,
+            @NonNull SurfaceControl.Transaction finishTransaction,
+            @NonNull Transitions.TransitionFinishCallback finishCallback) {
+        // TODO(b/207070762) Handle AE animation as a part of other transitions.
+        // Only handle the transition if all containers are embedded.
+        for (TransitionInfo.Change change : info.getChanges()) {
+            if (!isEmbedded(change)) {
+                return false;
+            }
+        }
+
+        // TODO(b/207070762) Implement AE animation.
+        startTransaction.apply();
+        finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
+        return true;
+    }
+
+    @Nullable
+    @Override
+    public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
+            @NonNull TransitionRequestInfo request) {
+        return null;
+    }
+
+    private static boolean isEmbedded(@NonNull TransitionInfo.Change change) {
+        return (change.getFlags() & FLAG_IS_EMBEDDED) != 0;
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/PhysicsAnimator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/PhysicsAnimator.kt
index b483fe0..312af4f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/PhysicsAnimator.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/PhysicsAnimator.kt
@@ -829,8 +829,12 @@
 
     /** Cancels all in progress animations on all properties. */
     fun cancel() {
-        cancelAction(flingAnimations.keys)
-        cancelAction(springAnimations.keys)
+        if (flingAnimations.size > 0) {
+            cancelAction(flingAnimations.keys)
+        }
+        if (springAnimations.size > 0) {
+            cancelAction(springAnimations.keys)
+        }
     }
 
     /** Cancels in progress animations on the provided properties only. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimation.java
index 8c0affb..86f9d5b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimation.java
@@ -29,6 +29,13 @@
 public interface BackAnimation {
 
     /**
+     * Returns a binder that can be passed to an external process to update back animations.
+     */
+    default IBackAnimation createExternalInterface() {
+        return null;
+    }
+
+    /**
      * Called when a {@link MotionEvent} is generated by a back gesture.
      *
      * @param touchX the X touch position of the {@link MotionEvent}.
@@ -47,13 +54,6 @@
     void setTriggerBack(boolean triggerBack);
 
     /**
-     * Returns a binder that can be passed to an external process to update back animations.
-     */
-    default IBackAnimation createExternalInterface() {
-        return null;
-    }
-
-    /**
      * Sets the threshold values that defining edge swipe behavior.
      * @param triggerThreshold the min threshold to trigger back.
      * @param progressThreshold the max threshold to keep progressing back animation.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index f061f8b..e35e4ac 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -406,7 +406,9 @@
     private boolean shouldDispatchToLauncher(int backType) {
         return backType == BackNavigationInfo.TYPE_RETURN_TO_HOME
                 && mBackToLauncherCallback != null
-                && mEnableAnimations.get();
+                && mEnableAnimations.get()
+                && mBackNavigationInfo != null
+                && mBackNavigationInfo.getDepartingAnimationTarget() != null;
     }
 
     private static void dispatchOnBackStarted(IOnBackInvokedCallback callback) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index a2c4055..d7f1292 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -85,7 +85,6 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.logging.UiEventLogger;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.TaskViewTransitions;
@@ -102,6 +101,8 @@
 import com.android.wm.shell.onehanded.OneHandedController;
 import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
 import com.android.wm.shell.pip.PinnedStackListenerForwarder;
+import com.android.wm.shell.sysui.ConfigurationChangeListener;
+import com.android.wm.shell.sysui.ShellController;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -120,7 +121,7 @@
  *
  * The controller manages addition, removal, and visible state of bubbles on screen.
  */
-public class BubbleController {
+public class BubbleController implements ConfigurationChangeListener {
 
     private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleController" : TAG_BUBBLES;
 
@@ -156,6 +157,7 @@
     private final DisplayController mDisplayController;
     private final TaskViewTransitions mTaskViewTransitions;
     private final SyncTransactionQueue mSyncQueue;
+    private final ShellController mShellController;
 
     // Used to post to main UI thread
     private final ShellExecutor mMainExecutor;
@@ -223,44 +225,9 @@
     /** Drag and drop controller to register listener for onDragStarted. */
     private DragAndDropController mDragAndDropController;
 
-    /**
-     * Creates an instance of the BubbleController.
-     */
-    public static BubbleController create(Context context,
-            @Nullable BubbleStackView.SurfaceSynchronizer synchronizer,
-            FloatingContentCoordinator floatingContentCoordinator,
-            @Nullable IStatusBarService statusBarService,
-            WindowManager windowManager,
-            WindowManagerShellWrapper windowManagerShellWrapper,
-            UserManager userManager,
-            LauncherApps launcherApps,
-            TaskStackListenerImpl taskStackListener,
-            UiEventLogger uiEventLogger,
-            ShellTaskOrganizer organizer,
-            DisplayController displayController,
-            Optional<OneHandedController> oneHandedOptional,
-            DragAndDropController dragAndDropController,
-            @ShellMainThread ShellExecutor mainExecutor,
-            @ShellMainThread Handler mainHandler,
-            @ShellBackgroundThread ShellExecutor bgExecutor,
-            TaskViewTransitions taskViewTransitions,
-            SyncTransactionQueue syncQueue) {
-        BubbleLogger logger = new BubbleLogger(uiEventLogger);
-        BubblePositioner positioner = new BubblePositioner(context, windowManager);
-        BubbleData data = new BubbleData(context, logger, positioner, mainExecutor);
-        return new BubbleController(context, data, synchronizer, floatingContentCoordinator,
-                new BubbleDataRepository(context, launcherApps, mainExecutor),
-                statusBarService, windowManager, windowManagerShellWrapper, userManager,
-                launcherApps, logger, taskStackListener, organizer, positioner, displayController,
-                oneHandedOptional, dragAndDropController, mainExecutor, mainHandler, bgExecutor,
-                taskViewTransitions, syncQueue);
-    }
-
-    /**
-     * Testing constructor.
-     */
-    @VisibleForTesting
-    protected BubbleController(Context context,
+  
+    public BubbleController(Context context,
+            ShellController shellController,
             BubbleData data,
             @Nullable BubbleStackView.SurfaceSynchronizer synchronizer,
             FloatingContentCoordinator floatingContentCoordinator,
@@ -283,6 +250,7 @@
             TaskViewTransitions taskViewTransitions,
             SyncTransactionQueue syncQueue) {
         mContext = context;
+        mShellController = shellController;
         mLauncherApps = launcherApps;
         mBarService = statusBarService == null
                 ? IStatusBarService.Stub.asInterface(
@@ -451,6 +419,8 @@
         // Clear out any persisted bubbles on disk that no longer have a valid user.
         List<UserInfo> users = mUserManager.getAliveUsers();
         mDataRepository.sanitizeBubbles(users);
+
+        mShellController.addConfigurationChangeListener(this);
     }
 
     @VisibleForTesting
@@ -835,7 +805,8 @@
         mSavedBubbleKeysPerUser.remove(userId);
     }
 
-    private void updateForThemeChanges() {
+    @Override
+    public void onThemeChanged() {
         if (mStackView != null) {
             mStackView.onThemeChanged();
         }
@@ -855,7 +826,8 @@
         }
     }
 
-    private void onConfigChanged(Configuration newConfig) {
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
         if (mBubblePositioner != null) {
             mBubblePositioner.update();
         }
@@ -1715,13 +1687,6 @@
         }
 
         @Override
-        public void updateForThemeChanges() {
-            mMainExecutor.execute(() -> {
-                BubbleController.this.updateForThemeChanges();
-            });
-        }
-
-        @Override
         public void expandStackAndSelectBubble(BubbleEntry entry) {
             mMainExecutor.execute(() -> {
                 BubbleController.this.expandStackAndSelectBubble(entry);
@@ -1860,13 +1825,6 @@
         }
 
         @Override
-        public void onConfigChanged(Configuration newConfig) {
-            mMainExecutor.execute(() -> {
-                BubbleController.this.onConfigChanged(newConfig);
-            });
-        }
-
-        @Override
         public void onNotificationPanelExpandedChanged(boolean expanded) {
             mMainExecutor.execute(
                     () -> BubbleController.this.onNotificationPanelExpandedChanged(expanded));
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
index 0072da1..f8ccf23 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
@@ -107,9 +107,6 @@
     /** Tell the stack of bubbles to collapse. */
     void collapseStack();
 
-    /** Tell the controller need update its UI to fit theme. */
-    void updateForThemeChanges();
-
     /**
      * Request the stack expand if needed, then select the specified Bubble as current.
      * If no bubble exists for this entry, one is created.
@@ -255,13 +252,6 @@
      */
     void onUserRemoved(int removedUserId);
 
-    /**
-     * Called when config changed.
-     *
-     * @param newConfig the new config.
-     */
-    void onConfigChanged(Configuration newConfig);
-
     /** Description of current bubble state. */
     void dump(PrintWriter pw, String[] args);
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
index 6a2acf4..b3f6247 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
@@ -20,6 +20,7 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
 import android.annotation.IntDef;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Point;
@@ -324,7 +325,7 @@
         }
 
         @Override
-        public void topFocusedWindowChanged(String packageName,
+        public void topFocusedWindowChanged(ComponentName component,
                 InsetsVisibilities requestedVisibilities) {
             // Do nothing
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayInsetsController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayInsetsController.java
index b670544..f546f11 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayInsetsController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayInsetsController.java
@@ -16,6 +16,7 @@
 
 package com.android.wm.shell.common;
 
+import android.content.ComponentName;
 import android.os.RemoteException;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -171,14 +172,14 @@
             }
         }
 
-        private void topFocusedWindowChanged(String packageName,
+        private void topFocusedWindowChanged(ComponentName component,
                 InsetsVisibilities requestedVisibilities) {
             CopyOnWriteArrayList<OnInsetsChangedListener> listeners = mListeners.get(mDisplayId);
             if (listeners == null) {
                 return;
             }
             for (OnInsetsChangedListener listener : listeners) {
-                listener.topFocusedWindowChanged(packageName, requestedVisibilities);
+                listener.topFocusedWindowChanged(component, requestedVisibilities);
             }
         }
 
@@ -186,10 +187,10 @@
         private class DisplayWindowInsetsControllerImpl
                 extends IDisplayWindowInsetsController.Stub {
             @Override
-            public void topFocusedWindowChanged(String packageName,
+            public void topFocusedWindowChanged(ComponentName component,
                     InsetsVisibilities requestedVisibilities) throws RemoteException {
                 mMainExecutor.execute(() -> {
-                    PerDisplay.this.topFocusedWindowChanged(packageName, requestedVisibilities);
+                    PerDisplay.this.topFocusedWindowChanged(component, requestedVisibilities);
                 });
             }
 
@@ -234,10 +235,10 @@
         /**
          * Called when top focused window changes to determine whether or not to take over insets
          * control. Won't be called if config_remoteInsetsControllerControlsSystemBars is false.
-         * @param packageName The name of the package that is open in the top focussed window.
+         * @param component The application component that is open in the top focussed window.
          * @param requestedVisibilities The insets visibilities requested by the focussed window.
          */
-        default void topFocusedWindowChanged(String packageName,
+        default void topFocusedWindowChanged(ComponentName component,
                 InsetsVisibilities requestedVisibilities) {}
 
         /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
index 5ebe384..8bc16bc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
@@ -206,12 +206,12 @@
         mSplitLayout = layout;
         mSplitWindowManager = splitWindowManager;
         mViewHost = viewHost;
-        mDividerBounds.set(layout.getDividerBounds());
+        layout.getDividerBounds(mDividerBounds);
         onInsetsChanged(insetsState, false /* animate */);
     }
 
     void onInsetsChanged(InsetsState insetsState, boolean animate) {
-        mTempRect.set(mSplitLayout.getDividerBounds());
+        mSplitLayout.getDividerBounds(mTempRect);
         final InsetsSource taskBarInsetsSource =
                 insetsState.getSource(InsetsState.ITYPE_EXTRA_NAVIGATION_BAR);
         // Only insets the divider bar with task bar when it's expanded so that the rounded corners
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
index 484294a..74f8bf9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
@@ -50,12 +50,15 @@
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.SurfaceUtils;
 
+import java.util.function.Consumer;
+
 /**
  * Handles split decor like showing resizing hint for a specific split.
  */
 public class SplitDecorManager extends WindowlessWindowManager {
     private static final String TAG = SplitDecorManager.class.getSimpleName();
     private static final String RESIZING_BACKGROUND_SURFACE_NAME = "ResizingBackground";
+    private static final String GAP_BACKGROUND_SURFACE_NAME = "GapBackground";
     private static final long FADE_DURATION = 133;
 
     private final IconProvider mIconProvider;
@@ -67,6 +70,7 @@
     private SurfaceControl mHostLeash;
     private SurfaceControl mIconLeash;
     private SurfaceControl mBackgroundLeash;
+    private SurfaceControl mGapBackgroundLeash;
 
     private boolean mShown;
     private boolean mIsResizing;
@@ -141,6 +145,10 @@
             t.remove(mBackgroundLeash);
             mBackgroundLeash = null;
         }
+        if (mGapBackgroundLeash != null) {
+            t.remove(mGapBackgroundLeash);
+            mGapBackgroundLeash = null;
+        }
         mHostLeash = null;
         mIcon = null;
         mResizingIconView = null;
@@ -150,7 +158,7 @@
 
     /** Showing resizing hint. */
     public void onResizing(ActivityManager.RunningTaskInfo resizingTask, Rect newBounds,
-            SurfaceControl.Transaction t) {
+            Rect sideBounds, SurfaceControl.Transaction t) {
         if (mResizingIconView == null) {
             return;
         }
@@ -176,6 +184,19 @@
                     .setLayer(mBackgroundLeash, Integer.MAX_VALUE - 1);
         }
 
+        if (mGapBackgroundLeash == null) {
+            final boolean isLandscape = newBounds.height() == sideBounds.height();
+            final int left = isLandscape ? mBounds.width() : 0;
+            final int top = isLandscape ? 0 : mBounds.height();
+            mGapBackgroundLeash = SurfaceUtils.makeColorLayer(mHostLeash,
+                    GAP_BACKGROUND_SURFACE_NAME, mSurfaceSession);
+            // Fill up another side bounds area.
+            t.setColor(mGapBackgroundLeash, getResizingBackgroundColor(resizingTask))
+                    .setLayer(mGapBackgroundLeash, Integer.MAX_VALUE - 2)
+                    .setPosition(mGapBackgroundLeash, left, top)
+                    .setWindowCrop(mGapBackgroundLeash, sideBounds.width(), sideBounds.height());
+        }
+
         if (mIcon == null && resizingTask.topActivityInfo != null) {
             mIcon = mIconProvider.getIcon(resizingTask.topActivityInfo);
             mResizingIconView.setImageDrawable(mIcon);
@@ -193,7 +214,7 @@
                 newBounds.height() / 2 - mIconSize / 2);
 
         if (animate) {
-            startFadeAnimation(show, false /* isResized */);
+            startFadeAnimation(show, null /* finishedConsumer */);
             mShown = show;
         }
     }
@@ -224,14 +245,29 @@
             mFadeAnimator.cancel();
         }
         if (mShown) {
-            startFadeAnimation(false /* show */, true /* isResized */);
+            fadeOutDecor(null /* finishedCallback */);
         } else {
             // Decor surface is hidden so release it directly.
             releaseDecor(t);
         }
     }
 
-    private void startFadeAnimation(boolean show, boolean isResized) {
+    /** Fade-out decor surface with animation end callback, if decor is hidden, run the callback
+     * directly. */
+    public void fadeOutDecor(Runnable finishedCallback) {
+        if (mShown) {
+            startFadeAnimation(false /* show */, transaction -> {
+                releaseDecor(transaction);
+                if (finishedCallback != null) finishedCallback.run();
+            });
+            mShown = false;
+        } else {
+            if (finishedCallback != null) finishedCallback.run();
+        }
+    }
+
+    private void startFadeAnimation(boolean show,
+            Consumer<SurfaceControl.Transaction> finishedConsumer) {
         final SurfaceControl.Transaction animT = new SurfaceControl.Transaction();
         mFadeAnimator = ValueAnimator.ofFloat(0f, 1f);
         mFadeAnimator.setDuration(FADE_DURATION);
@@ -249,7 +285,9 @@
             @Override
             public void onAnimationStart(@NonNull Animator animation) {
                 if (show) {
-                    animT.show(mBackgroundLeash).show(mIconLeash).apply();
+                    animT.show(mBackgroundLeash).show(mIconLeash).show(mGapBackgroundLeash).apply();
+                } else {
+                    animT.hide(mGapBackgroundLeash).apply();
                 }
             }
 
@@ -263,8 +301,8 @@
                         animT.hide(mIconLeash);
                     }
                 }
-                if (isResized) {
-                    releaseDecor(animT);
+                if (finishedConsumer != null) {
+                    finishedConsumer.accept(animT);
                 }
                 animT.apply();
                 animT.close();
@@ -280,6 +318,11 @@
             mBackgroundLeash = null;
         }
 
+        if (mGapBackgroundLeash != null) {
+            t.remove(mGapBackgroundLeash);
+            mGapBackgroundLeash = null;
+        }
+
         if (mIcon != null) {
             mResizingIconView.setVisibility(View.GONE);
             mResizingIconView.setImageDrawable(null);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index c962de6..40cf9a3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -32,6 +32,7 @@
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
+import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -200,6 +201,44 @@
         return outBounds;
     }
 
+    /** Gets bounds of the primary split with screen based coordinate on the param Rect. */
+    public void getBounds1(Rect rect) {
+        rect.set(mBounds1);
+    }
+
+    /** Gets bounds of the primary split with parent based coordinate on the param Rect. */
+    public void getRefBounds1(Rect rect) {
+        getBounds1(rect);
+        rect.offset(-mRootBounds.left, -mRootBounds.top);
+    }
+
+    /** Gets bounds of the secondary split with screen based coordinate on the param Rect. */
+    public void getBounds2(Rect rect) {
+        rect.set(mBounds2);
+    }
+
+    /** Gets bounds of the secondary split with parent based coordinate on the param Rect. */
+    public void getRefBounds2(Rect rect) {
+        getBounds2(rect);
+        rect.offset(-mRootBounds.left, -mRootBounds.top);
+    }
+
+    /** Gets root bounds of the whole split layout on the param Rect. */
+    public void getRootBounds(Rect rect) {
+        rect.set(mRootBounds);
+    }
+
+    /** Gets bounds of divider window with screen based coordinate on the param Rect. */
+    public void getDividerBounds(Rect rect) {
+        rect.set(mDividerBounds);
+    }
+
+    /** Gets bounds of divider window with parent based coordinate on the param Rect. */
+    public void getRefDividerBounds(Rect rect) {
+        getDividerBounds(rect);
+        rect.offset(-mRootBounds.left, -mRootBounds.top);
+    }
+
     /** Returns leash of the current divider bar. */
     @Nullable
     public SurfaceControl getDividerLeash() {
@@ -411,11 +450,13 @@
         switch (snapTarget.flag) {
             case FLAG_DISMISS_START:
                 flingDividePosition(currentPosition, snapTarget.position,
-                        () -> mSplitLayoutHandler.onSnappedToDismiss(false /* bottomOrRight */));
+                        () -> mSplitLayoutHandler.onSnappedToDismiss(false /* bottomOrRight */,
+                                EXIT_REASON_DRAG_DIVIDER));
                 break;
             case FLAG_DISMISS_END:
                 flingDividePosition(currentPosition, snapTarget.position,
-                        () -> mSplitLayoutHandler.onSnappedToDismiss(true /* bottomOrRight */));
+                        () -> mSplitLayoutHandler.onSnappedToDismiss(true /* bottomOrRight */,
+                                EXIT_REASON_DRAG_DIVIDER));
                 break;
             default:
                 flingDividePosition(currentPosition, snapTarget.position,
@@ -449,16 +490,36 @@
     private DividerSnapAlgorithm getSnapAlgorithm(Context context, Rect rootBounds,
             @Nullable Rect stableInsets) {
         final boolean isLandscape = isLandscape(rootBounds);
+        final Rect insets = stableInsets != null ? stableInsets : getDisplayInsets(context);
+
+        // Make split axis insets value same as the larger one to avoid bounds1 and bounds2
+        // have difference after split switching for solving issues on non-resizable app case.
+        if (isLandscape) {
+            final int largerInsets = Math.max(insets.left, insets.right);
+            insets.set(largerInsets, insets.top, largerInsets, insets.bottom);
+        } else {
+            final int largerInsets = Math.max(insets.top, insets.bottom);
+            insets.set(insets.left, largerInsets, insets.right, largerInsets);
+        }
+
         return new DividerSnapAlgorithm(
                 context.getResources(),
                 rootBounds.width(),
                 rootBounds.height(),
                 mDividerSize,
                 !isLandscape,
-                stableInsets != null ? stableInsets : getDisplayInsets(context),
+                insets,
                 isLandscape ? DOCKED_LEFT : DOCKED_TOP /* dockSide */);
     }
 
+    /** Fling divider from current position to end or start position then exit */
+    public void flingDividerToDismiss(boolean toEnd, int reason) {
+        final int target = toEnd ? mDividerSnapAlgorithm.getDismissEndTarget().position
+                : mDividerSnapAlgorithm.getDismissStartTarget().position;
+        flingDividePosition(getDividePosition(), target,
+                () -> mSplitLayoutHandler.onSnappedToDismiss(toEnd, reason));
+    }
+
     @VisibleForTesting
     void flingDividePosition(int from, int to, @Nullable Runnable flingFinishedCallback) {
         if (from == to) {
@@ -560,8 +621,8 @@
                 t.setPosition(leash, distX, distY);
                 t.setWindowCrop(leash, width, height);
             } else {
-                final int offsetX = width - start.width();
-                final int offsetY = height - start.height();
+                final int offsetX = width - tempStart.width();
+                final int offsetY = height - tempStart.height();
                 t.setPosition(leash, distX + offsetX, distY + offsetY);
                 mTempRect.set(0, 0, width, height);
                 mTempRect.offsetTo(-offsetX, -offsetY);
@@ -610,15 +671,15 @@
             boolean applyResizingOffset) {
         final SurfaceControl dividerLeash = getDividerLeash();
         if (dividerLeash != null) {
-            mTempRect.set(getRefDividerBounds());
+            getRefDividerBounds(mTempRect);
             t.setPosition(dividerLeash, mTempRect.left, mTempRect.top);
             // Resets layer of divider bar to make sure it is always on top.
             t.setLayer(dividerLeash, Integer.MAX_VALUE);
         }
-        mTempRect.set(getRefBounds1());
+        getRefBounds1(mTempRect);
         t.setPosition(leash1, mTempRect.left, mTempRect.top)
                 .setWindowCrop(leash1, mTempRect.width(), mTempRect.height());
-        mTempRect.set(getRefBounds2());
+        getRefBounds2(mTempRect);
         t.setPosition(leash2, mTempRect.left, mTempRect.top)
                 .setWindowCrop(leash2, mTempRect.width(), mTempRect.height());
 
@@ -666,31 +727,23 @@
             ActivityManager.RunningTaskInfo taskInfo1, ActivityManager.RunningTaskInfo taskInfo2) {
         if (offsetX == 0 && offsetY == 0) {
             wct.setBounds(taskInfo1.token, mBounds1);
-            wct.setAppBounds(taskInfo1.token, null);
             wct.setScreenSizeDp(taskInfo1.token,
                     SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
 
             wct.setBounds(taskInfo2.token, mBounds2);
-            wct.setAppBounds(taskInfo2.token, null);
             wct.setScreenSizeDp(taskInfo2.token,
                     SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
         } else {
-            mTempRect.set(taskInfo1.configuration.windowConfiguration.getBounds());
+            getBounds1(mTempRect);
             mTempRect.offset(offsetX, offsetY);
             wct.setBounds(taskInfo1.token, mTempRect);
-            mTempRect.set(taskInfo1.configuration.windowConfiguration.getAppBounds());
-            mTempRect.offset(offsetX, offsetY);
-            wct.setAppBounds(taskInfo1.token, mTempRect);
             wct.setScreenSizeDp(taskInfo1.token,
                     taskInfo1.configuration.screenWidthDp,
                     taskInfo1.configuration.screenHeightDp);
 
-            mTempRect.set(taskInfo2.configuration.windowConfiguration.getBounds());
+            getBounds2(mTempRect);
             mTempRect.offset(offsetX, offsetY);
             wct.setBounds(taskInfo2.token, mTempRect);
-            mTempRect.set(taskInfo2.configuration.windowConfiguration.getAppBounds());
-            mTempRect.offset(offsetX, offsetY);
-            wct.setAppBounds(taskInfo2.token, mTempRect);
             wct.setScreenSizeDp(taskInfo2.token,
                     taskInfo2.configuration.screenWidthDp,
                     taskInfo2.configuration.screenHeightDp);
@@ -708,7 +761,7 @@
     public interface SplitLayoutHandler {
 
         /** Calls when dismissing split. */
-        void onSnappedToDismiss(boolean snappedToEnd);
+        void onSnappedToDismiss(boolean snappedToEnd, int reason);
 
         /**
          * Calls when resizing the split bounds.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java
index 9b61487..afc706e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java
@@ -15,6 +15,11 @@
  */
 package com.android.wm.shell.common.split;
 
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+
 import android.annotation.IntDef;
 
 /** Helper utility class of methods and constants that are available to be imported in Launcher. */
@@ -44,4 +49,10 @@
     })
     public @interface SplitPosition {
     }
+
+    public static final int[] CONTROLLED_ACTIVITY_TYPES = {ACTIVITY_TYPE_STANDARD};
+    public static final int[] CONTROLLED_WINDOWING_MODES =
+            {WINDOWING_MODE_FULLSCREEN, WINDOWING_MODE_UNDEFINED};
+    public static final int[] CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE =
+            {WINDOWING_MODE_FULLSCREEN, WINDOWING_MODE_UNDEFINED, WINDOWING_MODE_MULTI_WINDOW};
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
index 864b9a7..7fea237 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
@@ -126,6 +126,7 @@
         lp.token = new Binder();
         lp.setTitle(mWindowName);
         lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY;
+        lp.accessibilityTitle = mContext.getResources().getString(R.string.accessibility_divider);
         mViewHost.setView(mDividerView, lp);
         mDividerView.setup(splitLayout, this, mViewHost, insetsState);
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUI.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUI.java
deleted file mode 100644
index b87cf47..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUI.java
+++ /dev/null
@@ -1,35 +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 com.android.wm.shell.compatui;
-
-import com.android.wm.shell.common.annotations.ExternalThread;
-
-/**
- * Interface to engage compat UI.
- */
-@ExternalThread
-public interface CompatUI {
-    /**
-     * Called when the keyguard showing state changes. Removes all compat UIs if the
-     * keyguard is now showing.
-     *
-     * <p>Note that if the keyguard is occluded it will also be considered showing.
-     *
-     * @param showing indicates if the keyguard is now showing.
-     */
-    void onKeyguardShowingChanged(boolean showing);
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
index 99b32a6..db8d9d4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
@@ -39,9 +39,10 @@
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.common.annotations.ExternalThread;
 import com.android.wm.shell.compatui.CompatUIWindowManager.CompatUIHintsState;
 import com.android.wm.shell.compatui.letterboxedu.LetterboxEduWindowManager;
+import com.android.wm.shell.sysui.KeyguardChangeListener;
+import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.transition.Transitions;
 
 import java.lang.ref.WeakReference;
@@ -58,7 +59,7 @@
  * activities are in compatibility mode.
  */
 public class CompatUIController implements OnDisplaysChangedListener,
-        DisplayImeController.ImePositionProcessor {
+        DisplayImeController.ImePositionProcessor, KeyguardChangeListener {
 
     /** Callback for compat UI interaction. */
     public interface CompatUICallback {
@@ -100,13 +101,13 @@
     private final SparseArray<WeakReference<Context>> mDisplayContextCache = new SparseArray<>(0);
 
     private final Context mContext;
+    private final ShellController mShellController;
     private final DisplayController mDisplayController;
     private final DisplayInsetsController mDisplayInsetsController;
     private final DisplayImeController mImeController;
     private final SyncTransactionQueue mSyncQueue;
     private final ShellExecutor mMainExecutor;
     private final Lazy<Transitions> mTransitionsLazy;
-    private final CompatUIImpl mImpl = new CompatUIImpl();
 
     private CompatUICallback mCallback;
 
@@ -118,6 +119,7 @@
     private boolean mKeyguardShowing;
 
     public CompatUIController(Context context,
+            ShellController shellController,
             DisplayController displayController,
             DisplayInsetsController displayInsetsController,
             DisplayImeController imeController,
@@ -125,6 +127,7 @@
             ShellExecutor mainExecutor,
             Lazy<Transitions> transitionsLazy) {
         mContext = context;
+        mShellController = shellController;
         mDisplayController = displayController;
         mDisplayInsetsController = displayInsetsController;
         mImeController = imeController;
@@ -134,11 +137,7 @@
         mDisplayController.addDisplayWindowListener(this);
         mImeController.addPositionProcessor(this);
         mCompatUIHintsState = new CompatUIHintsState();
-    }
-
-    /** Returns implementation of {@link CompatUI}. */
-    public CompatUI asCompatUI() {
-        return mImpl;
+        shellController.addKeyguardChangeListener(this);
     }
 
     /** Sets the callback for UI interactions. */
@@ -223,9 +222,10 @@
                 layout -> layout.updateVisibility(showOnDisplay(displayId)));
     }
 
-    @VisibleForTesting
-    void onKeyguardShowingChanged(boolean showing) {
-        mKeyguardShowing = showing;
+    @Override
+    public void onKeyguardVisibilityChanged(boolean visible, boolean occluded,
+            boolean animatingDismiss) {
+        mKeyguardShowing = visible;
         // Hide the compat UIs when keyguard is showing.
         forAllLayouts(layout -> layout.updateVisibility(showOnDisplay(layout.getDisplayId())));
     }
@@ -373,19 +373,6 @@
         }
     }
 
-    /**
-     * The interface for calls from outside the Shell, within the host process.
-     */
-    @ExternalThread
-    private class CompatUIImpl implements CompatUI {
-        @Override
-        public void onKeyguardShowingChanged(boolean showing) {
-            mMainExecutor.execute(() -> {
-                CompatUIController.this.onKeyguardShowingChanged(showing);
-            });
-        }
-    }
-
     /** An implementation of {@link OnInsetsChangedListener} for a given display id. */
     private class PerDisplayOnInsetsChangedListener implements OnInsetsChangedListener {
         final int mDisplayId;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/README.txt b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/README.txt
deleted file mode 100644
index 1cd69ed..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/README.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-The dagger modules in this directory can be included by the host SysUI using the Shell library for
-explicity injection of Shell components. Apps using this library are not required to use these
-dagger modules for setup, but it is recommended for them to include them as needed.
-
-The modules are currently inherited as such:
-
-+- WMShellBaseModule (common shell features across SysUI)
-   |
-   +- WMShellModule (handheld)
-   |
-   +- TvPipModule (tv pip)
-      |
-      +- TvWMShellModule (tv)
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java
index 1ea5e21..81904e2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java
@@ -48,6 +48,7 @@
 import com.android.wm.shell.pip.tv.TvPipTaskOrganizer;
 import com.android.wm.shell.pip.tv.TvPipTransition;
 import com.android.wm.shell.splitscreen.SplitScreenController;
+import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.transition.Transitions;
 
 import java.util.Optional;
@@ -64,6 +65,7 @@
     @Provides
     static Optional<Pip> providePip(
             Context context,
+            ShellController shellController,
             TvPipBoundsState tvPipBoundsState,
             TvPipBoundsAlgorithm tvPipBoundsAlgorithm,
             TvPipBoundsController tvPipBoundsController,
@@ -81,6 +83,7 @@
         return Optional.of(
                 TvPipController.create(
                         context,
+                        shellController,
                         tvPipBoundsState,
                         tvPipBoundsAlgorithm,
                         tvPipBoundsController,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 2ea111b..586eab0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -38,6 +38,7 @@
 import com.android.wm.shell.TaskViewFactoryController;
 import com.android.wm.shell.TaskViewTransitions;
 import com.android.wm.shell.WindowManagerShellWrapper;
+import com.android.wm.shell.activityembedding.ActivityEmbeddingController;
 import com.android.wm.shell.back.BackAnimation;
 import com.android.wm.shell.back.BackAnimationController;
 import com.android.wm.shell.bubbles.BubbleController;
@@ -56,15 +57,12 @@
 import com.android.wm.shell.common.annotations.ShellBackgroundThread;
 import com.android.wm.shell.common.annotations.ShellMainThread;
 import com.android.wm.shell.common.annotations.ShellSplashscreenThread;
-import com.android.wm.shell.compatui.CompatUI;
 import com.android.wm.shell.compatui.CompatUIController;
 import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
 import com.android.wm.shell.displayareahelper.DisplayAreaHelperController;
-import com.android.wm.shell.draganddrop.DragAndDrop;
 import com.android.wm.shell.draganddrop.DragAndDropController;
 import com.android.wm.shell.freeform.FreeformTaskListener;
 import com.android.wm.shell.fullscreen.FullscreenTaskListener;
-import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
 import com.android.wm.shell.hidedisplaycutout.HideDisplayCutoutController;
 import com.android.wm.shell.kidsmode.KidsModeTaskOrganizer;
 import com.android.wm.shell.onehanded.OneHanded;
@@ -82,8 +80,8 @@
 import com.android.wm.shell.startingsurface.StartingWindowController;
 import com.android.wm.shell.startingsurface.StartingWindowTypeAlgorithm;
 import com.android.wm.shell.startingsurface.phone.PhoneStartingWindowTypeAlgorithm;
-import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelper;
-import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelperController;
+import com.android.wm.shell.sysui.ShellController;
+import com.android.wm.shell.sysui.ShellInterface;
 import com.android.wm.shell.transition.ShellTransitions;
 import com.android.wm.shell.transition.Transitions;
 import com.android.wm.shell.unfold.ShellUnfoldProgressProvider;
@@ -159,16 +157,13 @@
     @WMSingleton
     @Provides
     static DragAndDropController provideDragAndDropController(Context context,
-            DisplayController displayController, UiEventLogger uiEventLogger,
-            IconProvider iconProvider, @ShellMainThread ShellExecutor mainExecutor) {
-        return new DragAndDropController(context, displayController, uiEventLogger, iconProvider,
-                mainExecutor);
-    }
-
-    @WMSingleton
-    @Provides
-    static Optional<DragAndDrop> provideDragAndDrop(DragAndDropController dragAndDropController) {
-        return Optional.of(dragAndDropController.asDragAndDrop());
+            ShellController shellController,
+            DisplayController displayController,
+            UiEventLogger uiEventLogger,
+            IconProvider iconProvider,
+            @ShellMainThread ShellExecutor mainExecutor) {
+        return new DragAndDropController(context, shellController, displayController, uiEventLogger,
+                iconProvider, mainExecutor);
     }
 
     @WMSingleton
@@ -201,18 +196,14 @@
     }
 
     @WMSingleton
-    @Provides static Optional<CompatUI> provideCompatUI(CompatUIController compatUIController) {
-        return Optional.of(compatUIController.asCompatUI());
-    }
-
-    @WMSingleton
     @Provides
     static CompatUIController provideCompatUIController(Context context,
+            ShellController shellController,
             DisplayController displayController, DisplayInsetsController displayInsetsController,
             DisplayImeController imeController, SyncTransactionQueue syncQueue,
             @ShellMainThread ShellExecutor mainExecutor, Lazy<Transitions> transitionsLazy) {
-        return new CompatUIController(context, displayController, displayInsetsController,
-                imeController, syncQueue, mainExecutor, transitionsLazy);
+        return new CompatUIController(context, shellController, displayController,
+                displayInsetsController, imeController, syncQueue, mainExecutor, transitionsLazy);
     }
 
     @WMSingleton
@@ -369,17 +360,12 @@
 
     @WMSingleton
     @Provides
-    static Optional<HideDisplayCutout> provideHideDisplayCutout(
-            Optional<HideDisplayCutoutController> hideDisplayCutoutController) {
-        return hideDisplayCutoutController.map((controller) -> controller.asHideDisplayCutout());
-    }
-
-    @WMSingleton
-    @Provides
     static Optional<HideDisplayCutoutController> provideHideDisplayCutoutController(Context context,
-            DisplayController displayController, @ShellMainThread ShellExecutor mainExecutor) {
+            ShellController shellController, DisplayController displayController,
+            @ShellMainThread ShellExecutor mainExecutor) {
         return Optional.ofNullable(
-                HideDisplayCutoutController.create(context, displayController, mainExecutor));
+                HideDisplayCutoutController.create(context, shellController, displayController,
+                        mainExecutor));
     }
 
     //
@@ -408,23 +394,6 @@
     }
 
     //
-    // Task to Surface communication
-    //
-
-    @WMSingleton
-    @Provides
-    static Optional<TaskSurfaceHelper> provideTaskSurfaceHelper(
-            Optional<TaskSurfaceHelperController> taskSurfaceController) {
-        return taskSurfaceController.map((controller) -> controller.asTaskSurfaceHelper());
-    }
-
-    @Provides
-    static Optional<TaskSurfaceHelperController> provideTaskSurfaceHelperController(
-            ShellTaskOrganizer taskOrganizer, @ShellMainThread ShellExecutor mainExecutor) {
-        return Optional.ofNullable(new TaskSurfaceHelperController(taskOrganizer, mainExecutor));
-    }
-
-    //
     // Pip (optional feature)
     //
 
@@ -621,6 +590,34 @@
                 taskViewTransitions);
     }
 
+
+    //
+    // ActivityEmbedding
+    //
+
+    @WMSingleton
+    @Provides
+    static Optional<ActivityEmbeddingController> provideActivityEmbeddingController(
+            Context context, Transitions transitions) {
+        return Optional.of(new ActivityEmbeddingController(context, transitions));
+    }
+
+    //
+    // SysUI -> Shell interface
+    //
+
+    @WMSingleton
+    @Provides
+    static ShellInterface provideShellSysuiCallbacks(ShellController shellController) {
+        return shellController.asShell();
+    }
+
+    @WMSingleton
+    @Provides
+    static ShellController provideShellController(@ShellMainThread ShellExecutor mainExecutor) {
+        return new ShellController(mainExecutor);
+    }
+
     //
     // Misc
     //
@@ -647,6 +644,7 @@
             Optional<UnfoldTransitionHandler> unfoldTransitionHandler,
             Optional<FreeformTaskListener<?>> freeformTaskListener,
             Optional<RecentTasksController> recentTasksOptional,
+            Optional<ActivityEmbeddingController> activityEmbeddingOptional,
             Transitions transitions,
             StartingWindowController startingWindow,
             @ShellMainThread ShellExecutor mainExecutor) {
@@ -664,6 +662,7 @@
                 unfoldTransitionHandler,
                 freeformTaskListener,
                 recentTasksOptional,
+                activityEmbeddingOptional,
                 transitions,
                 startingWindow,
                 mainExecutor);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index a8c1071..0f33f4c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -31,6 +31,10 @@
 import com.android.wm.shell.TaskViewTransitions;
 import com.android.wm.shell.WindowManagerShellWrapper;
 import com.android.wm.shell.bubbles.BubbleController;
+import com.android.wm.shell.bubbles.BubbleData;
+import com.android.wm.shell.bubbles.BubbleDataRepository;
+import com.android.wm.shell.bubbles.BubbleLogger;
+import com.android.wm.shell.bubbles.BubblePositioner;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayImeController;
 import com.android.wm.shell.common.DisplayInsetsController;
@@ -67,6 +71,7 @@
 import com.android.wm.shell.pip.phone.PipTouchHandler;
 import com.android.wm.shell.recents.RecentTasksController;
 import com.android.wm.shell.splitscreen.SplitScreenController;
+import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.transition.Transitions;
 import com.android.wm.shell.unfold.ShellUnfoldProgressProvider;
 import com.android.wm.shell.unfold.UnfoldAnimationController;
@@ -104,10 +109,34 @@
     // Bubbles
     //
 
+    @WMSingleton
+    @Provides
+    static BubbleLogger provideBubbleLogger(UiEventLogger uiEventLogger) {
+        return new BubbleLogger(uiEventLogger);
+    }
+
+    @WMSingleton
+    @Provides
+    static BubblePositioner provideBubblePositioner(Context context,
+            WindowManager windowManager) {
+        return new BubblePositioner(context, windowManager);
+    }
+
+    @WMSingleton
+    @Provides
+    static BubbleData provideBubbleData(Context context,
+            BubbleLogger logger,
+            BubblePositioner positioner,
+            @ShellMainThread ShellExecutor mainExecutor) {
+        return new BubbleData(context, logger, positioner, mainExecutor);
+    }
+
     // Note: Handler needed for LauncherApps.register
     @WMSingleton
     @Provides
     static BubbleController provideBubbleController(Context context,
+            ShellController shellController,
+            BubbleData data,
             FloatingContentCoordinator floatingContentCoordinator,
             IStatusBarService statusBarService,
             WindowManager windowManager,
@@ -115,8 +144,9 @@
             UserManager userManager,
             LauncherApps launcherApps,
             TaskStackListenerImpl taskStackListener,
-            UiEventLogger uiEventLogger,
+            BubbleLogger logger,
             ShellTaskOrganizer organizer,
+            BubblePositioner positioner,
             DisplayController displayController,
             @DynamicOverride Optional<OneHandedController> oneHandedOptional,
             DragAndDropController dragAndDropController,
@@ -125,11 +155,12 @@
             @ShellBackgroundThread ShellExecutor bgExecutor,
             TaskViewTransitions taskViewTransitions,
             SyncTransactionQueue syncQueue) {
-        return BubbleController.create(context, null /* synchronizer */,
-                floatingContentCoordinator, statusBarService, windowManager,
-                windowManagerShellWrapper, userManager, launcherApps, taskStackListener,
-                uiEventLogger, organizer, displayController, oneHandedOptional,
-                dragAndDropController, mainExecutor, mainHandler, bgExecutor,
+        return new BubbleController(context, shellController, data, null /* synchronizer */,
+                floatingContentCoordinator,
+                new BubbleDataRepository(context, launcherApps, mainExecutor),
+                statusBarService, windowManager, windowManagerShellWrapper, userManager,
+                launcherApps, logger, taskStackListener, organizer, positioner, displayController,
+                oneHandedOptional, dragAndDropController, mainExecutor, mainHandler, bgExecutor,
                 taskViewTransitions, syncQueue);
     }
 
@@ -176,12 +207,14 @@
     @Provides
     @DynamicOverride
     static OneHandedController provideOneHandedController(Context context,
+            ShellController shellController,
             WindowManager windowManager, DisplayController displayController,
             DisplayLayout displayLayout, TaskStackListenerImpl taskStackListener,
             UiEventLogger uiEventLogger, InteractionJankMonitor jankMonitor,
             @ShellMainThread ShellExecutor mainExecutor, @ShellMainThread Handler mainHandler) {
-        return OneHandedController.create(context, windowManager, displayController, displayLayout,
-                taskStackListener, jankMonitor, uiEventLogger, mainExecutor, mainHandler);
+        return OneHandedController.create(context, shellController, windowManager,
+                displayController, displayLayout, taskStackListener, jankMonitor, uiEventLogger,
+                mainExecutor, mainHandler);
     }
 
     //
@@ -192,6 +225,7 @@
     @Provides
     @DynamicOverride
     static SplitScreenController provideSplitScreenController(
+            ShellController shellController,
             ShellTaskOrganizer shellTaskOrganizer,
             SyncTransactionQueue syncQueue, Context context,
             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
@@ -201,7 +235,7 @@
             DisplayInsetsController displayInsetsController, Transitions transitions,
             TransactionPool transactionPool, IconProvider iconProvider,
             Optional<RecentTasksController> recentTasks) {
-        return new SplitScreenController(shellTaskOrganizer, syncQueue, context,
+        return new SplitScreenController(shellController, shellTaskOrganizer, syncQueue, context,
                 rootTaskDisplayAreaOrganizer, mainExecutor, displayController, displayImeController,
                 displayInsetsController, transitions, transactionPool, iconProvider,
                 recentTasks);
@@ -213,7 +247,8 @@
 
     @WMSingleton
     @Provides
-    static Optional<Pip> providePip(Context context, DisplayController displayController,
+    static Optional<Pip> providePip(Context context,
+            ShellController shellController, DisplayController displayController,
             PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm,
             PipKeepClearAlgorithm pipKeepClearAlgorithm, PipBoundsState pipBoundsState,
             PipMotionHelper pipMotionHelper, PipMediaController pipMediaController,
@@ -225,7 +260,7 @@
             PipParamsChangedForwarder pipParamsChangedForwarder,
             Optional<OneHandedController> oneHandedController,
             @ShellMainThread ShellExecutor mainExecutor) {
-        return Optional.ofNullable(PipController.create(context, displayController,
+        return Optional.ofNullable(PipController.create(context, shellController, displayController,
                 pipAppOpsListener, pipBoundsAlgorithm, pipKeepClearAlgorithm, pipBoundsState,
                 pipMotionHelper,
                 pipMediaController, phonePipMenuController, pipTaskOrganizer, pipTransitionState,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/README.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/README.md
new file mode 100644
index 0000000..73a7348
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/README.md
@@ -0,0 +1,18 @@
+# Window Manager Shell Readme
+
+The following docs present more detail about the implementation of the WMShell library (in no
+particular order):
+
+1) [What is the Shell](overview.md)
+2) [Integration with SystemUI & Launcher](sysui.md)
+3) [Usage of Dagger](dagger.md)
+4) [Threading model in the Shell](threading.md)
+5) [Making changes in the Shell](changes.md)
+6) [Extending the Shell for Products/OEMs](extending.md)
+7) [Debugging in the Shell](debugging.md)
+8) [Testing in the Shell](testing.md)
+
+Todo
+- Per-feature docs
+- Feature flagging
+- Best practices
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md
new file mode 100644
index 0000000..f4e2f20
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md
@@ -0,0 +1,73 @@
+# Making changes in the Shell
+
+---
+
+## Code reviews
+
+In addition to the individual reviewers who are most familiar with the changes you are making,
+please also add [wm-code-reviewers@google.com](http://g/wm-code-reviewers) to keep other WM folks
+in the loop.
+
+## Adding new code
+
+### Internal Shell utility classes
+If the new component is used only within the WMShell library, then there are no special
+considerations, go ahead and add it (in the `com.android.wm.shell.common` package for example)
+and make sure the appropriate [unit tests](testing.md) are added.
+
+### Internal Shell components
+If the new component is to be used by other components/features within the Shell library, then
+you can create an appropriate package for this component to add your new code. The current
+pattern is to have a single `<Component name>Controller` that handles the initialization of the
+component.
+
+As mentioned in the [Dagger usage](dagger.md) docs, you need to determine whether it should go into:
+- `WMShellBaseModule` for components that other base & product components will depend on
+- or `WMShellModule`, `TvWmShellModule`, etc. for product specific components that no base
+  components depend on
+
+### SysUI accessible components
+In addition to doing the above, you will also need to provide an interface for calling to SysUI
+from the Shell and vice versa.  The current pattern is to have a parallel `Optional<Component name>`
+interface that the `<Component name>Controller` implements and handles on the main Shell thread.
+
+In addition, because components accessible to SysUI injection are explicitly listed, you'll have to
+add an appropriate method in `WMComponent` to get the interface and update the `Builder` in
+`SysUIComponent` to take the interface so it can be injected in SysUI code.  The binding between
+the two is done in `SystemUIFactory#init()` which will need to be updated as well.
+
+### Launcher accessible components
+Because Launcher is not a part of SystemUI and is a separate process, exposing controllers to
+Launcher requires a new AIDL interface to be created and implemented by the controller.  The
+implementation of the stub interface in the controller otherwise behaves similar to the interface
+to SysUI where it posts the work to the main Shell thread.
+
+### Component initialization
+To initialize the component:
+- On the Shell side, update `ShellInitImpl` to get a signal to initialize when the SysUI is started
+- On the SysUI side, update `WMShell` to setup any bindings for the component that depend on
+  SysUI code
+
+### General Do's & Dont's
+Do:
+- Do add unit tests for all new components
+- Do keep controllers simple and break them down as needed
+
+Don't:
+- **Don't** do initialization in the constructor, only do initialization in the init callbacks.
+  Otherwise it complicates the building of the dependency graph.
+- **Don't** create dependencies from base-module components on specific features (the base module
+  is intended for use with all products)
+  - Try adding a mechanism to register and listen for changes from the base module component instead
+- **Don't** add blocking synchronous calls in the SysUI interface between Shell & SysUI
+  - Try adding a push-mechanism to share data, or an async callback to request data
+
+### Exposing shared code for use in Launcher
+Launcher doesn't currently build against the Shell library, but needs to have access to some shared
+AIDL interfaces and constants.  Currently, all AIDL files, and classes under the
+`com.android.wm.shell.util` package are automatically built into the `SystemUISharedLib` that
+Launcher uses.
+
+If the new code doesn't fall into those categories, they can be added explicitly in the Shell's
+[Android.bp](frameworks/base/libs/WindowManager/Shell/Android.bp) file under the
+`wm_shell_util-sources` filegroup.
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/dagger.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/dagger.md
new file mode 100644
index 0000000..6c01d96
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/dagger.md
@@ -0,0 +1,50 @@
+# Usage of Dagger in the Shell library
+
+---
+
+## Dependencies
+
+Dagger is not required to use the Shell library, but it has a lot of obvious benefits:
+
+- Not having to worry about how to instantiate all the dependencies of a class, especially as
+  dependencies evolve (ie. product controller depends on base controller)
+- Can create boundaries within the same app to encourage better code modularity
+
+As such, the Shell also tries to provide some reasonable out-of-the-box modules for use with Dagger.
+
+## Modules
+
+All the Dagger related code in the Shell can be found in the `com.android.wm.shell.dagger` package,
+this is intentional as it keeps the "magic" in a single location.  The explicit nature of how
+components in the shell are provided is as a result a bit more verbose, but it makes it easy for
+developers to jump into a few select files and understand how different components are provided
+(especially as products override components).
+
+The module dependency tree looks a bit like:
+- [WMShellConcurrencyModule](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java)
+  (provides threading-related components)
+  - [WMShellBaseModule](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java)
+    (provides components that are likely common to all products, ie. DisplayController,
+    Transactions, etc.)
+    - [WMShellModule](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java)
+      (phone/tablet specific components only)
+    - [TvPipModule](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java)
+      (PIP specific components for TV)
+      - [TvWMShellModule](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java)
+        (TV specific components only)
+  - etc.
+
+Ideally features could be abstracted out into their own modules and included as needed by each
+product.
+
+## Overriding base components
+
+In some rare cases, there are base components that can change behavior depending on which
+product it runs on.  If there are hooks that can be added to the component, that is the
+preferable approach.
+
+The alternative is to use the [@DynamicOverride](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/DynamicOverride.java)
+annotation to allow the product module to provide an implementation that the base module can
+reference.  This is most useful if the existence of the entire component is controlled by the
+product and the override implementation is optional (there is a default implementation).  More
+details can be found in the class's javadoc.
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md
new file mode 100644
index 0000000..52f0c42
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md
@@ -0,0 +1,69 @@
+# Debugging in the Shell
+
+---
+
+## Logging & ProtoLogs
+
+The interactions in the Shell can be pretty complicated, so having good logging is crucial to
+debugging problems that arise (especially in dogfood).  The Shell uses the same efficient Protolog
+mechanism as WM Core, which can be enabled at runtime on debug devices.
+
+**TLDR**&nbsp; Don’t use Logs or Slogs except for error cases, Protologs are much more flexible,
+easy to add and easy to use
+
+### Adding a new ProtoLog
+Update `ShellProtoLogGroup` to include a new log group (ie. NEW_FEATURE) for the content you want to
+log.  ProtoLog log calls mirror Log.v/d/e(), and take a format message and arguments:
+```java
+ProtoLog.v(NEW_FEATURE, "Test log w/ params: %d %s", 1, “a”)
+```
+This code itself will not compile by itself, but the `protologtool` will preprocess the file when
+building to check the log state (is enabled) before printing the print format style log.
+
+**Notes**
+- ProtoLogs currently only work from soong builds (ie. via make/mp). We need to reimplement the
+  tool for use with SysUI-studio
+- Non-text ProtoLogs are not currently supported with the Shell library (you can't view them with
+  traces in Winscope)
+
+### Enabling ProtoLog command line logging
+Run these commands to enable protologs for both WM Core and WM Shell to print to logcat.
+```shell
+adb shell wm logging enable-text NEW_FEATURE
+adb shell wm logging disable-text NEW_FEATURE
+```
+
+## Winscope Tracing
+
+The Winscope tool is extremely useful in determining what is happening on-screen in both
+WindowManager and SurfaceFlinger.  Follow [go/winscope](http://go/winscope-help) to learn how to
+use the tool.
+
+In addition, there is limited preliminary support for Winscope tracing componetns in the Shell,
+which involves adding trace fields to [wm_shell_trace.proto](frameworks/base/libs/WindowManager/Shell/proto/wm_shell_trace.proto)
+file and ensure it is updated as a part of `WMShell#writeToProto`.
+
+Tracing can be started via the shell command (to be added to the Winscope tool as needed):
+```shell
+adb shell cmd statusbar tracing start
+adb shell cmd statusbar tracing stop
+```
+
+## Dumps
+
+Because the Shell library is built as a part of SystemUI, dumping the state is currently done as a
+part of dumping the SystemUI service.  Dumping the Shell specific data can be done by specifying the
+WMShell SysUI service:
+
+```shell
+adb shell dumpsys activity service SystemUIService WMShell
+```
+
+If information should be added to the dump, make updates to:
+- `WMShell` if you are dumping SysUI state
+- `ShellCommandHandler` if you are dumping Shell state
+
+## Debugging in Android Studio
+
+If you are using the [go/sysui-studio](http://go/sysui-studio) project, then you can debug Shell
+code directly from Android Studio like any other app.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/extending.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/extending.md
new file mode 100644
index 0000000..061ae00e
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/extending.md
@@ -0,0 +1,13 @@
+# Extending the Shell for Products/OEMs
+
+---
+
+## General Do's & Dont's
+
+Do:
+- &nbsp;
+
+Don't
+- **Don't** override classes provided by WMShellBaseModule, it makes it difficult to make
+  simple changes to the Shell library base modules which are shared by all products
+  - If possible add mechanisms to modify the base class behavior
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/overview.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/overview.md
new file mode 100644
index 0000000..a88ef6a
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/overview.md
@@ -0,0 +1,58 @@
+# What is the WindowManager Shell
+
+---
+
+## Motivation
+
+The primary motivation for the WindowManager Shell (WMShell) library is to effectively scale
+WindowManager by making it easy&trade; and safe to create windowing features to fit the needs of
+various Android products and form factors.
+
+To achieve this, WindowManager separates the policy of managing windows (WMCore) from the
+presentation of surfaces (WMShell) and provides a minimal interface boundary for the two to
+communicate.
+
+## Who is using the library?
+
+Currently, the WMShell library is used to drive the windowing experience on handheld
+(phones & tablets), TV, Auto, Arc++, and Wear to varying degrees.
+
+## Where does the code live
+
+The core WMShell library code is currently located in the [frameworks/base/libs/WindowManager/Shell](frameworks/base/libs/WindowManager/Shell)
+directory and is included as a part dependency of the host SystemUI apk.
+
+## How do I build the Shell library
+
+The library can be built directly by running (using [go/makepush](http://go/makepush)):
+```shell
+mp :WindowManager-Shell
+```
+But this is mainly useful for inspecting the contents of the library or verifying it builds. The
+various targets can be found in the Shell library's [Android.bp](frameworks/base/libs/WindowManager/Shell/Android.bp)
+file.
+
+Normally, you would build it as a part of the host SystemUI, for example via commandline:
+```shell
+# Phone SystemUI variant
+mp sysuig
+# Building Shell & SysUI changes along w/ framework changes
+mp core services sysuig
+```
+
+Or preferably, if you are making WMShell/SysUI only changes (no other framework changes), then
+building via [go/sysui-studio](http://go/sysui-studio) allows for very quick iteration (one click
+build and push of SysUI in < 30s).
+
+If you are making framework changes and are using `aidegen` to set up your platform IDE, make sure
+to include the appropriate directories to build, for example:
+```shell
+# frameworks/base will include base/libs/WindowManager/Shell and base/packages/SystemUI
+aidegen frameworks/base \
+    vendor/<oem>/packages/SystemUI \
+    ...
+```
+
+## Other useful links
+- [go/o-o-summit-20](go/o-o-summit-20) (Video presentations from the WM team)
+- [go/o-o-summit-21](go/o-o-summit-21)
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md
new file mode 100644
index 0000000..0dd50b1
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md
@@ -0,0 +1,65 @@
+# Shell & SystemUI
+
+---
+
+## Setup
+
+The SystemUI of various products depend on and build against the WM Shell library. To ensure
+that we don't inadvertently build dependencies between the Shell library and one particular
+product (ie. handheld SysUI), we deliberately separate the initialization of the WM Shell
+component from the SysUI component when set up through Dagger.
+
+**TLDR**&nbsp; Initialize everything as needed in the WM component scope and export only well
+defined interfaces to SysUI.
+
+## Initialization
+
+There are more details in the Dagger docs, but the general overview of the SysUI/Shell
+initialization flow is such:
+
+1) SysUI Global scope is initialize (see `GlobalModule` and its included modules)
+2) WM Shell scope is initialized, for example
+   1) On phones: `WMComponent` includes `WMShellModule` which includes `WMShellBaseModule`
+      (common to all SysUI)
+   2) On TVs: `TvWMComponent` includes `TvWMShellModule` which includes `WMShellBaseModule`
+   3) etc.
+3) SysUI explicitly passes interfaces provided from the `WMComponent` to `SysUIComponent` via
+   the `SysUIComponent#Builder`, then builds the SysUI scoped components
+4) `WMShell` is the SystemUI “service” (in the SysUI scope) that initializes with the app after the
+SystemUI part of the dependency graph has been created. It contains the binding code between the
+interfaces provided by the Shell and the rest of SystemUI.
+5) SysUI can inject the interfaces into its own components
+
+More detail can be found in [go/wm-sysui-dagger](http://go/wm-sysui-dagger).
+
+## Interfaces to Shell components
+
+Within the same process, the WM Shell components can be running on a different thread than the main
+SysUI thread (disabled on certain products).  This introduces challenges where we have to be
+careful about how SysUI calls into the Shell and vice versa.
+
+As a result, we enforce explicit interfaces between SysUI and Shell components, and the
+implementations of the interfaces on each side need to post to the right thread before it calls
+into other code.
+
+For example, you might have:
+1) (Shell) ShellFeature interface to be used from SysUI
+2) (Shell) ShellFeatureController handles logic, implements ShellFeature interface and posts to
+   main Shell thread
+3) SysUI application init injects Optional<ShellFeature> as an interface to SysUI to call
+4) (SysUI) SysUIFeature depends on ShellFeature interface
+5) (SysUI) SysUIFeature injects Optional<ShellFeature>, and sets up a callback for the Shell to
+   call, and the callback posts to the main SysUI thread
+
+Adding an interface to a Shell component may seem like a lot of boiler plate, but is currently
+necessary to maintain proper threading and logic isolation.
+
+## Configuration changes & other SysUI events
+
+Aside from direct calls into Shell controllers for exposed features, the Shell also receives 
+common event callbacks from SysUI via the `ShellController`.  This includes things like:
+
+- Configuration changes
+- TODO: Shell init
+- TODO: Shell command
+- TODO: Keyguard events
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/testing.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/testing.md
new file mode 100644
index 0000000..8a80333
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/testing.md
@@ -0,0 +1,49 @@
+# Testing
+
+---
+
+## Unit tests
+
+New WM Shell unit tests can be added to the
+[Shell/tests/unittest](frameworks/base/libs/WindowManager/Shell/tests/unittest) directory, and can
+be run via command line using `atest`:
+```shell
+atest WMShellUnitTests
+```
+
+If you use the SysUI Studio project, you can run and debug tests directly in the source files
+(click on the little arrows next to the test class or test method).
+
+These unit tests are run as a part of WindowManager presubmit, and the dashboards for these unit
+tests tests can be found at [go/wm-tests](http://go/wm-tests).
+
+This [GCL file](http://go/wm-unit-tests-gcl) configures the tests being run on the server.
+
+## Flicker tests
+
+Flicker tests are tests that perform actions and make assertions on the state in Window Manager
+and SurfaceFlinger traces captured during the run.
+
+New WM Shell Flicker tests can be added to the
+[Shell/tests/flicker](frameworks/base/libs/WindowManager/Shell/tests/flicker) directory, and can
+be run via command line using `atest`:
+```shell
+atest WMShellFlickerTests
+```
+
+**Note**: Currently Flicker tests can only be run from the commandline and not via SysUI Studio
+
+A subset of the flicker tests tests are run as a part of WindowManager presubmit, and the
+dashboards for these tests tests can be found at [go/wm-tests-flicker](http://go/wm-tests-flicker).
+
+## CTS tests
+
+Some windowing features also have CTS tests to ensure consistent behavior across OEMs.  For example:
+- Picture-in-Picture:
+  [PinnedStackTests](cts/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java)
+- etc.
+
+These can also be run via commandline only using `atest`, for example:
+```shell
+atest PinnedStackTests
+```
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/threading.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/threading.md
new file mode 100644
index 0000000..eac74889
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/threading.md
@@ -0,0 +1,83 @@
+# Threading
+
+---
+
+## Boundaries
+
+```text
+                                    Thread boundary
+                                          |
+                                WM Shell  | SystemUI
+                                          |
+                                          |
+FeatureController <-> FeatureInterface <--|--> WMShell <-> SysUI
+       |          (^post to shell thread) |            (^post to main thread)
+      ...                                 |
+       |                                  |
+ OtherControllers                         |
+```
+
+## Threads
+
+We currently have multiple threads in use in the Shell library depending on the configuration by
+the product.
+- SysUI main thread (standard main thread)
+- `ShellMainThread` (only used if the resource `config_enableShellMainThread` is set true
+  (ie. phones))
+  - This falls back to the SysUI main thread otherwise
+  - **Note**:
+    - This thread runs with `THREAD_PRIORITY_DISPLAY` priority since so many windowing-critical
+      components depend on it
+    - This is also the UI thread for almost all UI created by the Shell
+    - The Shell main thread Handler (and the Executor that wraps it) is async, so
+      messages/runnables used via this Handler are handled immediately if there is no sync
+      messages prior to it in the queue.
+- `ShellBackgroundThread` (for longer running tasks where we don't want to block the shell main
+  thread)
+  - This is always another thread even if config_enableShellMainThread is not set true
+  - **Note**:
+    - This thread runs with `THREAD_PRIORITY_BACKGROUND` priority
+- `ShellAnimationThread` (currently only used for Transitions and Splitscreen, but potentially all
+  animations could be offloaded here)
+- `ShellSplashScreenThread` (only for use with splashscreens)
+
+## Dagger setup
+
+The threading-related components are provided by the [WMShellConcurrencyModule](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java),
+for example, the Executors and Handlers for the various threads that are used.  You can request
+an executor of the necessary type by using the appropriate annotation for each of the threads (ie.
+`@ShellMainThread Executor`) when injecting into your Shell component.
+
+To get the SysUI main thread, you can use the `@Main` annotation.
+
+## Best practices
+
+### Components
+- Don't do initialization in the Shell component constructors
+  - If the host SysUI is not careful, it may construct the WMComponent dependencies on the main
+    thread, and this reduces the likelihood that components will intiailize on the wrong thread
+    in such cases
+- Be careful of using CountDownLatch and other blocking synchronization mechanisms in Shell code
+  - If the Shell main thread is not a separate thread, this will cause a deadlock
+- Callbacks, Observers, Listeners to any non-shell component should post onto main Shell thread
+  - This includes Binder calls, SysUI calls, BroadcastReceivers, etc. Basically any API that
+    takes a runnable should either be registered with the right Executor/Handler or posted to
+    the main Shell thread manually
+- Since everything in the Shell runs on the main Shell thread, you do **not** need to explicitly
+  `synchronize` your code (unless you are trying to prevent reentrantcy, but that can also be
+  done in other ways)
+
+### Handlers/Executors
+- You generally **never** need to create Handlers explicitly, instead inject `@ShellMainThread
+  ShellExecutor` instead
+  - This is a common pattern to defer logic in UI code, but the Handler created wraps the Looper
+    that is currently running, which can be wrong (see above for initialization vs construction)
+- That said, sometimes Handlers are necessary because Framework API only takes Handlers or you
+  want to dedupe multiple messages
+  - In such cases inject `@ShellMainThread Handler` or use view.getHandler() which should be OK
+    assuming that the view root was initialized on the main Shell thread
+- **Never use Looper.getMainLooper()**
+  - It's likely going to be wrong, you can inject `@Main ShellExecutor` to get the SysUI main thread
+
+### Testing
+- You can use a `TestShellExecutor` to control the processing of messages
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDrop.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDrop.java
deleted file mode 100644
index edeff6e3..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDrop.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.draganddrop;
-
-import android.content.res.Configuration;
-
-import com.android.wm.shell.common.annotations.ExternalThread;
-
-/**
- * Interface for telling DragAndDrop stuff.
- */
-@ExternalThread
-public interface DragAndDrop {
-
-    /** Called when the theme changes. */
-    void onThemeChanged();
-
-    /** Called when the configuration changes. */
-    void onConfigChanged(Configuration newConfig);
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
index 95de2dc..c5df53b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
@@ -60,6 +60,8 @@
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.splitscreen.SplitScreenController;
+import com.android.wm.shell.sysui.ConfigurationChangeListener;
+import com.android.wm.shell.sysui.ShellController;
 
 import java.util.ArrayList;
 import java.util.Optional;
@@ -68,21 +70,20 @@
  * Handles the global drag and drop handling for the Shell.
  */
 public class DragAndDropController implements DisplayController.OnDisplaysChangedListener,
-        View.OnDragListener {
+        View.OnDragListener, ConfigurationChangeListener {
 
     private static final String TAG = DragAndDropController.class.getSimpleName();
 
     private final Context mContext;
+    private final ShellController mShellController;
     private final DisplayController mDisplayController;
     private final DragAndDropEventLogger mLogger;
     private final IconProvider mIconProvider;
     private SplitScreenController mSplitScreen;
     private ShellExecutor mMainExecutor;
-    private DragAndDropImpl mImpl;
     private ArrayList<DragAndDropListener> mListeners = new ArrayList<>();
 
     private final SparseArray<PerDisplay> mDisplayDropTargets = new SparseArray<>();
-    private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();
 
     /**
      * Listener called during drag events, currently just onDragStarted.
@@ -92,23 +93,24 @@
         void onDragStarted();
     }
 
-    public DragAndDropController(Context context, DisplayController displayController,
-            UiEventLogger uiEventLogger, IconProvider iconProvider, ShellExecutor mainExecutor) {
+    public DragAndDropController(Context context,
+            ShellController shellController,
+            DisplayController displayController,
+            UiEventLogger uiEventLogger,
+            IconProvider iconProvider,
+            ShellExecutor mainExecutor) {
         mContext = context;
+        mShellController = shellController;
         mDisplayController = displayController;
         mLogger = new DragAndDropEventLogger(uiEventLogger);
         mIconProvider = iconProvider;
         mMainExecutor = mainExecutor;
-        mImpl = new DragAndDropImpl();
-    }
-
-    public DragAndDrop asDragAndDrop() {
-        return mImpl;
     }
 
     public void initialize(Optional<SplitScreenController> splitscreen) {
         mSplitScreen = splitscreen.orElse(null);
         mDisplayController.addDisplayWindowListener(this);
+        mShellController.addConfigurationChangeListener(this);
     }
 
     /** Adds a listener to be notified of drag and drop events. */
@@ -310,13 +312,15 @@
         return mimeTypes;
     }
 
-    private void onThemeChange() {
+    @Override
+    public void onThemeChanged() {
         for (int i = 0; i < mDisplayDropTargets.size(); i++) {
             mDisplayDropTargets.get(i).dragLayout.onThemeChange();
         }
     }
 
-    private void onConfigChanged(Configuration newConfig) {
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
         for (int i = 0; i < mDisplayDropTargets.size(); i++) {
             mDisplayDropTargets.get(i).dragLayout.onConfigChanged(newConfig);
         }
@@ -342,21 +346,4 @@
             dragLayout = dl;
         }
     }
-
-    private class DragAndDropImpl implements DragAndDrop {
-
-        @Override
-        public void onThemeChanged() {
-            mMainExecutor.execute(() -> {
-                DragAndDropController.this.onThemeChange();
-            });
-        }
-
-        @Override
-        public void onConfigChanged(Configuration newConfig) {
-            mMainExecutor.execute(() -> {
-                DragAndDropController.this.onConfigChanged(newConfig);
-            });
-        }
-    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
index 6373728..435d8ea 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
@@ -45,12 +45,10 @@
 import android.content.ActivityNotFoundException;
 import android.content.ClipData;
 import android.content.ClipDescription;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.LauncherApps;
-import android.content.pm.ResolveInfo;
 import android.graphics.Insets;
 import android.graphics.Rect;
 import android.os.Bundle;
@@ -64,19 +62,15 @@
 import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.logging.InstanceId;
-import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.DisplayLayout;
-import com.android.wm.shell.common.split.SplitLayout;
 import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
-import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.splitscreen.SplitScreenController;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Objects;
 
 /**
  * The policy for handling drag and drop operations to shell.
@@ -269,47 +263,11 @@
             mStarter.startShortcut(packageName, id, position, opts, user);
         } else {
             final PendingIntent launchIntent = intent.getParcelableExtra(EXTRA_PENDING_INTENT);
-            mStarter.startIntent(launchIntent, getStartIntentFillInIntent(launchIntent, position),
-                    position, opts);
+            mStarter.startIntent(launchIntent, null /* fillIntent */, position, opts);
         }
     }
 
     /**
-     * Returns the fill-in intent to use when starting an app from a drop.
-     */
-    @VisibleForTesting
-    Intent getStartIntentFillInIntent(PendingIntent launchIntent, @SplitPosition int position) {
-        // Get the drag app
-        final List<ResolveInfo> infos = launchIntent.queryIntentComponents(0 /* flags */);
-        final ComponentName dragIntentActivity = !infos.isEmpty()
-                ? infos.get(0).activityInfo.getComponentName()
-                : null;
-
-        // Get the current app (either fullscreen or the remaining app post-drop if in splitscreen)
-        final boolean inSplitScreen = mSplitScreen != null
-                && mSplitScreen.isSplitScreenVisible();
-        final ComponentName currentActivity;
-        if (!inSplitScreen) {
-            currentActivity = mSession.runningTaskInfo != null
-                    ? mSession.runningTaskInfo.baseIntent.getComponent()
-                    : null;
-        } else {
-            final ActivityManager.RunningTaskInfo nonReplacedTaskInfo =
-                    mSplitScreen.getTaskInfo(SplitLayout.reversePosition(position));
-            currentActivity = nonReplacedTaskInfo.baseIntent.getComponent();
-        }
-
-        if (Objects.equals(currentActivity, dragIntentActivity)) {
-            // Only apply MULTIPLE_TASK if we are dragging the same activity
-            final Intent fillInIntent = new Intent();
-            fillInIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
-            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Adding MULTIPLE_TASK");
-            return fillInIntent;
-        }
-        return null;
-    }
-
-    /**
      * Per-drag session data.
      */
     private static class DragSession {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutout.java
deleted file mode 100644
index 60123ab..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutout.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.hidedisplaycutout;
-
-import android.content.res.Configuration;
-
-import androidx.annotation.NonNull;
-
-import com.android.wm.shell.common.annotations.ExternalThread;
-
-import java.io.PrintWriter;
-
-/**
- * Interface to engage hide display cutout feature.
- */
-@ExternalThread
-public interface HideDisplayCutout {
-    /**
-     * Notifies {@link Configuration} changed.
-     */
-    void onConfigurationChanged(Configuration newConfig);
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutController.java
index 23f76ca5..665b035 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutController.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.os.SystemProperties;
-import android.util.Slog;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -27,20 +26,20 @@
 
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.sysui.ConfigurationChangeListener;
+import com.android.wm.shell.sysui.ShellController;
 
 import java.io.PrintWriter;
-import java.util.concurrent.TimeUnit;
 
 /**
  * Manages the hide display cutout status.
  */
-public class HideDisplayCutoutController {
+public class HideDisplayCutoutController implements ConfigurationChangeListener {
     private static final String TAG = "HideDisplayCutoutController";
 
     private final Context mContext;
+    private final ShellController mShellController;
     private final HideDisplayCutoutOrganizer mOrganizer;
-    private final ShellExecutor mMainExecutor;
-    private final HideDisplayCutoutImpl mImpl = new HideDisplayCutoutImpl();
     @VisibleForTesting
     boolean mEnabled;
 
@@ -49,8 +48,9 @@
      * supported.
      */
     @Nullable
-    public static HideDisplayCutoutController create(
-            Context context, DisplayController displayController, ShellExecutor mainExecutor) {
+    public static HideDisplayCutoutController create(Context context,
+            ShellController shellController, DisplayController displayController,
+            ShellExecutor mainExecutor) {
         // The SystemProperty is set for devices that support this feature and is used to control
         // whether to create the HideDisplayCutout instance.
         // It's defined in the device.mk (e.g. device/google/crosshatch/device.mk).
@@ -60,19 +60,16 @@
 
         HideDisplayCutoutOrganizer organizer =
                 new HideDisplayCutoutOrganizer(context, displayController, mainExecutor);
-        return new HideDisplayCutoutController(context, organizer, mainExecutor);
+        return new HideDisplayCutoutController(context, shellController, organizer);
     }
 
-    HideDisplayCutoutController(Context context, HideDisplayCutoutOrganizer organizer,
-            ShellExecutor mainExecutor) {
+    HideDisplayCutoutController(Context context, ShellController shellController,
+            HideDisplayCutoutOrganizer organizer) {
         mContext = context;
+        mShellController = shellController;
         mOrganizer = organizer;
-        mMainExecutor = mainExecutor;
         updateStatus();
-    }
-
-    public HideDisplayCutout asHideDisplayCutout() {
-        return mImpl;
+        mShellController.addConfigurationChangeListener(this);
     }
 
     @VisibleForTesting
@@ -94,7 +91,8 @@
         }
     }
 
-    private void onConfigurationChanged(Configuration newConfig) {
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
         updateStatus();
     }
 
@@ -107,13 +105,4 @@
         pw.println(mEnabled);
         mOrganizer.dump(pw);
     }
-
-    private class HideDisplayCutoutImpl implements HideDisplayCutout {
-        @Override
-        public void onConfigurationChanged(Configuration newConfig) {
-            mMainExecutor.execute(() -> {
-                HideDisplayCutoutController.this.onConfigurationChanged(newConfig);
-            });
-        }
-    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java
index 3f7d78d..9478b34 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java
@@ -128,9 +128,10 @@
 
             final WindowContainerTransaction wct = new WindowContainerTransaction();
             final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
-            applyBoundsAndOffsets(
-                    displayAreaInfo.token, mDisplayAreaMap.get(displayAreaInfo.token), wct, t);
+            final SurfaceControl leash = mDisplayAreaMap.get(displayAreaInfo.token);
+            applyBoundsAndOffsets(displayAreaInfo.token, leash, wct, t);
             applyTransaction(wct, t);
+            leash.release();
             mDisplayAreaMap.remove(displayAreaInfo.token);
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java
index b00182f..76c0f41 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java
@@ -16,7 +16,6 @@
 
 package com.android.wm.shell.onehanded;
 
-import android.content.res.Configuration;
 import android.os.SystemProperties;
 
 import com.android.wm.shell.common.annotations.ExternalThread;
@@ -83,17 +82,7 @@
     void registerTransitionCallback(OneHandedTransitionCallback callback);
 
     /**
-     * Receive onConfigurationChanged() events
-     */
-    void onConfigChanged(Configuration newConfig);
-
-    /**
      * Notifies when user switch complete
      */
     void onUserSwitch(int userId);
-
-    /**
-     * Notifies when keyguard visibility changed
-     */
-    void onKeyguardVisibilityChanged(boolean showing);
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
index 3b9fcc7..24f02ac 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
@@ -54,6 +54,9 @@
 import com.android.wm.shell.common.TaskStackListenerCallback;
 import com.android.wm.shell.common.TaskStackListenerImpl;
 import com.android.wm.shell.common.annotations.ExternalThread;
+import com.android.wm.shell.sysui.ConfigurationChangeListener;
+import com.android.wm.shell.sysui.KeyguardChangeListener;
+import com.android.wm.shell.sysui.ShellController;
 
 import java.io.PrintWriter;
 
@@ -61,7 +64,8 @@
  * Manages and manipulates the one handed states, transitions, and gesture for phones.
  */
 public class OneHandedController implements RemoteCallable<OneHandedController>,
-        DisplayChangeController.OnDisplayChangingListener {
+        DisplayChangeController.OnDisplayChangingListener, ConfigurationChangeListener,
+        KeyguardChangeListener {
     private static final String TAG = "OneHandedController";
 
     private static final String ONE_HANDED_MODE_OFFSET_PERCENTAGE =
@@ -81,6 +85,7 @@
 
     private Context mContext;
 
+    private final ShellController mShellController;
     private final AccessibilityManager mAccessibilityManager;
     private final DisplayController mDisplayController;
     private final OneHandedSettingsUtil mOneHandedSettingsUtil;
@@ -188,8 +193,9 @@
      * Creates {@link OneHandedController}, returns {@code null} if the feature is not supported.
      */
     public static OneHandedController create(
-            Context context, WindowManager windowManager, DisplayController displayController,
-            DisplayLayout displayLayout, TaskStackListenerImpl taskStackListener,
+            Context context, ShellController shellController, WindowManager windowManager,
+            DisplayController displayController, DisplayLayout displayLayout,
+            TaskStackListenerImpl taskStackListener,
             InteractionJankMonitor jankMonitor, UiEventLogger uiEventLogger,
             ShellExecutor mainExecutor, Handler mainHandler) {
         OneHandedSettingsUtil settingsUtil = new OneHandedSettingsUtil();
@@ -207,14 +213,15 @@
                 context, displayLayout, settingsUtil, animationController, tutorialHandler,
                 jankMonitor, mainExecutor);
         OneHandedUiEventLogger oneHandedUiEventsLogger = new OneHandedUiEventLogger(uiEventLogger);
-        return new OneHandedController(context, displayController, organizer, touchHandler,
-                tutorialHandler, settingsUtil, accessibilityUtil, timeoutHandler, oneHandedState,
-                oneHandedUiEventsLogger, taskStackListener,
+        return new OneHandedController(context, shellController, displayController, organizer,
+                touchHandler, tutorialHandler, settingsUtil, accessibilityUtil, timeoutHandler,
+                oneHandedState, oneHandedUiEventsLogger, taskStackListener,
                 mainExecutor, mainHandler);
     }
 
     @VisibleForTesting
     OneHandedController(Context context,
+            ShellController shellController,
             DisplayController displayController,
             OneHandedDisplayAreaOrganizer displayAreaOrganizer,
             OneHandedTouchHandler touchHandler,
@@ -228,6 +235,7 @@
             ShellExecutor mainExecutor,
             Handler mainHandler) {
         mContext = context;
+        mShellController = shellController;
         mOneHandedSettingsUtil = settingsUtil;
         mOneHandedAccessibilityUtil = oneHandedAccessibilityUtil;
         mDisplayAreaOrganizer = displayAreaOrganizer;
@@ -272,6 +280,8 @@
                 mAccessibilityStateChangeListener);
 
         mState.addSListeners(mTutorialHandler);
+        mShellController.addConfigurationChangeListener(this);
+        mShellController.addKeyguardChangeListener(this);
     }
 
     public OneHanded asOneHanded() {
@@ -587,7 +597,8 @@
         mLockedDisabled = locked && !enabled;
     }
 
-    private void onConfigChanged(Configuration newConfig) {
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
         if (mTutorialHandler == null) {
             return;
         }
@@ -597,8 +608,11 @@
         mTutorialHandler.onConfigurationChanged();
     }
 
-    private void onKeyguardVisibilityChanged(boolean showing) {
-        mKeyguardShowing = showing;
+    @Override
+    public void onKeyguardVisibilityChanged(boolean visible, boolean occluded,
+            boolean animatingDismiss) {
+        mKeyguardShowing = visible;
+        stopOneHanded();
     }
 
     private void onUserSwitch(int newUserId) {
@@ -667,9 +681,12 @@
             return;
         }
 
+        if (mState.getState() == STATE_ACTIVE) {
+            mOneHandedUiEventLogger.writeEvent(
+                    OneHandedUiEventLogger.EVENT_ONE_HANDED_TRIGGER_ROTATION_OUT);
+        }
+
         mDisplayAreaOrganizer.onRotateDisplay(mContext, toRotation, wct);
-        mOneHandedUiEventLogger.writeEvent(
-                OneHandedUiEventLogger.EVENT_ONE_HANDED_TRIGGER_ROTATION_OUT);
     }
 
     /**
@@ -743,25 +760,11 @@
         }
 
         @Override
-        public void onConfigChanged(Configuration newConfig) {
-            mMainExecutor.execute(() -> {
-                OneHandedController.this.onConfigChanged(newConfig);
-            });
-        }
-
-        @Override
         public void onUserSwitch(int userId) {
             mMainExecutor.execute(() -> {
                 OneHandedController.this.onUserSwitch(userId);
             });
         }
-
-        @Override
-        public void onKeyguardVisibilityChanged(boolean showing) {
-            mMainExecutor.execute(() -> {
-                OneHandedController.this.onKeyguardVisibilityChanged(showing);
-            });
-        }
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
index f61d1b9..451afa0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
@@ -159,6 +159,10 @@
 
     @Override
     public void onDisplayAreaVanished(@NonNull DisplayAreaInfo displayAreaInfo) {
+        final SurfaceControl leash = mDisplayAreaTokenMap.get(displayAreaInfo.token);
+        if (leash != null) {
+            leash.release();
+        }
         mDisplayAreaTokenMap.remove(displayAreaInfo.token);
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java
index bbc47e4..38631ce 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java
@@ -16,7 +16,6 @@
 
 package com.android.wm.shell.pip;
 
-import android.content.res.Configuration;
 import android.graphics.Rect;
 
 import com.android.wm.shell.common.annotations.ExternalThread;
@@ -44,24 +43,6 @@
     }
 
     /**
-     * Called when configuration is changed.
-     */
-    default void onConfigurationChanged(Configuration newConfig) {
-    }
-
-    /**
-     * Called when display size or font size of settings changed
-     */
-    default void onDensityOrFontScaleChanged() {
-    }
-
-    /**
-     * Called when overlay package change invoked.
-     */
-    default void onOverlayChanged() {
-    }
-
-    /**
      * Called when SysUI state changed.
      *
      * @param isSysUiStateValid Is SysUI state valid or not.
@@ -120,23 +101,6 @@
     default void removePipExclusionBoundsChangeListener(Consumer<Rect> listener) { }
 
     /**
-     * Called when the visibility of keyguard is changed.
-     * @param showing {@code true} if keyguard is now showing, {@code false} otherwise.
-     * @param animating {@code true} if system is animating between keyguard and surface behind,
-     *                              this only makes sense when showing is {@code false}.
-     */
-    default void onKeyguardVisibilityChanged(boolean showing, boolean animating) { }
-
-    /**
-     * Called when the dismissing animation keyguard and surfaces behind is finished.
-     * See also {@link #onKeyguardVisibilityChanged(boolean, boolean)}.
-     *
-     * TODO(b/206741900) deprecate this path once we're able to animate the PiP window as part of
-     * keyguard dismiss animation.
-     */
-    default void onKeyguardDismissAnimationFinished() { }
-
-    /**
      * Dump the current state and information if need.
      *
      * @param pw The stream to dump information to.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java
index 16f1d1c..0006244 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java
@@ -26,11 +26,14 @@
 import android.annotation.Nullable;
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.RemoteAction;
+import android.content.Context;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.view.SurfaceControl;
 import android.view.WindowManager;
 
+import com.android.wm.shell.R;
+
 import java.util.List;
 
 /**
@@ -97,16 +100,20 @@
 
     /**
      * Returns a default LayoutParams for the PIP Menu.
+     * @param context the context.
      * @param width the PIP stack width.
      * @param height the PIP stack height.
      */
-    default WindowManager.LayoutParams getPipMenuLayoutParams(String title, int width, int height) {
+    default WindowManager.LayoutParams getPipMenuLayoutParams(Context context, String title,
+            int width, int height) {
         final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, height,
                 TYPE_APPLICATION_OVERLAY,
                 FLAG_WATCH_OUTSIDE_TOUCH | FLAG_SPLIT_TOUCH | FLAG_SLIPPERY | FLAG_NOT_TOUCHABLE,
                 PixelFormat.TRANSLUCENT);
         lp.privateFlags |= PRIVATE_FLAG_TRUSTED_OVERLAY;
         lp.setTitle(title);
+        lp.accessibilityTitle = context.getResources().getString(
+                R.string.pip_menu_accessibility_title);
         return lp;
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index 22b0ccb..da88c2d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -943,6 +943,7 @@
         mPipBoundsState.setBounds(new Rect());
         mPipUiEventLoggerLogger.setTaskInfo(null);
         mMainExecutor.executeDelayed(() -> mPipMenuController.detach(), 0);
+        mLeash = null;
 
         if (info.displayId != Display.DEFAULT_DISPLAY && mOnDisplayIdChangeCallback != null) {
             mOnDisplayIdChangeCallback.accept(Display.DEFAULT_DISPLAY);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index 05a890f..51be2a5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -315,7 +315,7 @@
     }
 
     @Override
-    public void onTransitionMerged(@NonNull IBinder transition) {
+    public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted) {
         if (transition != mExitTransition) {
             return;
         }
@@ -328,7 +328,7 @@
         }
         // Unset exitTransition AFTER cancel so that finishResize knows we are merging.
         mExitTransition = null;
-        if (!cancelled) return;
+        if (!cancelled || aborted) return;
         final ActivityManager.RunningTaskInfo taskInfo = mPipOrganizer.getTaskInfo();
         if (taskInfo != null) {
             startExpandAnimation(taskInfo, mPipOrganizer.getSurfaceControl(),
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
index 4942987..504dc02 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
@@ -181,7 +181,7 @@
         mPipMenuView = new PipMenuView(mContext, this, mMainExecutor, mMainHandler,
                 mSplitScreenController, mPipUiEventLogger);
         mSystemWindows.addView(mPipMenuView,
-                getPipMenuLayoutParams(MENU_WINDOW_TITLE, 0 /* width */, 0 /* height */),
+                getPipMenuLayoutParams(mContext, MENU_WINDOW_TITLE, 0 /* width */, 0 /* height */),
                 0, SHELL_ROOT_LAYER_PIP);
         setShellRootAccessibilityWindow();
 
@@ -206,7 +206,7 @@
     @Override
     public void updateMenuBounds(Rect destinationBounds) {
         mSystemWindows.updateViewLayout(mPipMenuView,
-                getPipMenuLayoutParams(MENU_WINDOW_TITLE, destinationBounds.width(),
+                getPipMenuLayoutParams(mContext, MENU_WINDOW_TITLE, destinationBounds.width(),
                         destinationBounds.height()));
         updateMenuLayout(destinationBounds);
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index 3000998..420d606 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -87,6 +87,9 @@
 import com.android.wm.shell.pip.PipTransitionState;
 import com.android.wm.shell.pip.PipUtils;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
+import com.android.wm.shell.sysui.ConfigurationChangeListener;
+import com.android.wm.shell.sysui.KeyguardChangeListener;
+import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.transition.Transitions;
 
 import java.io.PrintWriter;
@@ -100,7 +103,7 @@
  * Manages the picture-in-picture (PIP) UI and states for Phones.
  */
 public class PipController implements PipTransitionController.PipTransitionCallback,
-        RemoteCallable<PipController> {
+        RemoteCallable<PipController>, ConfigurationChangeListener, KeyguardChangeListener {
     private static final String TAG = "PipController";
 
     private Context mContext;
@@ -119,6 +122,7 @@
     private TaskStackListenerImpl mTaskStackListener;
     private PipParamsChangedForwarder mPipParamsChangedForwarder;
     private Optional<OneHandedController> mOneHandedController;
+    private final ShellController mShellController;
     protected final PipImpl mImpl;
 
     private final Rect mTmpInsetBounds = new Rect();
@@ -290,13 +294,20 @@
      * Instantiates {@link PipController}, returns {@code null} if the feature not supported.
      */
     @Nullable
-    public static Pip create(Context context, DisplayController displayController,
-            PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm,
-            PipKeepClearAlgorithm pipKeepClearAlgorithm, PipBoundsState pipBoundsState,
-            PipMotionHelper pipMotionHelper, PipMediaController pipMediaController,
-            PhonePipMenuController phonePipMenuController, PipTaskOrganizer pipTaskOrganizer,
+    public static Pip create(Context context,
+            ShellController shellController,
+            DisplayController displayController,
+            PipAppOpsListener pipAppOpsListener,
+            PipBoundsAlgorithm pipBoundsAlgorithm,
+            PipKeepClearAlgorithm pipKeepClearAlgorithm,
+            PipBoundsState pipBoundsState,
+            PipMotionHelper pipMotionHelper,
+            PipMediaController pipMediaController,
+            PhonePipMenuController phonePipMenuController,
+            PipTaskOrganizer pipTaskOrganizer,
             PipTransitionState pipTransitionState,
-            PipTouchHandler pipTouchHandler, PipTransitionController pipTransitionController,
+            PipTouchHandler pipTouchHandler,
+            PipTransitionController pipTransitionController,
             WindowManagerShellWrapper windowManagerShellWrapper,
             TaskStackListenerImpl taskStackListener,
             PipParamsChangedForwarder pipParamsChangedForwarder,
@@ -308,9 +319,9 @@
             return null;
         }
 
-        return new PipController(context, displayController, pipAppOpsListener, pipBoundsAlgorithm,
-                pipKeepClearAlgorithm, pipBoundsState, pipMotionHelper, pipMediaController,
-                phonePipMenuController, pipTaskOrganizer, pipTransitionState,
+        return new PipController(context, shellController, displayController, pipAppOpsListener,
+                pipBoundsAlgorithm, pipKeepClearAlgorithm, pipBoundsState, pipMotionHelper,
+                pipMediaController, phonePipMenuController, pipTaskOrganizer, pipTransitionState,
                 pipTouchHandler, pipTransitionController,
                 windowManagerShellWrapper, taskStackListener, pipParamsChangedForwarder,
                 oneHandedController, mainExecutor)
@@ -318,6 +329,7 @@
     }
 
     protected PipController(Context context,
+            ShellController shellController,
             DisplayController displayController,
             PipAppOpsListener pipAppOpsListener,
             PipBoundsAlgorithm pipBoundsAlgorithm,
@@ -343,6 +355,7 @@
         }
 
         mContext = context;
+        mShellController = shellController;
         mImpl = new PipImpl();
         mWindowManagerShellWrapper = windowManagerShellWrapper;
         mDisplayController = displayController;
@@ -513,6 +526,9 @@
                         }
                     });
         });
+
+        mShellController.addConfigurationChangeListener(this);
+        mShellController.addKeyguardChangeListener(this);
     }
 
     @Override
@@ -525,18 +541,21 @@
         return mMainExecutor;
     }
 
-    private void onConfigurationChanged(Configuration newConfig) {
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
         mPipBoundsAlgorithm.onConfigurationChanged(mContext);
         mTouchHandler.onConfigurationChanged();
         mPipBoundsState.onConfigurationChanged();
     }
 
-    private void onDensityOrFontScaleChanged() {
+    @Override
+    public void onDensityOrFontScaleChanged() {
         mPipTaskOrganizer.onDensityOrFontScaleChanged(mContext);
         onPipResourceDimensionsChanged();
     }
 
-    private void onOverlayChanged() {
+    @Override
+    public void onThemeChanged() {
         mTouchHandler.onOverlayChanged();
         onDisplayChanged(new DisplayLayout(mContext, mContext.getDisplay()),
                 false /* saveRestoreSnapFraction */);
@@ -644,21 +663,24 @@
      * finished first to reset the visibility of PiP window.
      * See also {@link #onKeyguardDismissAnimationFinished()}
      */
-    private void onKeyguardVisibilityChanged(boolean keyguardShowing, boolean animating) {
+    @Override
+    public void onKeyguardVisibilityChanged(boolean visible, boolean occluded,
+            boolean animatingDismiss) {
         if (!mPipTaskOrganizer.isInPip()) {
             return;
         }
-        if (keyguardShowing) {
+        if (visible) {
             mIsKeyguardShowingOrAnimating = true;
             hidePipMenu(null /* onStartCallback */, null /* onEndCallback */);
             mPipTaskOrganizer.setPipVisibility(false);
-        } else if (!animating) {
+        } else if (!animatingDismiss) {
             mIsKeyguardShowingOrAnimating = false;
             mPipTaskOrganizer.setPipVisibility(true);
         }
     }
 
-    private void onKeyguardDismissAnimationFinished() {
+    @Override
+    public void onKeyguardDismissAnimationFinished() {
         if (mPipTaskOrganizer.isInPip()) {
             mIsKeyguardShowingOrAnimating = false;
             mPipTaskOrganizer.setPipVisibility(true);
@@ -923,27 +945,6 @@
         }
 
         @Override
-        public void onConfigurationChanged(Configuration newConfig) {
-            mMainExecutor.execute(() -> {
-                PipController.this.onConfigurationChanged(newConfig);
-            });
-        }
-
-        @Override
-        public void onDensityOrFontScaleChanged() {
-            mMainExecutor.execute(() -> {
-                PipController.this.onDensityOrFontScaleChanged();
-            });
-        }
-
-        @Override
-        public void onOverlayChanged() {
-            mMainExecutor.execute(() -> {
-                PipController.this.onOverlayChanged();
-            });
-        }
-
-        @Override
         public void onSystemUiStateChanged(boolean isSysUiStateValid, int flag) {
             mMainExecutor.execute(() -> {
                 PipController.this.onSystemUiStateChanged(isSysUiStateValid, flag);
@@ -1000,18 +1001,6 @@
         }
 
         @Override
-        public void onKeyguardVisibilityChanged(boolean showing, boolean animating) {
-            mMainExecutor.execute(() -> {
-                PipController.this.onKeyguardVisibilityChanged(showing, animating);
-            });
-        }
-
-        @Override
-        public void onKeyguardDismissAnimationFinished() {
-            mMainExecutor.execute(PipController.this::onKeyguardDismissAnimationFinished);
-        }
-
-        @Override
         public void dump(PrintWriter pw) {
             try {
                 mMainExecutor.executeBlocking(() -> {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
index fa48def..a24d9618 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
@@ -49,6 +49,8 @@
 import com.android.wm.shell.pip.PipTaskOrganizer;
 import com.android.wm.shell.pip.PipTransitionController;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
+import com.android.wm.shell.sysui.ConfigurationChangeListener;
+import com.android.wm.shell.sysui.ShellController;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -61,7 +63,8 @@
  */
 public class TvPipController implements PipTransitionController.PipTransitionCallback,
         TvPipBoundsController.PipBoundsListener, TvPipMenuController.Delegate,
-        TvPipNotificationController.Delegate, DisplayController.OnDisplaysChangedListener {
+        TvPipNotificationController.Delegate, DisplayController.OnDisplaysChangedListener,
+        ConfigurationChangeListener {
     private static final String TAG = "TvPipController";
     static final boolean DEBUG = false;
 
@@ -93,6 +96,7 @@
 
     private final Context mContext;
 
+    private final ShellController mShellController;
     private final TvPipBoundsState mTvPipBoundsState;
     private final TvPipBoundsAlgorithm mTvPipBoundsAlgorithm;
     private final TvPipBoundsController mTvPipBoundsController;
@@ -117,6 +121,7 @@
 
     public static Pip create(
             Context context,
+            ShellController shellController,
             TvPipBoundsState tvPipBoundsState,
             TvPipBoundsAlgorithm tvPipBoundsAlgorithm,
             TvPipBoundsController tvPipBoundsController,
@@ -133,6 +138,7 @@
             ShellExecutor mainExecutor) {
         return new TvPipController(
                 context,
+                shellController,
                 tvPipBoundsState,
                 tvPipBoundsAlgorithm,
                 tvPipBoundsController,
@@ -151,6 +157,7 @@
 
     private TvPipController(
             Context context,
+            ShellController shellController,
             TvPipBoundsState tvPipBoundsState,
             TvPipBoundsAlgorithm tvPipBoundsAlgorithm,
             TvPipBoundsController tvPipBoundsController,
@@ -167,6 +174,7 @@
             ShellExecutor mainExecutor) {
         mContext = context;
         mMainExecutor = mainExecutor;
+        mShellController = shellController;
 
         mTvPipBoundsState = tvPipBoundsState;
         mTvPipBoundsState.setDisplayId(context.getDisplayId());
@@ -193,9 +201,12 @@
         registerTaskStackListenerCallback(taskStackListener);
         registerWmShellPinnedStackListener(wmShell);
         displayController.addDisplayWindowListener(this);
+
+        mShellController.addConfigurationChangeListener(this);
     }
 
-    private void onConfigurationChanged(Configuration newConfig) {
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
         if (DEBUG) {
             ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                     "%s: onConfigurationChanged(), state=%s", TAG, stateToName(mState));
@@ -669,13 +680,6 @@
 
     private class TvPipImpl implements Pip {
         @Override
-        public void onConfigurationChanged(Configuration newConfig) {
-            mMainExecutor.execute(() -> {
-                TvPipController.this.onConfigurationChanged(newConfig);
-            });
-        }
-
-        @Override
         public void registerSessionListenerForCurrentUser() {
             mMainExecutor.execute(() -> {
                 TvPipController.this.registerSessionListenerForCurrentUser();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
index 4ce45e1..a4e9062 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
@@ -193,14 +193,14 @@
     }
 
     private void addPipMenuViewToSystemWindows(View v, String title) {
-        mSystemWindows.addView(v, getPipMenuLayoutParams(title, 0 /* width */, 0 /* height */),
-                0 /* displayId */, SHELL_ROOT_LAYER_PIP);
+        mSystemWindows.addView(v, getPipMenuLayoutParams(mContext, title, 0 /* width */,
+                0 /* height */), 0 /* displayId */, SHELL_ROOT_LAYER_PIP);
     }
 
     void notifyPipAnimating(boolean animating) {
         mPipMenuView.setEduTextActive(!animating);
         if (!animating) {
-            mPipMenuView.onPipTransitionFinished();
+            mPipMenuView.onPipTransitionFinished(mTvPipBoundsState.isTvPipExpanded());
         }
     }
 
@@ -267,7 +267,6 @@
     void updateExpansionState() {
         mPipMenuView.setExpandedModeEnabled(mTvPipBoundsState.isTvExpandedPipSupported()
                 && mTvPipBoundsState.getDesiredTvExpandedAspectRatio() != 0);
-        mPipMenuView.setIsExpanded(mTvPipBoundsState.isTvPipExpanded());
     }
 
     private Rect calculateMenuSurfaceBounds(Rect pipBounds) {
@@ -573,10 +572,10 @@
                     "%s: updateMenuBounds: %s", TAG, menuBounds.toShortString());
         }
         mSystemWindows.updateViewLayout(mPipBackgroundView,
-                getPipMenuLayoutParams(BACKGROUND_WINDOW_TITLE, menuBounds.width(),
+                getPipMenuLayoutParams(mContext, BACKGROUND_WINDOW_TITLE, menuBounds.width(),
                         menuBounds.height()));
         mSystemWindows.updateViewLayout(mPipMenuView,
-                getPipMenuLayoutParams(MENU_WINDOW_TITLE, menuBounds.width(),
+                getPipMenuLayoutParams(mContext, MENU_WINDOW_TITLE, menuBounds.width(),
                         menuBounds.height()));
 
         if (mPipMenuView != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
index 1c30755..57d3a44 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
@@ -266,7 +266,7 @@
         }
     }
 
-    void onPipTransitionFinished() {
+    void onPipTransitionFinished(boolean isTvPipExpanded) {
         ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                 "%s: onPipTransitionFinished()", TAG);
 
@@ -277,6 +277,8 @@
                 .setInterpolator(TvPipInterpolators.ENTER)
                 .start();
 
+        setIsExpanded(isTvPipExpanded);
+
         // Update buttons.
         if (mSwitchingOrientation) {
             mActionButtonsContainer.animate()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
index d04c349..b296151 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
@@ -26,6 +26,8 @@
 public enum ShellProtoLogGroup implements IProtoLogGroup {
     // NOTE: Since we enable these from the same WM ShellCommand, these names should not conflict
     // with those in the framework ProtoLogGroup
+    WM_SHELL_INIT(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true,
+            Consts.TAG_WM_SHELL),
     WM_SHELL_TASK_ORG(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
             Consts.TAG_WM_SHELL),
     WM_SHELL_TRANSITIONS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true,
@@ -38,10 +40,12 @@
             "ShellBackPreview"),
     WM_SHELL_RECENT_TASKS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
             Consts.TAG_WM_SHELL),
-    WM_SHELL_PICTURE_IN_PICTURE(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG,
-            false, Consts.TAG_WM_SHELL),
+    WM_SHELL_PICTURE_IN_PICTURE(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+            Consts.TAG_WM_SHELL),
     WM_SHELL_SPLIT_SCREEN(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
             Consts.TAG_WM_SHELL),
+    WM_SHELL_SYSUI_EVENTS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+            Consts.TAG_WM_SHELL),
     TEST_GROUP(true, true, false, "WindowManagerShellProtoLogTest");
 
     private final boolean mEnabled;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
index 2bfa5db..b0080b2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
@@ -16,6 +16,9 @@
 
 package com.android.wm.shell.splitscreen;
 
+import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
+import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
+
 import android.content.Context;
 import android.view.SurfaceSession;
 import android.window.WindowContainerToken;
@@ -42,6 +45,11 @@
                 iconProvider);
     }
 
+    @Override
+    void dismiss(WindowContainerTransaction wct, boolean toTop) {
+        deactivate(wct, toTop);
+    }
+
     boolean isActive() {
         return mIsActive;
     }
@@ -74,10 +82,10 @@
         if (mRootTaskInfo == null) return;
         final WindowContainerToken rootToken = mRootTaskInfo.token;
         wct.reparentTasks(
-                        rootToken,
-                        null /* newParent */,
-                        CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE,
-                        CONTROLLED_ACTIVITY_TYPES,
-                        toTop);
+                rootToken,
+                null /* newParent */,
+                null /* windowingModes */,
+                null /* activityTypes */,
+                toTop);
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
index f92a0d3..86efbe0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
@@ -42,13 +42,18 @@
                 iconProvider);
     }
 
+    @Override
+    void dismiss(WindowContainerTransaction wct, boolean toTop) {
+        removeAllTasks(wct, toTop);
+    }
+
     boolean removeAllTasks(WindowContainerTransaction wct, boolean toTop) {
         if (mChildrenTaskInfo.size() == 0) return false;
         wct.reparentTasks(
                 mRootTaskInfo.token,
                 null /* newParent */,
-                CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE,
-                CONTROLLED_ACTIVITY_TYPES,
+                null /* windowingModes */,
+                null /* activityTypes */,
                 toTop);
         return true;
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
index 29b6311..e73b799 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
@@ -77,12 +77,6 @@
         return null;
     }
 
-    /**
-     * Called when the visibility of the keyguard changes.
-     * @param showing Indicates if the keyguard is now visible.
-     */
-    void onKeyguardVisibilityChanged(boolean showing);
-
     /** Called when device waking up finished. */
     void onFinishedWakingUp();
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index ee49366..53ec39d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -18,6 +18,7 @@
 
 import static android.app.ActivityManager.START_SUCCESS;
 import static android.app.ActivityManager.START_TASK_TO_FRONT;
+import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.RemoteAnimationTarget.MODE_OPENING;
@@ -58,7 +59,9 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.InstanceId;
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
 import com.android.wm.shell.ShellTaskOrganizer;
@@ -74,8 +77,11 @@
 import com.android.wm.shell.common.split.SplitLayout;
 import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
 import com.android.wm.shell.draganddrop.DragAndDropPolicy;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.recents.RecentTasksController;
 import com.android.wm.shell.splitscreen.SplitScreen.StageType;
+import com.android.wm.shell.sysui.KeyguardChangeListener;
+import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.transition.LegacyTransitions;
 import com.android.wm.shell.transition.Transitions;
 
@@ -95,18 +101,18 @@
  */
 // TODO(b/198577848): Implement split screen flicker test to consolidate CUJ of split screen.
 public class SplitScreenController implements DragAndDropPolicy.Starter,
-        RemoteCallable<SplitScreenController> {
+        RemoteCallable<SplitScreenController>, KeyguardChangeListener {
     private static final String TAG = SplitScreenController.class.getSimpleName();
 
-    static final int EXIT_REASON_UNKNOWN = 0;
-    static final int EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW = 1;
-    static final int EXIT_REASON_APP_FINISHED = 2;
-    static final int EXIT_REASON_DEVICE_FOLDED = 3;
-    static final int EXIT_REASON_DRAG_DIVIDER = 4;
-    static final int EXIT_REASON_RETURN_HOME = 5;
-    static final int EXIT_REASON_ROOT_TASK_VANISHED = 6;
-    static final int EXIT_REASON_SCREEN_LOCKED = 7;
-    static final int EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP = 8;
+    public static final int EXIT_REASON_UNKNOWN = 0;
+    public static final int EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW = 1;
+    public static final int EXIT_REASON_APP_FINISHED = 2;
+    public static final int EXIT_REASON_DEVICE_FOLDED = 3;
+    public static final int EXIT_REASON_DRAG_DIVIDER = 4;
+    public static final int EXIT_REASON_RETURN_HOME = 5;
+    public static final int EXIT_REASON_ROOT_TASK_VANISHED = 6;
+    public static final int EXIT_REASON_SCREEN_LOCKED = 7;
+    public static final int EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP = 8;
     public static final int EXIT_REASON_CHILD_TASK_ENTER_PIP = 9;
     @IntDef(value = {
             EXIT_REASON_UNKNOWN,
@@ -123,6 +129,7 @@
     @Retention(RetentionPolicy.SOURCE)
     @interface ExitReason{}
 
+    private final ShellController mShellController;
     private final ShellTaskOrganizer mTaskOrganizer;
     private final SyncTransactionQueue mSyncQueue;
     private final Context mContext;
@@ -143,7 +150,8 @@
     // outside the bounds of the roots by being reparented into a higher level fullscreen container
     private SurfaceControl mSplitTasksContainerLayer;
 
-    public SplitScreenController(ShellTaskOrganizer shellTaskOrganizer,
+    public SplitScreenController(ShellController shellController,
+            ShellTaskOrganizer shellTaskOrganizer,
             SyncTransactionQueue syncQueue, Context context,
             RootTaskDisplayAreaOrganizer rootTDAOrganizer,
             ShellExecutor mainExecutor, DisplayController displayController,
@@ -151,6 +159,7 @@
             DisplayInsetsController displayInsetsController,
             Transitions transitions, TransactionPool transactionPool, IconProvider iconProvider,
             Optional<RecentTasksController> recentTasks) {
+        mShellController = shellController;
         mTaskOrganizer = shellTaskOrganizer;
         mSyncQueue = syncQueue;
         mContext = context;
@@ -181,6 +190,7 @@
     }
 
     public void onOrganizerRegistered() {
+        mShellController.addKeyguardChangeListener(this);
         if (mStageCoordinator == null) {
             // TODO: Multi-display
             mStageCoordinator = new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
@@ -198,6 +208,14 @@
         return mStageCoordinator;
     }
 
+    public ActivityManager.RunningTaskInfo getFocusingTaskInfo() {
+        return mStageCoordinator.getFocusingTaskInfo();
+    }
+
+    public boolean isValidToEnterSplitScreen(@NonNull ActivityManager.RunningTaskInfo taskInfo) {
+        return mStageCoordinator.isValidToEnterSplitScreen(taskInfo);
+    }
+
     @Nullable
     public ActivityManager.RunningTaskInfo getTaskInfo(@SplitPosition int splitPosition) {
         if (!isSplitScreenVisible() || splitPosition == SPLIT_POSITION_UNDEFINED) {
@@ -271,8 +289,10 @@
         mStageCoordinator.exitSplitScreen(toTopTaskId, exitReason);
     }
 
-    public void onKeyguardVisibilityChanged(boolean showing) {
-        mStageCoordinator.onKeyguardVisibilityChanged(showing);
+    @Override
+    public void onKeyguardVisibilityChanged(boolean visible, boolean occluded,
+            boolean animatingDismiss) {
+        mStageCoordinator.onKeyguardVisibilityChanged(visible);
     }
 
     public void onFinishedWakingUp() {
@@ -341,14 +361,21 @@
             options = mStageCoordinator.resolveStartStage(STAGE_TYPE_UNDEFINED, position, options,
                     null /* wct */);
 
-            // Flag this as a no-user-action launch to prevent sending user leaving event to the
-            // current top activity since it's going to be put into another side of the split. This
-            // prevents the current top activity from going into pip mode due to user leaving event.
             if (fillInIntent == null) {
                 fillInIntent = new Intent();
             }
+            // Flag this as a no-user-action launch to prevent sending user leaving event to the
+            // current top activity since it's going to be put into another side of the split. This
+            // prevents the current top activity from going into pip mode due to user leaving event.
             fillInIntent.addFlags(FLAG_ACTIVITY_NO_USER_ACTION);
 
+            // Flag with MULTIPLE_TASK if this is launching the same activity into both sides of the
+            // split.
+            if (isLaunchingAdjacently(intent.getIntent(), position)) {
+                fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK");
+            }
+
             intent.send(mContext, 0, fillInIntent, null /* onFinished */, null /* handler */,
                     null /* requiredPermission */, options);
         } catch (PendingIntent.CanceledException e) {
@@ -358,6 +385,8 @@
 
     private void startIntentLegacy(PendingIntent intent, @Nullable Intent fillInIntent,
             @SplitPosition int position, @Nullable Bundle options) {
+        boolean startSameActivityAdjacently = isLaunchingAdjacently(intent.getIntent(), position);
+
         final WindowContainerTransaction evictWct = new WindowContainerTransaction();
         mStageCoordinator.prepareEvictChildTasks(position, evictWct);
 
@@ -368,14 +397,7 @@
                     IRemoteAnimationFinishedCallback finishedCallback,
                     SurfaceControl.Transaction t) {
                 if (apps == null || apps.length == 0) {
-                    final ActivityManager.RunningTaskInfo pairedTaskInfo =
-                            getTaskInfo(SplitLayout.reversePosition(position));
-                    final ComponentName pairedActivity = pairedTaskInfo != null
-                            ? pairedTaskInfo.baseIntent.getComponent() : null;
-                    final ComponentName intentActivity = intent.getIntent() != null
-                            ? intent.getIntent().getComponent() : null;
-
-                    if (Objects.equals(pairedActivity, intentActivity)) {
+                    if (startSameActivityAdjacently) {
                         // Switch split position if dragging the same activity to another side.
                         setSideStagePosition(SplitLayout.reversePosition(
                                 mStageCoordinator.getSideStagePosition()));
@@ -417,11 +439,44 @@
             fillInIntent = new Intent();
         }
         fillInIntent.addFlags(FLAG_ACTIVITY_NO_USER_ACTION);
+        if (startSameActivityAdjacently) {
+            fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK");
+        }
 
         wct.sendPendingIntent(intent, fillInIntent, options);
         mSyncQueue.queue(transition, WindowManager.TRANSIT_OPEN, wct);
     }
 
+    /** Returns {@code true} if it's launching the same component on both sides of the split. */
+    @VisibleForTesting
+    boolean isLaunchingAdjacently(@Nullable Intent startIntent,
+            @SplitPosition int position) {
+        if (startIntent == null) {
+            return false;
+        }
+
+        final ComponentName launchingActivity = startIntent.getComponent();
+        if (launchingActivity == null) {
+            return false;
+        }
+
+        if (isSplitScreenVisible()) {
+            final ActivityManager.RunningTaskInfo pairedTaskInfo =
+                    getTaskInfo(SplitLayout.reversePosition(position));
+            final ComponentName pairedActivity = pairedTaskInfo != null
+                    ? pairedTaskInfo.baseIntent.getComponent() : null;
+            return Objects.equals(launchingActivity, pairedActivity);
+        }
+
+        final ActivityManager.RunningTaskInfo taskInfo = getFocusingTaskInfo();
+        if (taskInfo != null && isValidToEnterSplitScreen(taskInfo)) {
+            return Objects.equals(taskInfo.baseIntent.getComponent(), launchingActivity);
+        }
+
+        return false;
+    }
+
     RemoteAnimationTarget[] onGoingToRecentsLegacy(RemoteAnimationTarget[] apps) {
         if (isSplitScreenVisible()) {
             // Evict child tasks except the top visible one under split root to ensure it could be
@@ -434,7 +489,15 @@
     }
 
     RemoteAnimationTarget[] onStartingSplitLegacy(RemoteAnimationTarget[] apps) {
-        return reparentSplitTasksForAnimation(apps, false /*splitExpectedToBeVisible*/);
+        try {
+            return reparentSplitTasksForAnimation(apps, false /*splitExpectedToBeVisible*/);
+        } finally {
+            for (RemoteAnimationTarget appTarget : apps) {
+                if (appTarget.leash != null) {
+                    appTarget.leash.release();
+                }
+            }
+        }
     }
 
     private RemoteAnimationTarget[] reparentSplitTasksForAnimation(RemoteAnimationTarget[] apps,
@@ -603,13 +666,6 @@
         }
 
         @Override
-        public void onKeyguardVisibilityChanged(boolean showing) {
-            mMainExecutor.execute(() -> {
-                SplitScreenController.this.onKeyguardVisibilityChanged(showing);
-            });
-        }
-
-        @Override
         public void onFinishedWakingUp() {
             mMainExecutor.execute(() -> {
                 SplitScreenController.this.onFinishedWakingUp();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
index e55729a..056cd58 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
@@ -246,7 +246,9 @@
         return true;
     }
 
-    void onTransitionMerged(@NonNull IBinder transition) {
+    void onTransitionConsumed(@NonNull IBinder transition, boolean aborted) {
+        if (aborted) return;
+
         // Once a pending enter transition got merged, make sure to append the reset of finishing
         // operations to the finish transition.
         if (transition == mPendingEnter) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 59b0afe..2229e26 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -35,6 +35,8 @@
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER;
 
 import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_ALIGN_CENTER;
+import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
+import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
@@ -87,6 +89,7 @@
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
 import android.view.WindowManager;
+import android.widget.Toast;
 import android.window.DisplayAreaInfo;
 import android.window.RemoteTransition;
 import android.window.TransitionInfo;
@@ -97,7 +100,9 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.InstanceId;
 import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.util.ArrayUtils;
 import com.android.launcher3.icons.IconProvider;
+import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayImeController;
@@ -136,7 +141,7 @@
  */
 public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
         DisplayController.OnDisplaysChangedListener, Transitions.TransitionHandler,
-        ShellTaskOrganizer.TaskListener {
+        ShellTaskOrganizer.TaskListener, ShellTaskOrganizer.FocusListener {
 
     private static final String TAG = StageCoordinator.class.getSimpleName();
 
@@ -171,6 +176,11 @@
     private final ShellExecutor mMainExecutor;
     private final Optional<RecentTasksController> mRecentTasks;
 
+    private final Rect mTempRect1 = new Rect();
+    private final Rect mTempRect2 = new Rect();
+
+    private ActivityManager.RunningTaskInfo mFocusingTaskInfo;
+
     /**
      * A single-top root task which the split divider attached to.
      */
@@ -184,6 +194,7 @@
     private boolean mShouldUpdateRecents;
     private boolean mExitSplitScreenOnHide;
     private boolean mIsDividerRemoteAnimating;
+    private boolean mIsExiting;
     private boolean mResizingSplits;
 
     /** The target stage to dismiss to when unlock after folded. */
@@ -249,6 +260,7 @@
         mDisplayController.addDisplayWindowListener(this);
         mDisplayLayout = new DisplayLayout(displayController.getDisplayLayout(displayId));
         transitions.addHandler(this);
+        mTaskOrganizer.addFocusListener(this);
     }
 
     @VisibleForTesting
@@ -437,7 +449,7 @@
                         new IRemoteAnimationFinishedCallback.Stub() {
                             @Override
                             public void onAnimationFinished() throws RemoteException {
-                                onRemoteAnimationFinishedOrCancelled(evictWct);
+                                onRemoteAnimationFinishedOrCancelled(false /* cancel */, evictWct);
                                 finishedCallback.onAnimationFinished();
                             }
                         };
@@ -458,7 +470,7 @@
 
             @Override
             public void onAnimationCancelled(boolean isKeyguardOccluded) {
-                onRemoteAnimationFinishedOrCancelled(evictWct);
+                onRemoteAnimationFinishedOrCancelled(true /* cancel */, evictWct);
                 try {
                     adapter.getRunner().onAnimationCancelled(isKeyguardOccluded);
                 } catch (RemoteException e) {
@@ -508,13 +520,14 @@
         });
     }
 
-    private void onRemoteAnimationFinishedOrCancelled(WindowContainerTransaction evictWct) {
+    private void onRemoteAnimationFinishedOrCancelled(boolean cancel,
+            WindowContainerTransaction evictWct) {
         mIsDividerRemoteAnimating = false;
         mShouldUpdateRecents = true;
         // If any stage has no child after animation finished, it means that split will display
         // nothing, such status will happen if task and intent is same app but not support
         // multi-instagce, we should exit split and expand that app as full screen.
-        if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0) {
+        if (!cancel && (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0)) {
             mMainExecutor.execute(() ->
                     exitSplitScreen(mMainStage.getChildCount() == 0
                         ? mSideStage : mMainStage, EXIT_REASON_UNKNOWN));
@@ -728,7 +741,7 @@
 
     private void applyExitSplitScreen(@Nullable StageTaskListener childrenToTop,
             WindowContainerTransaction wct, @ExitReason int exitReason) {
-        if (!mMainStage.isActive()) return;
+        if (!mMainStage.isActive() || mIsExiting) return;
 
         mRecentTasks.ifPresent(recentTasks -> {
             // Notify recents if we are exiting in a way that breaks the pair, and disable further
@@ -740,22 +753,45 @@
         });
         mShouldUpdateRecents = false;
 
-        // When the exit split-screen is caused by one of the task enters auto pip,
-        // we want the tasks to be put to bottom instead of top, otherwise it will end up
-        // a fullscreen plus a pinned task instead of pinned only at the end of the transition.
-        final boolean fromEnteringPip = exitReason == EXIT_REASON_CHILD_TASK_ENTER_PIP;
-        mSideStage.removeAllTasks(wct, !fromEnteringPip && mSideStage == childrenToTop);
-        mMainStage.deactivate(wct, !fromEnteringPip && mMainStage == childrenToTop);
-        wct.reorder(mRootTaskInfo.token, false /* onTop */);
-        mTaskOrganizer.applyTransaction(wct);
+        if (childrenToTop == null) {
+            mSideStage.removeAllTasks(wct, false /* toTop */);
+            mMainStage.deactivate(wct, false /* toTop */);
+            wct.reorder(mRootTaskInfo.token, false /* onTop */);
+            onTransitionAnimationComplete();
+        } else {
+            // Expand to top side split as full screen for fading out decor animation and dismiss
+            // another side split(Moving its children to bottom).
+            mIsExiting = true;
+            final StageTaskListener tempFullStage = childrenToTop;
+            final StageTaskListener dismissStage = mMainStage == childrenToTop
+                    ? mSideStage : mMainStage;
+            tempFullStage.resetBounds(wct);
+            wct.setSmallestScreenWidthDp(tempFullStage.mRootTaskInfo.token,
+                    mRootTaskInfo.configuration.smallestScreenWidthDp);
+            dismissStage.dismiss(wct, false /* toTop */);
+        }
+        mSyncQueue.queue(wct);
         mSyncQueue.runInSync(t -> {
-            setResizingSplits(false /* resizing */);
             t.setWindowCrop(mMainStage.mRootLeash, null)
                     .setWindowCrop(mSideStage.mRootLeash, null);
+            t.setPosition(mMainStage.mRootLeash, 0, 0)
+                    .setPosition(mSideStage.mRootLeash, 0, 0);
             setDividerVisibility(false, t);
+
+            // In this case, exit still under progress, fade out the split decor after first WCT
+            // done and do remaining WCT after animation finished.
+            if (childrenToTop != null) {
+                childrenToTop.fadeOutDecor(() -> {
+                    WindowContainerTransaction finishedWCT = new WindowContainerTransaction();
+                    mIsExiting = false;
+                    childrenToTop.dismiss(finishedWCT, true /* toTop */);
+                    wct.reorder(mRootTaskInfo.token, false /* toTop */);
+                    mTaskOrganizer.applyTransaction(finishedWCT);
+                    onTransitionAnimationComplete();
+                });
+            }
         });
 
-        onTransitionAnimationComplete();
         Slog.i(TAG, "applyExitSplitScreen, reason = " + exitReasonToString(exitReason));
         // Log the exit
         if (childrenToTop != null) {
@@ -925,9 +961,11 @@
         }
     }
 
-    private void onStageChildTaskEnterPip(StageListenerImpl stageListener, int taskId) {
-        exitSplitScreen(stageListener == mMainStageListener ? mMainStage : mSideStage,
-                EXIT_REASON_CHILD_TASK_ENTER_PIP);
+    private void onStageChildTaskEnterPip() {
+        // When the exit split-screen is caused by one of the task enters auto pip,
+        // we want both tasks to be put to bottom instead of top, otherwise it will end up
+        // a fullscreen plus a pinned task instead of pinned only at the end of the transition.
+        exitSplitScreen(null, EXIT_REASON_CHILD_TASK_ENTER_PIP);
     }
 
     private void updateRecentTasksSplitPair() {
@@ -1022,6 +1060,7 @@
         }
 
         mRootTaskInfo = null;
+        mRootTaskLeash = null;
     }
 
 
@@ -1148,12 +1187,11 @@
                         mDividerFadeInAnimator.cancel();
                         return;
                     }
+                    mSplitLayout.getRefDividerBounds(mTempRect1);
                     transaction.show(dividerLeash);
                     transaction.setAlpha(dividerLeash, 0);
                     transaction.setLayer(dividerLeash, Integer.MAX_VALUE);
-                    transaction.setPosition(dividerLeash,
-                                    mSplitLayout.getRefDividerBounds().left,
-                                    mSplitLayout.getRefDividerBounds().top);
+                    transaction.setPosition(dividerLeash, mTempRect1.left, mTempRect1.top);
                     transaction.apply();
                 }
 
@@ -1173,21 +1211,42 @@
     private void onStageHasChildrenChanged(StageListenerImpl stageListener) {
         final boolean hasChildren = stageListener.mHasChildren;
         final boolean isSideStage = stageListener == mSideStageListener;
-        if (!hasChildren) {
+        if (!hasChildren && !mIsExiting) {
             if (isSideStage && mMainStageListener.mVisible) {
                 // Exit to main stage if side stage no longer has children.
-                exitSplitScreen(mMainStage, EXIT_REASON_APP_FINISHED);
+                if (ENABLE_SHELL_TRANSITIONS) {
+                    exitSplitScreen(mMainStage, EXIT_REASON_APP_FINISHED);
+                } else {
+                    mSplitLayout.flingDividerToDismiss(
+                            mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT,
+                            EXIT_REASON_APP_FINISHED);
+                }
             } else if (!isSideStage && mSideStageListener.mVisible) {
                 // Exit to side stage if main stage no longer has children.
-                exitSplitScreen(mSideStage, EXIT_REASON_APP_FINISHED);
+                if (ENABLE_SHELL_TRANSITIONS) {
+                    exitSplitScreen(mSideStage, EXIT_REASON_APP_FINISHED);
+                } else {
+                    mSplitLayout.flingDividerToDismiss(
+                            mSideStagePosition != SPLIT_POSITION_BOTTOM_OR_RIGHT,
+                            EXIT_REASON_APP_FINISHED);
+                }
             }
         } else if (isSideStage && !mMainStage.isActive()) {
-            final WindowContainerTransaction wct = new WindowContainerTransaction();
-            mSplitLayout.init();
-            prepareEnterSplitScreen(wct);
-            mSyncQueue.queue(wct);
-            mSyncQueue.runInSync(t ->
-                    updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */));
+            if (mFocusingTaskInfo != null && !isValidToEnterSplitScreen(mFocusingTaskInfo)) {
+                final WindowContainerTransaction wct = new WindowContainerTransaction();
+                mSideStage.removeAllTasks(wct, true);
+                wct.reorder(mRootTaskInfo.token, false /* onTop */);
+                mTaskOrganizer.applyTransaction(wct);
+                Slog.i(TAG, "cancel entering split screen, reason = "
+                        + exitReasonToString(EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW));
+            } else {
+                final WindowContainerTransaction wct = new WindowContainerTransaction();
+                mSplitLayout.init();
+                prepareEnterSplitScreen(wct);
+                mSyncQueue.queue(wct);
+                mSyncQueue.runInSync(t ->
+                        updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */));
+            }
         }
         if (mMainStageListener.mHasChildren && mSideStageListener.mHasChildren) {
             mShouldUpdateRecents = true;
@@ -1202,17 +1261,31 @@
         }
     }
 
+    boolean isValidToEnterSplitScreen(@NonNull ActivityManager.RunningTaskInfo taskInfo) {
+        return taskInfo.supportsMultiWindow
+                && ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType())
+                && ArrayUtils.contains(CONTROLLED_WINDOWING_MODES, taskInfo.getWindowingMode());
+    }
+
+    ActivityManager.RunningTaskInfo getFocusingTaskInfo() {
+        return mFocusingTaskInfo;
+    }
+
     @Override
-    public void onSnappedToDismiss(boolean bottomOrRight) {
+    public void onFocusTaskChanged(ActivityManager.RunningTaskInfo taskInfo) {
+        mFocusingTaskInfo = taskInfo;
+    }
+
+    @Override
+    public void onSnappedToDismiss(boolean bottomOrRight, int reason) {
         final boolean mainStageToTop =
                 bottomOrRight ? mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
                         : mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT;
         if (!ENABLE_SHELL_TRANSITIONS) {
-            exitSplitScreen(mainStageToTop ? mMainStage : mSideStage, EXIT_REASON_DRAG_DIVIDER);
+            exitSplitScreen(mainStageToTop ? mMainStage : mSideStage, reason);
             return;
         }
 
-        setResizingSplits(false /* resizing */);
         final int dismissTop = mainStageToTop ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE;
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         prepareExitSplitScreen(dismissTop, wct);
@@ -1243,10 +1316,11 @@
     public void onLayoutSizeChanging(SplitLayout layout) {
         final SurfaceControl.Transaction t = mTransactionPool.acquire();
         t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId());
-        setResizingSplits(true /* resizing */);
         updateSurfaceBounds(layout, t, true /* applyResizingOffset */);
-        mMainStage.onResizing(getMainStageBounds(), t);
-        mSideStage.onResizing(getSideStageBounds(), t);
+        getMainStageBounds(mTempRect1);
+        getSideStageBounds(mTempRect2);
+        mMainStage.onResizing(mTempRect1, mTempRect2, t);
+        mSideStage.onResizing(mTempRect2, mTempRect1, t);
         t.apply();
         mTransactionPool.release(t);
     }
@@ -1258,7 +1332,6 @@
         sendOnBoundsChanged();
         mSyncQueue.queue(wct);
         mSyncQueue.runInSync(t -> {
-            setResizingSplits(false /* resizing */);
             updateSurfaceBounds(layout, t, false /* applyResizingOffset */);
             mMainStage.onResized(t);
             mSideStage.onResized(t);
@@ -1293,16 +1366,6 @@
                 applyResizingOffset);
     }
 
-    void setResizingSplits(boolean resizing) {
-        if (resizing == mResizingSplits) return;
-        try {
-            ActivityTaskManager.getService().setSplitScreenResizing(resizing);
-            mResizingSplits = resizing;
-        } catch (RemoteException e) {
-            Slog.w(TAG, "Error calling setSplitScreenResizing", e);
-        }
-    }
-
     @Override
     public int getSplitItemPosition(WindowContainerToken token) {
         if (token == null) {
@@ -1353,8 +1416,6 @@
     private void onDisplayChange(int displayId, int fromRotation, int toRotation,
             @Nullable DisplayAreaInfo newDisplayAreaInfo, WindowContainerTransaction wct) {
         if (!mMainStage.isActive()) return;
-        // Only do this when shell transition
-        if (!ENABLE_SHELL_TRANSITIONS) return;
 
         mDisplayLayout.rotateTo(mContext.getResources(), toRotation);
         mSplitLayout.rotateTo(toRotation, mDisplayLayout.stableInsets());
@@ -1386,6 +1447,22 @@
                 ? mSplitLayout.getBounds2() : mSplitLayout.getBounds1();
     }
 
+    private void getSideStageBounds(Rect rect) {
+        if (mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT) {
+            mSplitLayout.getBounds1(rect);
+        } else {
+            mSplitLayout.getBounds2(rect);
+        }
+    }
+
+    private void getMainStageBounds(Rect rect) {
+        if (mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT) {
+            mSplitLayout.getBounds2(rect);
+        } else {
+            mSplitLayout.getBounds1(rect);
+        }
+    }
+
     /**
      * Get the stage that should contain this `taskInfo`. The stage doesn't necessarily contain
      * this task (yet) so this can also be used to identify which stage to put a task into.
@@ -1527,8 +1604,8 @@
     }
 
     @Override
-    public void onTransitionMerged(@NonNull IBinder transition) {
-        mSplitTransitions.onTransitionMerged(transition);
+    public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted) {
+        mSplitTransitions.onTransitionConsumed(transition, aborted);
     }
 
     @Override
@@ -1607,7 +1684,7 @@
     /** Called to clean-up state and do house-keeping after the animation is done. */
     public void onTransitionAnimationComplete() {
         // If still playing, let it finish.
-        if (!mMainStage.isActive()) {
+        if (!mMainStage.isActive() && !mIsExiting) {
             // Update divider state after animation so that it is still around and positioned
             // properly for the animation itself.
             mSplitLayout.release();
@@ -1903,8 +1980,8 @@
         }
 
         @Override
-        public void onChildTaskEnterPip(int taskId) {
-            StageCoordinator.this.onStageChildTaskEnterPip(this, taskId);
+        public void onChildTaskEnterPip() {
+            StageCoordinator.this.onStageChildTaskEnterPip();
         }
 
         @Override
@@ -1916,10 +1993,13 @@
         @Override
         public void onNoLongerSupportMultiWindow() {
             if (mMainStage.isActive()) {
+                final Toast splitUnsupportedToast = Toast.makeText(mContext,
+                        R.string.dock_non_resizeble_failed_to_dock_text, Toast.LENGTH_SHORT);
                 final boolean isMainStage = mMainStageListener == this;
                 if (!ENABLE_SHELL_TRANSITIONS) {
                     StageCoordinator.this.exitSplitScreen(isMainStage ? mMainStage : mSideStage,
                             EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW);
+                    splitUnsupportedToast.show();
                     return;
                 }
 
@@ -1928,6 +2008,7 @@
                 prepareExitSplitScreen(stageType, wct);
                 mSplitTransitions.startDismissTransition(wct,StageCoordinator.this, stageType,
                         EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW);
+                splitUnsupportedToast.show();
             }
         }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index 23eec96a..f6dc68b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -17,12 +17,12 @@
 package com.android.wm.shell.splitscreen;
 
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 
+import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
+import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE;
 import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
 
 import android.annotation.CallSuper;
@@ -40,6 +40,7 @@
 
 import androidx.annotation.NonNull;
 
+import com.android.internal.util.ArrayUtils;
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.SurfaceUtils;
@@ -62,12 +63,6 @@
 class StageTaskListener implements ShellTaskOrganizer.TaskListener {
     private static final String TAG = StageTaskListener.class.getSimpleName();
 
-    protected static final int[] CONTROLLED_ACTIVITY_TYPES = {ACTIVITY_TYPE_STANDARD};
-    protected static final int[] CONTROLLED_WINDOWING_MODES =
-            {WINDOWING_MODE_FULLSCREEN, WINDOWING_MODE_UNDEFINED};
-    protected static final int[] CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE =
-            {WINDOWING_MODE_FULLSCREEN, WINDOWING_MODE_UNDEFINED, WINDOWING_MODE_MULTI_WINDOW};
-
     /** Callback interface for listening to changes in a split-screen stage. */
     public interface StageListenerCallbacks {
         void onRootTaskAppeared();
@@ -76,7 +71,7 @@
 
         void onChildTaskStatusChanged(int taskId, boolean present, boolean visible);
 
-        void onChildTaskEnterPip(int taskId);
+        void onChildTaskEnterPip();
 
         void onRootTaskVanished();
 
@@ -108,6 +103,11 @@
         taskOrganizer.createRootTask(displayId, WINDOWING_MODE_MULTI_WINDOW, this);
     }
 
+    /**
+     * General function for dismiss this stage.
+     */
+    void dismiss(WindowContainerTransaction wct, boolean toTop) {}
+
     int getChildCount() {
         return mChildrenTaskInfo.size();
     }
@@ -200,11 +200,6 @@
     @Override
     @CallSuper
     public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
-        if (!taskInfo.supportsMultiWindow) {
-            // Leave split screen if the task no longer supports multi window.
-            mCallbacks.onNoLongerSupportMultiWindow();
-            return;
-        }
         if (mRootTaskInfo.taskId == taskInfo.taskId) {
             // Inflates split decor view only when the root task is visible.
             if (mRootTaskInfo.isVisible != taskInfo.isVisible) {
@@ -217,6 +212,15 @@
             }
             mRootTaskInfo = taskInfo;
         } else if (taskInfo.parentTaskId == mRootTaskInfo.taskId) {
+            if (!taskInfo.supportsMultiWindow
+                    || !ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType())
+                    || !ArrayUtils.contains(CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE,
+                    taskInfo.getWindowingMode())) {
+                // Leave split screen if the task no longer supports multi window or have
+                // uncontrolled task.
+                mCallbacks.onNoLongerSupportMultiWindow();
+                return;
+            }
             mChildrenTaskInfo.put(taskInfo.taskId, taskInfo);
             mCallbacks.onChildTaskStatusChanged(taskInfo.taskId, true /* present */,
                     taskInfo.isVisible);
@@ -242,6 +246,7 @@
         if (mRootTaskInfo.taskId == taskId) {
             mCallbacks.onRootTaskVanished();
             mRootTaskInfo = null;
+            mRootLeash = null;
             mSyncQueue.runInSync(t -> {
                 t.remove(mDimLayer);
                 mSplitDecorManager.release(t);
@@ -255,7 +260,7 @@
                 return;
             }
             if (taskInfo.getWindowingMode() == WINDOWING_MODE_PINNED) {
-                mCallbacks.onChildTaskEnterPip(taskId);
+                mCallbacks.onChildTaskEnterPip();
             }
             sendStatusChanged();
         } else {
@@ -285,9 +290,9 @@
         }
     }
 
-    void onResizing(Rect newBounds, SurfaceControl.Transaction t) {
+    void onResizing(Rect newBounds, Rect sideBounds, SurfaceControl.Transaction t) {
         if (mSplitDecorManager != null && mRootTaskInfo != null) {
-            mSplitDecorManager.onResizing(mRootTaskInfo, newBounds, t);
+            mSplitDecorManager.onResizing(mRootTaskInfo, newBounds, sideBounds, t);
         }
     }
 
@@ -297,6 +302,14 @@
         }
     }
 
+    void fadeOutDecor(Runnable finishedCallback) {
+        if (mSplitDecorManager != null) {
+            mSplitDecorManager.fadeOutDecor(finishedCallback);
+        } else {
+            finishedCallback.run();
+        }
+    }
+
     void addTask(ActivityManager.RunningTaskInfo task, WindowContainerTransaction wct) {
         // Clear overridden bounds and windowing mode to make sure the child task can inherit
         // windowing mode and bounds from split root.
@@ -330,6 +343,11 @@
         }
     }
 
+    void resetBounds(WindowContainerTransaction wct) {
+        wct.setBounds(mRootTaskInfo.token, null);
+        wct.setAppBounds(mRootTaskInfo.token, null);
+    }
+
     void onSplitScreenListenerRegistered(SplitScreen.SplitScreenListener listener,
             @StageType int stage) {
         for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ConfigurationChangeListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ConfigurationChangeListener.java
new file mode 100644
index 0000000..2fca8f0
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ConfigurationChangeListener.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.sysui;
+
+import android.content.res.Configuration;
+
+/**
+ * Callbacks for when the configuration changes.
+ */
+public interface ConfigurationChangeListener {
+
+    /**
+     * Called when a configuration changes. This precedes all the following callbacks.
+     */
+    default void onConfigurationChanged(Configuration newConfiguration) {}
+
+    /**
+     * Convenience method to the above, called when the density or font scale changes.
+     */
+    default void onDensityOrFontScaleChanged() {}
+
+    /**
+     * Convenience method to the above, called when the smallest screen width changes.
+     */
+    default void onSmallestScreenWidthChanged() {}
+
+    /**
+     * Convenience method to the above, called when the system theme changes, including dark/light
+     * UI_MODE changes.
+     */
+    default void onThemeChanged() {}
+
+    /**
+     * Convenience method to the above, called when the local list or layout direction changes.
+     */
+    default void onLocaleOrLayoutDirectionChanged() {}
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/KeyguardChangeListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/KeyguardChangeListener.java
new file mode 100644
index 0000000..1c0b358
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/KeyguardChangeListener.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.sysui;
+
+/**
+ * Callbacks for when the keyguard changes.
+ */
+public interface KeyguardChangeListener {
+    /**
+     * Notifies the Shell that the keyguard is showing (and if so, whether it is occluded).
+     */
+    default void onKeyguardVisibilityChanged(boolean visible, boolean occluded,
+            boolean animatingDismiss) {}
+
+    /**
+     * Notifies the Shell when the keyguard dismiss animation has finished.
+     *
+     * TODO(b/206741900) deprecate this path once we're able to animate the PiP window as part of
+     * keyguard dismiss animation.
+     */
+    default void onKeyguardDismissAnimationFinished() {}
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java
new file mode 100644
index 0000000..837acec
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.sysui;
+
+import static android.content.pm.ActivityInfo.CONFIG_ASSETS_PATHS;
+import static android.content.pm.ActivityInfo.CONFIG_FONT_SCALE;
+import static android.content.pm.ActivityInfo.CONFIG_LAYOUT_DIRECTION;
+import static android.content.pm.ActivityInfo.CONFIG_LOCALE;
+import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
+import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
+
+import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SYSUI_EVENTS;
+
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.annotations.ExternalThread;
+
+import java.io.PrintWriter;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Handles event callbacks from SysUI that can be used within the Shell.
+ */
+public class ShellController {
+    private static final String TAG = ShellController.class.getSimpleName();
+
+    private final ShellExecutor mMainExecutor;
+    private final ShellInterfaceImpl mImpl = new ShellInterfaceImpl();
+
+    private final CopyOnWriteArrayList<ConfigurationChangeListener> mConfigChangeListeners =
+            new CopyOnWriteArrayList<>();
+    private final CopyOnWriteArrayList<KeyguardChangeListener> mKeyguardChangeListeners =
+            new CopyOnWriteArrayList<>();
+    private Configuration mLastConfiguration;
+
+
+    public ShellController(ShellExecutor mainExecutor) {
+        mMainExecutor = mainExecutor;
+    }
+
+    /**
+     * Returns the external interface to this controller.
+     */
+    public ShellInterface asShell() {
+        return mImpl;
+    }
+
+    /**
+     * Adds a new configuration listener. The configuration change callbacks are not made in any
+     * particular order.
+     */
+    public void addConfigurationChangeListener(ConfigurationChangeListener listener) {
+        mConfigChangeListeners.remove(listener);
+        mConfigChangeListeners.add(listener);
+    }
+
+    /**
+     * Removes an existing configuration listener.
+     */
+    public void removeConfigurationChangeListener(ConfigurationChangeListener listener) {
+        mConfigChangeListeners.remove(listener);
+    }
+
+    /**
+     * Adds a new Keyguard listener. The Keyguard change callbacks are not made in any
+     * particular order.
+     */
+    public void addKeyguardChangeListener(KeyguardChangeListener listener) {
+        mKeyguardChangeListeners.remove(listener);
+        mKeyguardChangeListeners.add(listener);
+    }
+
+    /**
+     * Removes an existing Keyguard listener.
+     */
+    public void removeKeyguardChangeListener(KeyguardChangeListener listener) {
+        mKeyguardChangeListeners.remove(listener);
+    }
+
+    @VisibleForTesting
+    void onConfigurationChanged(Configuration newConfig) {
+        // The initial config is send on startup and doesn't trigger listener callbacks
+        if (mLastConfiguration == null) {
+            mLastConfiguration = new Configuration(newConfig);
+            ProtoLog.v(WM_SHELL_SYSUI_EVENTS, "Initial Configuration: %s", newConfig);
+            return;
+        }
+
+        final int diff = newConfig.diff(mLastConfiguration);
+        ProtoLog.v(WM_SHELL_SYSUI_EVENTS, "New configuration change: %s", newConfig);
+        ProtoLog.v(WM_SHELL_SYSUI_EVENTS, "\tchanges=%s",
+                Configuration.configurationDiffToString(diff));
+        final boolean densityFontScaleChanged = (diff & CONFIG_FONT_SCALE) != 0
+                || (diff & ActivityInfo.CONFIG_DENSITY) != 0;
+        final boolean smallestScreenWidthChanged = (diff & CONFIG_SMALLEST_SCREEN_SIZE) != 0;
+        final boolean themeChanged = (diff & CONFIG_ASSETS_PATHS) != 0
+                || (diff & CONFIG_UI_MODE) != 0;
+        final boolean localOrLayoutDirectionChanged = (diff & CONFIG_LOCALE) != 0
+                || (diff & CONFIG_LAYOUT_DIRECTION) != 0;
+
+        // Update the last configuration and call listeners
+        mLastConfiguration.updateFrom(newConfig);
+        for (ConfigurationChangeListener listener : mConfigChangeListeners) {
+            listener.onConfigurationChanged(newConfig);
+            if (densityFontScaleChanged) {
+                listener.onDensityOrFontScaleChanged();
+            }
+            if (smallestScreenWidthChanged) {
+                listener.onSmallestScreenWidthChanged();
+            }
+            if (themeChanged) {
+                listener.onThemeChanged();
+            }
+            if (localOrLayoutDirectionChanged) {
+                listener.onLocaleOrLayoutDirectionChanged();
+            }
+        }
+    }
+
+    @VisibleForTesting
+    void onKeyguardVisibilityChanged(boolean visible, boolean occluded, boolean animatingDismiss) {
+        for (KeyguardChangeListener listener : mKeyguardChangeListeners) {
+            listener.onKeyguardVisibilityChanged(visible, occluded, animatingDismiss);
+        }
+    }
+
+    @VisibleForTesting
+    void onKeyguardDismissAnimationFinished() {
+        for (KeyguardChangeListener listener : mKeyguardChangeListeners) {
+            listener.onKeyguardDismissAnimationFinished();
+        }
+    }
+
+    public void dump(@NonNull PrintWriter pw, String prefix) {
+        final String innerPrefix = prefix + "  ";
+        pw.println(prefix + TAG);
+        pw.println(innerPrefix + "mConfigChangeListeners=" + mConfigChangeListeners.size());
+        pw.println(innerPrefix + "mLastConfiguration=" + mLastConfiguration);
+        pw.println(innerPrefix + "mKeyguardChangeListeners=" + mKeyguardChangeListeners.size());
+    }
+
+    /**
+     * The interface for calls from outside the Shell, within the host process.
+     */
+    @ExternalThread
+    private class ShellInterfaceImpl implements ShellInterface {
+        @Override
+        public void onConfigurationChanged(Configuration newConfiguration) {
+            mMainExecutor.execute(() ->
+                    ShellController.this.onConfigurationChanged(newConfiguration));
+        }
+
+        @Override
+        public void onKeyguardVisibilityChanged(boolean visible, boolean occluded,
+                boolean animatingDismiss) {
+            mMainExecutor.execute(() ->
+                    ShellController.this.onKeyguardVisibilityChanged(visible, occluded,
+                            animatingDismiss));
+        }
+
+        @Override
+        public void onKeyguardDismissAnimationFinished() {
+            mMainExecutor.execute(() ->
+                    ShellController.this.onKeyguardDismissAnimationFinished());
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInterface.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInterface.java
new file mode 100644
index 0000000..a15ce5d
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInterface.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.sysui;
+
+import android.content.res.Configuration;
+
+/**
+ * General interface for notifying the Shell of common SysUI events like configuration or keyguard
+ * changes.
+ *
+ * TODO: Move ShellInit and ShellCommandHandler into this interface
+ */
+public interface ShellInterface {
+
+    /**
+     * Notifies the Shell that the configuration has changed.
+     */
+    default void onConfigurationChanged(Configuration newConfiguration) {}
+
+    /**
+     * Notifies the Shell that the keyguard is showing (and if so, whether it is occluded) or not
+     * showing, and whether it is animating a dismiss.
+     */
+    default void onKeyguardVisibilityChanged(boolean visible, boolean occluded,
+            boolean animatingDismiss) {}
+
+    /**
+     * Notifies the Shell when the keyguard dismiss animation has finished.
+     */
+    default void onKeyguardDismissAnimationFinished() {}
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/tasksurfacehelper/TaskSurfaceHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/tasksurfacehelper/TaskSurfaceHelper.java
deleted file mode 100644
index ad9dda6..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/tasksurfacehelper/TaskSurfaceHelper.java
+++ /dev/null
@@ -1,37 +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 com.android.wm.shell.tasksurfacehelper;
-
-import android.app.ActivityManager.RunningTaskInfo;
-import android.graphics.Rect;
-import android.view.SurfaceControl;
-
-import java.util.concurrent.Executor;
-import java.util.function.Consumer;
-
-/**
- * Interface to communicate with a Task's SurfaceControl.
- */
-public interface TaskSurfaceHelper {
-
-    /** Sets the METADATA_GAME_MODE for the layer corresponding to the task **/
-    default void setGameModeForTask(int taskId, int gameMode) {}
-
-    /** Takes a screenshot for a task **/
-    default void screenshotTask(RunningTaskInfo taskInfo, Rect crop, Executor executor,
-            Consumer<SurfaceControl.ScreenshotHardwareBuffer> consumer) {}
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/tasksurfacehelper/TaskSurfaceHelperController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/tasksurfacehelper/TaskSurfaceHelperController.java
deleted file mode 100644
index 064d9d1..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/tasksurfacehelper/TaskSurfaceHelperController.java
+++ /dev/null
@@ -1,82 +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 com.android.wm.shell.tasksurfacehelper;
-
-import android.app.ActivityManager.RunningTaskInfo;
-import android.graphics.Rect;
-import android.view.SurfaceControl;
-
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.common.ShellExecutor;
-
-import java.util.concurrent.Executor;
-import java.util.function.Consumer;
-
-/**
- * Intermediary controller that communicates with {@link ShellTaskOrganizer} to send commands
- * to SurfaceControl.
- */
-public class TaskSurfaceHelperController {
-
-    private final ShellTaskOrganizer mTaskOrganizer;
-    private final ShellExecutor mMainExecutor;
-    private final TaskSurfaceHelperImpl mImpl = new TaskSurfaceHelperImpl();
-
-    public TaskSurfaceHelperController(ShellTaskOrganizer taskOrganizer,
-            ShellExecutor mainExecutor) {
-        mTaskOrganizer = taskOrganizer;
-        mMainExecutor = mainExecutor;
-    }
-
-    public TaskSurfaceHelper asTaskSurfaceHelper() {
-        return mImpl;
-    }
-
-    /**
-     * Sends a Transaction to set the game mode metadata on the
-     * corresponding SurfaceControl
-     */
-    public void setGameModeForTask(int taskId, int gameMode) {
-        mTaskOrganizer.setSurfaceMetadata(taskId, SurfaceControl.METADATA_GAME_MODE, gameMode);
-    }
-
-    /**
-     * Take screenshot of the specified task.
-     */
-    public void screenshotTask(RunningTaskInfo taskInfo, Rect crop,
-            Consumer<SurfaceControl.ScreenshotHardwareBuffer> consumer) {
-        mTaskOrganizer.screenshotTask(taskInfo, crop, consumer);
-    }
-
-    private class TaskSurfaceHelperImpl implements TaskSurfaceHelper {
-        @Override
-        public void setGameModeForTask(int taskId, int gameMode) {
-            mMainExecutor.execute(() -> {
-                TaskSurfaceHelperController.this.setGameModeForTask(taskId, gameMode);
-            });
-        }
-
-        @Override
-        public void screenshotTask(RunningTaskInfo taskInfo, Rect crop, Executor executor,
-                Consumer<SurfaceControl.ScreenshotHardwareBuffer> consumer) {
-            mMainExecutor.execute(() -> {
-                TaskSurfaceHelperController.this.screenshotTask(taskInfo, crop,
-                        (t) -> executor.execute(() -> consumer.accept(t)));
-            });
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index 7234d55..11b453c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -274,7 +274,7 @@
     }
 
     @Override
-    public void onTransitionMerged(@NonNull IBinder transition) {
+    public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted) {
         MixedTransition mixed = null;
         for (int i = mActiveTransitions.size() - 1; i >= 0; --i) {
             if (mActiveTransitions.get(i).mTransition != transition) continue;
@@ -283,7 +283,7 @@
         }
         if (mixed == null) return;
         if (mixed.mType == MixedTransition.TYPE_ENTER_PIP_FROM_SPLIT) {
-            mPipHandler.onTransitionMerged(transition);
+            mPipHandler.onTransitionConsumed(transition, aborted);
         }
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java
index 3e2a0e6..ebaece2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java
@@ -99,6 +99,8 @@
                         + " during unit tests");
             }
             mRemote.getRemoteTransition().startAnimation(transition, info, startTransaction, cb);
+            // assume that remote will apply the start transaction.
+            startTransaction.clear();
         } catch (RemoteException e) {
             Log.e(Transitions.TAG, "Error running remote transition.", e);
             if (mRemote.asBinder() != null) {
@@ -120,6 +122,11 @@
             @Override
             public void onTransitionFinished(WindowContainerTransaction wct,
                     SurfaceControl.Transaction sct) {
+                // We have merged, since we sent the transaction over binder, the one in this
+                // process won't be cleared if the remote applied it. We don't actually know if the
+                // remote applied the transaction, but applying twice will break surfaceflinger
+                // so just assume the worst-case and clear the local transaction.
+                t.clear();
                 mMainExecutor.execute(
                         () -> finishCallback.onTransitionFinished(wct, null /* wctCB */));
             }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java
index ece9f47..b15c48c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java
@@ -83,7 +83,7 @@
     }
 
     @Override
-    public void onTransitionMerged(@NonNull IBinder transition) {
+    public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted) {
         mRequestedRemotes.remove(transition);
     }
 
@@ -139,6 +139,8 @@
                         + " during unit tests");
             }
             remote.getRemoteTransition().startAnimation(transition, info, startTransaction, cb);
+            // assume that remote will apply the start transaction.
+            startTransaction.clear();
         } catch (RemoteException e) {
             Log.e(Transitions.TAG, "Error running remote transition.", e);
             unhandleDeath(remote.asBinder(), finishCallback);
@@ -162,6 +164,11 @@
             @Override
             public void onTransitionFinished(WindowContainerTransaction wct,
                     SurfaceControl.Transaction sct) {
+                // We have merged, since we sent the transaction over binder, the one in this
+                // process won't be cleared if the remote applied it. We don't actually know if the
+                // remote applied the transaction, but applying twice will break surfaceflinger
+                // so just assume the worst-case and clear the local transaction.
+                t.clear();
                 mMainExecutor.execute(() -> {
                     if (!mRequestedRemotes.containsKey(mergeTarget)) {
                         Log.e(TAG, "Merged transition finished after it's mergeTarget (the "
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index de0f47f..fa22c7c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -516,15 +516,20 @@
             active.mMerged = true;
             active.mAborted = abort;
             if (active.mHandler != null) {
-                active.mHandler.onTransitionMerged(active.mToken);
+                active.mHandler.onTransitionConsumed(active.mToken, abort);
             }
             return;
         }
-        mActiveTransitions.get(activeIdx).mAborted = abort;
+        final ActiveTransition active = mActiveTransitions.get(activeIdx);
+        active.mAborted = abort;
+        if (active.mAborted && active.mHandler != null) {
+            // Notifies to clean-up the aborted transition.
+            active.mHandler.onTransitionConsumed(transition, true /* aborted */);
+        }
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
                 "Transition animation finished (abort=%b), notifying core %s", abort, transition);
         // Merge all relevant transactions together
-        SurfaceControl.Transaction fullFinish = mActiveTransitions.get(activeIdx).mFinishT;
+        SurfaceControl.Transaction fullFinish = active.mFinishT;
         for (int iA = activeIdx + 1; iA < mActiveTransitions.size(); ++iA) {
             final ActiveTransition toMerge = mActiveTransitions.get(iA);
             if (!toMerge.mMerged) break;
@@ -553,6 +558,10 @@
         while (mActiveTransitions.size() > activeIdx
                 && mActiveTransitions.get(activeIdx).mAborted) {
             ActiveTransition aborted = mActiveTransitions.remove(activeIdx);
+            // Notifies to clean-up the aborted transition.
+            if (aborted.mHandler != null) {
+                aborted.mHandler.onTransitionConsumed(transition, true /* aborted */);
+            }
             mOrganizer.finishTransition(aborted.mToken, null /* wct */, null /* wctCB */);
         }
         if (mActiveTransitions.size() <= activeIdx) {
@@ -735,9 +744,10 @@
 
         /**
          * Called when a transition which was already "claimed" by this handler has been merged
-         * into another animation. Gives this handler a chance to clean-up any expectations.
+         * into another animation or has been aborted. Gives this handler a chance to clean-up any
+         * expectations.
          */
-        default void onTransitionMerged(@NonNull IBinder transition) { }
+        default void onTransitionConsumed(@NonNull IBinder transition, boolean aborted) { }
 
         /**
          * Sets transition animation scale settings value to handler.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
index 572516d..cdca051 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -95,6 +95,7 @@
         mDragResizeCallback = dragResizeCallback;
     }
 
+    @Override
     void relayout(ActivityManager.RunningTaskInfo taskInfo) {
         final int shadowRadiusDp = taskInfo.isFocused
                 ? DECOR_SHADOW_FOCUSED_THICKNESS_IN_DIP : DECOR_SHADOW_UNFOCUSED_THICKNESS_IN_DIP;
@@ -119,8 +120,8 @@
         });
 
         if (mResult.mRootView == null) {
-            // This means the task is hidden. Nothing is set up in this case including the
-            // decoration surface.
+            // This means something blocks the window decor from showing, e.g. the task is hidden.
+            // Nothing is set up in this case including the decoration surface.
             return;
         }
         if (oldRootView != mResult.mRootView) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index 0c502283..c19a33a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -38,6 +38,8 @@
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.DisplayController;
 
+import java.util.function.Supplier;
+
 /**
  * Manages a container surface and a windowless window to show window decoration. Responsible to
  * update window decoration window state and layout parameters on task info changes and so that
@@ -53,7 +55,8 @@
  *
  * @param <T> The type of the root view
  */
-public class WindowDecoration<T extends View & TaskFocusStateConsumer> implements AutoCloseable {
+public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
+        implements AutoCloseable {
     private static final int[] CAPTION_INSETS_TYPES = { InsetsState.ITYPE_CAPTION_BAR };
 
     /**
@@ -62,6 +65,20 @@
     final Context mContext;
     final DisplayController mDisplayController;
     final ShellTaskOrganizer mTaskOrganizer;
+    final Supplier<SurfaceControl.Builder> mSurfaceControlBuilderSupplier;
+    final SurfaceControlViewHostFactory mSurfaceControlViewHostFactory;
+    private final DisplayController.OnDisplaysChangedListener mOnDisplaysChangedListener =
+            new DisplayController.OnDisplaysChangedListener() {
+                @Override
+                public void onDisplayAdded(int displayId) {
+                    if (mTaskInfo.displayId != displayId) {
+                        return;
+                    }
+
+                    mDisplayController.removeDisplayWindowListener(this);
+                    relayout(mTaskInfo);
+                }
+            };
 
     RunningTaskInfo mTaskInfo;
     final SurfaceControl mTaskSurface;
@@ -71,7 +88,7 @@
     SurfaceControl mDecorationContainerSurface;
     SurfaceControl mTaskBackgroundSurface;
 
-    private CaptionWindowManager mCaptionWindowManager;
+    private final CaptionWindowManager mCaptionWindowManager;
     private SurfaceControlViewHost mViewHost;
 
     private final Rect mCaptionInsetsRect = new Rect();
@@ -84,11 +101,25 @@
             ShellTaskOrganizer taskOrganizer,
             RunningTaskInfo taskInfo,
             SurfaceControl taskSurface) {
+        this(context, displayController, taskOrganizer, taskInfo, taskSurface,
+                SurfaceControl.Builder::new, new SurfaceControlViewHostFactory() {});
+    }
+
+    WindowDecoration(
+            Context context,
+            DisplayController displayController,
+            ShellTaskOrganizer taskOrganizer,
+            RunningTaskInfo taskInfo,
+            SurfaceControl taskSurface,
+            Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier,
+            SurfaceControlViewHostFactory surfaceControlViewHostFactory) {
         mContext = context;
         mDisplayController = displayController;
         mTaskOrganizer = taskOrganizer;
         mTaskInfo = taskInfo;
         mTaskSurface = taskSurface;
+        mSurfaceControlBuilderSupplier = surfaceControlBuilderSupplier;
+        mSurfaceControlViewHostFactory = surfaceControlViewHostFactory;
 
         mDisplay = mDisplayController.getDisplay(mTaskInfo.displayId);
         mDecorWindowContext = mContext.createConfigurationContext(mTaskInfo.getConfiguration());
@@ -99,6 +130,15 @@
                 new CaptionWindowManager(mTaskInfo.getConfiguration(), mTaskSurface);
     }
 
+    /**
+     * Used by {@link WindowDecoration} to trigger a new relayout because the requirements for a
+     * relayout weren't satisfied are satisfied now.
+     *
+     * @param taskInfo The previous {@link RunningTaskInfo} passed into {@link #relayout} or the
+     *                 constructor.
+     */
+    abstract void relayout(RunningTaskInfo taskInfo);
+
     void relayout(RunningTaskInfo taskInfo, int layoutResId, T rootView, float captionHeightDp,
             Rect outsetsDp, float shadowRadiusDp, SurfaceControl.Transaction t,
             WindowContainerTransaction wct, RelayoutResult<T> outResult) {
@@ -110,7 +150,7 @@
         }
 
         if (!mTaskInfo.isVisible) {
-            close();
+            releaseViews();
             t.hide(mTaskSurface);
             return;
         }
@@ -123,10 +163,14 @@
         rootView = null; // Clear it just in case we use it accidentally
         final Configuration taskConfig = mTaskInfo.getConfiguration();
         if (oldTaskConfig.densityDpi != taskConfig.densityDpi
+                || mDisplay == null
                 || mDisplay.getDisplayId() != mTaskInfo.displayId) {
-            close();
+            releaseViews();
 
-            mDisplay = mDisplayController.getDisplay(mTaskInfo.displayId);
+            if (!obtainDisplayOrRegisterListener()) {
+                outResult.mRootView = null;
+                return;
+            }
             mDecorWindowContext = mContext.createConfigurationContext(taskConfig);
             if (layoutResId != 0) {
                 outResult.mRootView =
@@ -141,7 +185,7 @@
 
         // DecorationContainerSurface
         if (mDecorationContainerSurface == null) {
-            final SurfaceControl.Builder builder = new SurfaceControl.Builder();
+            final SurfaceControl.Builder builder = mSurfaceControlBuilderSupplier.get();
             mDecorationContainerSurface = builder
                     .setName("Decor container of Task=" + mTaskInfo.taskId)
                     .setContainerLayer()
@@ -168,7 +212,7 @@
 
         // TaskBackgroundSurface
         if (mTaskBackgroundSurface == null) {
-            final SurfaceControl.Builder builder = new SurfaceControl.Builder();
+            final SurfaceControl.Builder builder = mSurfaceControlBuilderSupplier.get();
             mTaskBackgroundSurface = builder
                     .setName("Background of Task=" + mTaskInfo.taskId)
                     .setEffectLayer()
@@ -195,7 +239,7 @@
         lp.setTitle("Caption of Task=" + mTaskInfo.taskId);
         lp.setTrustedOverlay();
         if (mViewHost == null) {
-            mViewHost = new SurfaceControlViewHost(mDecorWindowContext, mDisplay,
+            mViewHost = mSurfaceControlViewHostFactory.create(mDecorWindowContext, mDisplay,
                     mCaptionWindowManager, true);
             mViewHost.setView(outResult.mRootView, lp);
         } else {
@@ -225,8 +269,22 @@
                 .show(mTaskSurface);
     }
 
-    @Override
-    public void close() {
+    /**
+     * Obtains the {@link Display} instance for the display ID in {@link #mTaskInfo} if it exists or
+     * registers {@link #mOnDisplaysChangedListener} if it doesn't.
+     *
+     * @return {@code true} if the {@link Display} instance exists; or {@code false} otherwise
+     */
+    private boolean obtainDisplayOrRegisterListener() {
+        mDisplay = mDisplayController.getDisplay(mTaskInfo.displayId);
+        if (mDisplay == null) {
+            mDisplayController.addDisplayWindowListener(mOnDisplaysChangedListener);
+            return false;
+        }
+        return true;
+    }
+
+    private void releaseViews() {
         if (mViewHost != null) {
             mViewHost.release();
             mViewHost = null;
@@ -243,6 +301,12 @@
         }
     }
 
+    @Override
+    public void close() {
+        mDisplayController.removeDisplayWindowListener(mOnDisplaysChangedListener);
+        releaseViews();
+    }
+
     static class RelayoutResult<T extends View & TaskFocusStateConsumer> {
         int mWidth;
         int mHeight;
@@ -267,4 +331,11 @@
             super.setConfiguration(configuration);
         }
     }
+
+    interface SurfaceControlViewHostFactory {
+        default SurfaceControlViewHost create(
+                Context c, Display d, WindowlessWindowManager wmm, boolean useSfChoreographer) {
+            return new SurfaceControlViewHost(c, d, wmm, useSfChoreographer);
+        }
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt
new file mode 100644
index 0000000..1c587a2
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker
+
+import android.app.Instrumentation
+import android.platform.test.annotations.Presubmit
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.FlickerTestParameter
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.entireScreenCovered
+import com.android.server.wm.flicker.navBarLayerIsVisibleAtStartAndEnd
+import com.android.server.wm.flicker.navBarLayerPositionAtStartAndEnd
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerIsVisibleAtStartAndEnd
+import com.android.server.wm.flicker.statusBarLayerPositionAtStartAndEnd
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.taskBarLayerIsVisibleAtStartAndEnd
+import com.android.server.wm.flicker.taskBarWindowIsAlwaysVisible
+import com.android.server.wm.traces.common.ComponentMatcher
+import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
+import org.junit.Assume
+import org.junit.Test
+
+/**
+ * Base test class containing common assertions for [ComponentMatcher.NAV_BAR],
+ * [ComponentMatcher.TASK_BAR], [ComponentMatcher.STATUS_BAR], and general assertions
+ * (layers visible in consecutive states, entire screen covered, etc.)
+ */
+abstract class BaseTest @JvmOverloads constructor(
+    protected val testSpec: FlickerTestParameter,
+    protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation(),
+    protected val tapl: LauncherInstrumentation = LauncherInstrumentation()
+) {
+    init {
+        testSpec.setIsTablet(
+            WindowManagerStateHelper(instrumentation).currentState.wmState.isTablet
+        )
+    }
+
+    /**
+     * Specification of the test transition to execute
+     */
+    abstract val transition: FlickerBuilder.() -> Unit
+
+    /**
+     * Entry point for the test runner. It will use this method to initialize and cache
+     * flicker executions
+     */
+    @FlickerBuilderProvider
+    fun buildFlicker(): FlickerBuilder {
+        return FlickerBuilder(instrumentation).apply {
+            setup {
+                test {
+                    testSpec.setIsTablet(wmHelper.currentState.wmState.isTablet)
+                }
+            }
+            transition()
+        }
+    }
+
+    /**
+     * Checks that all parts of the screen are covered during the transition
+     */
+    open fun entireScreenCovered() = testSpec.entireScreenCovered()
+
+    /**
+     * Checks that the [ComponentMatcher.NAV_BAR] layer is visible during the whole transition
+     */
+    @Presubmit
+    @Test
+    open fun navBarLayerIsVisibleAtStartAndEnd() {
+        Assume.assumeFalse(testSpec.isTablet)
+        testSpec.navBarLayerIsVisibleAtStartAndEnd()
+    }
+
+    /**
+     * Checks the position of the [ComponentMatcher.NAV_BAR] at the start and end of the transition
+     */
+    @Presubmit
+    @Test
+    open fun navBarLayerPositionAtStartAndEnd() {
+        Assume.assumeFalse(testSpec.isTablet)
+        testSpec.navBarLayerPositionAtStartAndEnd()
+    }
+
+    /**
+     * Checks that the [ComponentMatcher.NAV_BAR] window is visible during the whole transition
+     *
+     * Note: Phones only
+     */
+    @Presubmit
+    @Test
+    open fun navBarWindowIsAlwaysVisible() {
+        Assume.assumeFalse(testSpec.isTablet)
+        testSpec.navBarWindowIsAlwaysVisible()
+    }
+
+    /**
+     * Checks that the [ComponentMatcher.TASK_BAR] layer is visible during the whole transition
+     */
+    @Presubmit
+    @Test
+    open fun taskBarLayerIsVisibleAtStartAndEnd() {
+        Assume.assumeTrue(testSpec.isTablet)
+        testSpec.taskBarLayerIsVisibleAtStartAndEnd()
+    }
+
+    /**
+     * Checks that the [ComponentMatcher.TASK_BAR] window is visible during the whole transition
+     *
+     * Note: Large screen only
+     */
+    @Presubmit
+    @Test
+    open fun taskBarWindowIsAlwaysVisible() {
+        Assume.assumeTrue(testSpec.isTablet)
+        testSpec.taskBarWindowIsAlwaysVisible()
+    }
+
+    /**
+     * Checks that the [ComponentMatcher.STATUS_BAR] layer is visible during the whole transition
+     */
+    @Presubmit
+    @Test
+    open fun statusBarLayerIsVisibleAtStartAndEnd() =
+        testSpec.statusBarLayerIsVisibleAtStartAndEnd()
+
+    /**
+     * Checks the position of the [ComponentMatcher.STATUS_BAR] at the start and end of the transition
+     */
+    @Presubmit
+    @Test
+    open fun statusBarLayerPositionAtStartAndEnd() = testSpec.statusBarLayerPositionAtStartAndEnd()
+
+    /**
+     * Checks that the [ComponentMatcher.STATUS_BAR] window is visible during the whole transition
+     */
+    @Presubmit
+    @Test
+    open fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible()
+
+    /**
+     * Checks that all layers that are visible on the trace, are visible for at least 2
+     * consecutive entries.
+     */
+    @Presubmit
+    @Test
+    open fun visibleLayersShownMoreThanOneConsecutiveEntry() {
+        testSpec.assertLayers {
+            this.visibleLayersShownMoreThanOneConsecutiveEntry()
+        }
+    }
+
+    /**
+     * Checks that all windows that are visible on the trace, are visible for at least 2
+     * consecutive entries.
+     */
+    @Presubmit
+    @Test
+    open fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
+        testSpec.assertWm {
+            this.visibleWindowsShownMoreThanOneConsecutiveEntry()
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
index cba396a..c1d743b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
@@ -20,7 +20,7 @@
 import android.view.Surface
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.helpers.WindowUtils
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
 import com.android.server.wm.traces.common.region.Region
 
 fun FlickerTestParameter.appPairsDividerIsVisibleAtEnd() {
@@ -48,7 +48,7 @@
 }
 
 fun FlickerTestParameter.layerBecomesVisible(
-    component: FlickerComponentName
+    component: IComponentMatcher
 ) {
     assertLayers {
         this.isInvisible(component)
@@ -58,7 +58,7 @@
 }
 
 fun FlickerTestParameter.layerIsVisibleAtEnd(
-    component: FlickerComponentName
+    component: IComponentMatcher
 ) {
     assertLayersEnd {
         this.isVisible(component)
@@ -67,7 +67,7 @@
 
 fun FlickerTestParameter.splitAppLayerBoundsBecomesVisible(
     rotation: Int,
-    component: FlickerComponentName,
+    component: IComponentMatcher,
     splitLeftTop: Boolean
 ) {
     assertLayers {
@@ -88,7 +88,7 @@
 
 fun FlickerTestParameter.splitAppLayerBoundsIsVisibleAtEnd(
     rotation: Int,
-    component: FlickerComponentName,
+    component: IComponentMatcher,
     splitLeftTop: Boolean
 ) {
     assertLayersEnd {
@@ -104,7 +104,7 @@
 }
 
 fun FlickerTestParameter.appWindowBecomesVisible(
-    component: FlickerComponentName
+    component: IComponentMatcher
 ) {
     assertWm {
         this.isAppWindowInvisible(component)
@@ -114,7 +114,7 @@
 }
 
 fun FlickerTestParameter.appWindowIsVisibleAtEnd(
-    component: FlickerComponentName
+    component: IComponentMatcher
 ) {
     assertWmEnd {
         this.isAppWindowVisible(component)
@@ -151,7 +151,7 @@
 
 fun FlickerTestParameter.appPairsPrimaryBoundsIsVisibleAtEnd(
     rotation: Int,
-    primaryComponent: FlickerComponentName
+    primaryComponent: IComponentMatcher
 ) {
     assertLayersEnd {
         val dividerRegion = layer(APP_PAIR_SPLIT_DIVIDER_COMPONENT).visibleRegion.region
@@ -162,7 +162,7 @@
 
 fun FlickerTestParameter.dockedStackPrimaryBoundsIsVisibleAtEnd(
     rotation: Int,
-    primaryComponent: FlickerComponentName
+    primaryComponent: IComponentMatcher
 ) {
     assertLayersEnd {
         val dividerRegion = layer(DOCKED_STACK_DIVIDER_COMPONENT).visibleRegion.region
@@ -173,7 +173,7 @@
 
 fun FlickerTestParameter.appPairsSecondaryBoundsIsVisibleAtEnd(
     rotation: Int,
-    secondaryComponent: FlickerComponentName
+    secondaryComponent: IComponentMatcher
 ) {
     assertLayersEnd {
         val dividerRegion = layer(APP_PAIR_SPLIT_DIVIDER_COMPONENT).visibleRegion.region
@@ -184,7 +184,7 @@
 
 fun FlickerTestParameter.dockedStackSecondaryBoundsIsVisibleAtEnd(
     rotation: Int,
-    secondaryComponent: FlickerComponentName
+    secondaryComponent: IComponentMatcher
 ) {
     assertLayersEnd {
         val dividerRegion = layer(DOCKED_STACK_DIVIDER_COMPONENT).visibleRegion.region
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
index f56eb6e..3708e5f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
@@ -17,9 +17,9 @@
 @file:JvmName("CommonConstants")
 package com.android.wm.shell.flicker
 
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
 
 const val SYSTEM_UI_PACKAGE_NAME = "com.android.systemui"
-val APP_PAIR_SPLIT_DIVIDER_COMPONENT = FlickerComponentName("", "AppPairSplitDivider#")
-val DOCKED_STACK_DIVIDER_COMPONENT = FlickerComponentName("", "DockedStackDivider#")
-val SPLIT_SCREEN_DIVIDER_COMPONENT = FlickerComponentName("", "StageCoordinatorSplitDivider#")
+val APP_PAIR_SPLIT_DIVIDER_COMPONENT = ComponentMatcher("", "AppPairSplitDivider#")
+val DOCKED_STACK_DIVIDER_COMPONENT = ComponentMatcher("", "DockedStackDivider#")
+val SPLIT_SCREEN_DIVIDER_COMPONENT = ComponentMatcher("", "StageCoordinatorSplitDivider#")
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt
deleted file mode 100644
index 9c50630..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.flicker
-
-import android.app.Instrumentation
-import android.content.pm.PackageManager
-import android.content.pm.PackageManager.FEATURE_LEANBACK
-import android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY
-import android.view.Surface
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.uiautomator.UiDevice
-import org.junit.Assume.assumeFalse
-import org.junit.Before
-import org.junit.runners.Parameterized
-
-/**
- * Base class of all Flicker test that performs common functions for all flicker tests:
- *
- * - Caches transitions so that a transition is run once and the transition results are used by
- * tests multiple times. This is needed for parameterized tests which call the BeforeClass methods
- * multiple times.
- * - Keeps track of all test artifacts and deletes ones which do not need to be reviewed.
- * - Fails tests if results are not available for any test due to jank.
- */
-abstract class FlickerTestBase(
-    protected val rotationName: String,
-    protected val rotation: Int
-) {
-    val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
-    val uiDevice = UiDevice.getInstance(instrumentation)
-    val packageManager: PackageManager = instrumentation.context.packageManager
-    protected val isTelevision: Boolean by lazy {
-        packageManager.run {
-            hasSystemFeature(FEATURE_LEANBACK) || hasSystemFeature(FEATURE_LEANBACK_ONLY)
-        }
-    }
-
-    /**
-     * By default WmShellFlickerTests do not run on TV devices.
-     * If the test should run on TV - it should override this method.
-     */
-    @Before
-    open fun televisionSetUp() = assumeFalse(isTelevision)
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<Array<Any>> {
-            val supportedRotations = intArrayOf(Surface.ROTATION_0, Surface.ROTATION_90)
-            return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt
index 5b07303..67d7aca 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt
@@ -17,41 +17,38 @@
 package com.android.wm.shell.flicker.bubble
 
 import android.app.INotificationManager
-import android.app.Instrumentation
 import android.app.NotificationManager
 import android.content.Context
 import android.os.ServiceManager
 import android.view.Surface
-import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.By
 import androidx.test.uiautomator.UiObject2
 import androidx.test.uiautomator.Until
 import com.android.server.wm.flicker.Flicker
-import com.android.server.wm.flicker.FlickerBuilderProvider
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.dsl.FlickerBuilder
 import com.android.server.wm.flicker.helpers.SYSTEMUI_PACKAGE
+import com.android.wm.shell.flicker.BaseTest
 import com.android.wm.shell.flicker.helpers.LaunchBubbleHelper
 import org.junit.runners.Parameterized
 
 /**
  * Base configurations for Bubble flicker tests
  */
-abstract class BaseBubbleScreen(protected val testSpec: FlickerTestParameter) {
+abstract class BaseBubbleScreen(
+    testSpec: FlickerTestParameter
+) : BaseTest(testSpec) {
 
-    protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
     protected val context: Context = instrumentation.context
     protected val testApp = LaunchBubbleHelper(instrumentation)
 
-    protected val notifyManager = INotificationManager.Stub.asInterface(
+    private val notifyManager = INotificationManager.Stub.asInterface(
             ServiceManager.getService(Context.NOTIFICATION_SERVICE))
 
-    protected val uid = context.packageManager.getApplicationInfo(
+    private val uid = context.packageManager.getApplicationInfo(
             testApp.`package`, 0).uid
 
-    protected abstract val transition: FlickerBuilder.() -> Unit
-
     @JvmOverloads
     protected open fun buildTransition(
         extraSpec: FlickerBuilder.() -> Unit = {}
@@ -60,7 +57,7 @@
             setup {
                 test {
                     notifyManager.setBubblesAllowed(testApp.`package`,
-                            uid, NotificationManager.BUBBLE_PREFERENCE_ALL)
+                        uid, NotificationManager.BUBBLE_PREFERENCE_ALL)
                     testApp.launchViaIntent(wmHelper)
                     waitAndGetAddBubbleBtn()
                     waitAndGetCancelAllBtn()
@@ -84,13 +81,6 @@
     protected fun Flicker.waitAndGetCancelAllBtn(): UiObject2? = device.wait(Until.findObject(
             By.text("Cancel All Bubble")), FIND_OBJECT_TIMEOUT)
 
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            transition(this)
-        }
-    }
-
     companion object {
         @Parameterized.Parameters(name = "{0}")
         @JvmStatic
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DismissBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DismissBubbleScreen.kt
index b137e92..c44e250 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DismissBubbleScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DismissBubbleScreen.kt
@@ -18,6 +18,7 @@
 
 import android.content.Context
 import android.graphics.Point
+import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.util.DisplayMetrics
 import android.view.WindowManager
@@ -28,8 +29,8 @@
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.annotation.Group4
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import org.junit.runner.RunWith
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
 
 /**
@@ -49,6 +50,7 @@
     private val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
     private val displaySize = DisplayMetrics()
 
+    /** {@inheritDoc} */
     override val transition: FlickerBuilder.() -> Unit
         get() = buildTransition {
             setup {
@@ -58,10 +60,13 @@
                 }
             }
             transitions {
-                wm.run { wm.getDefaultDisplay().getMetrics(displaySize) }
+                wm.run { wm.defaultDisplay.getMetrics(displaySize) }
                 val dist = Point((displaySize.widthPixels / 2), displaySize.heightPixels)
-                val showBubble = device.wait(Until.findObject(
-                        By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME)), FIND_OBJECT_TIMEOUT)
+                val showBubble = device.wait(
+                    Until.findObject(
+                        By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME)
+                    ), FIND_OBJECT_TIMEOUT
+                )
                 showBubble?.run { drag(dist, 1000) } ?: error("Show bubble not found")
             }
         }
@@ -70,7 +75,25 @@
     @Test
     open fun testAppIsAlwaysVisible() {
         testSpec.assertLayers {
-            this.isVisible(testApp.component)
+            this.isVisible(testApp)
         }
     }
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarLayerIsVisibleAtStartAndEnd() =
+        super.taskBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarWindowIsAlwaysVisible() =
+        super.taskBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ExpandBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ExpandBubbleScreen.kt
index f288b0a..bab0112 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ExpandBubbleScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ExpandBubbleScreen.kt
@@ -24,8 +24,8 @@
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.annotation.Group4
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import org.junit.runner.RunWith
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
 
 /**
@@ -44,6 +44,7 @@
 @Group4
 open class ExpandBubbleScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen(testSpec) {
 
+    /** {@inheritDoc} */
     override val transition: FlickerBuilder.() -> Unit
         get() = buildTransition {
             setup {
@@ -53,8 +54,11 @@
                 }
             }
             transitions {
-                val showBubble = device.wait(Until.findObject(
-                        By.res("com.android.systemui", "bubble_view")), FIND_OBJECT_TIMEOUT)
+                val showBubble = device.wait(
+                    Until.findObject(
+                        By.res("com.android.systemui", "bubble_view")
+                    ), FIND_OBJECT_TIMEOUT
+                )
                 showBubble?.run { showBubble.click() } ?: error("Bubble notify not found")
             }
         }
@@ -63,7 +67,7 @@
     @Test
     open fun testAppIsAlwaysVisible() {
         testSpec.assertLayers {
-            this.isVisible(testApp.component)
+            this.isVisible(testApp)
         }
     }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
index e2b19ea..319de8e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
@@ -17,6 +17,7 @@
 package com.android.wm.shell.flicker.bubble
 
 import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.view.WindowInsets
 import android.view.WindowManager
@@ -27,8 +28,6 @@
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.annotation.Group4
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
-import org.junit.Assume
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
@@ -47,6 +46,7 @@
 @Group4
 class LaunchBubbleFromLockScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen(testSpec) {
 
+    /** {@inheritDoc} */
     override val transition: FlickerBuilder.() -> Unit
         get() = buildTransition {
             setup {
@@ -66,18 +66,25 @@
                     ?: error("Unable to obtain WM service")
                 val metricInsets = wm.currentWindowMetrics.windowInsets
                 val insets = metricInsets.getInsetsIgnoringVisibility(
-                        WindowInsets.Type.statusBars()
-                        or WindowInsets.Type.displayCutout())
+                    WindowInsets.Type.statusBars()
+                        or WindowInsets.Type.displayCutout()
+                )
                 device.swipe(100, insets.top + 100, 100, device.displayHeight / 2, 4)
                 device.waitForIdle(2000)
                 instrumentation.uiAutomation.syncInputTransactions()
 
-                val notification = device.wait(Until.findObject(
-                    By.text("BubbleChat")), FIND_OBJECT_TIMEOUT)
+                val notification = device.wait(
+                    Until.findObject(
+                        By.text("BubbleChat")
+                    ), FIND_OBJECT_TIMEOUT
+                )
                 notification?.click() ?: error("Notification not found")
                 instrumentation.uiAutomation.syncInputTransactions()
-                val showBubble = device.wait(Until.findObject(
-                        By.res("com.android.systemui", "bubble_view")), FIND_OBJECT_TIMEOUT)
+                val showBubble = device.wait(
+                    Until.findObject(
+                        By.res("com.android.systemui", "bubble_view")
+                    ), FIND_OBJECT_TIMEOUT
+                )
                 showBubble?.click() ?: error("Bubble notify not found")
                 instrumentation.uiAutomation.syncInputTransactions()
                 val cancelAllBtn = waitAndGetCancelAllBtn()
@@ -88,18 +95,38 @@
     @Presubmit
     @Test
     fun testAppIsVisibleAtEnd() {
-        Assume.assumeFalse(isShellTransitionsEnabled)
         testSpec.assertLayersEnd {
-            this.isVisible(testApp.component)
+            this.isVisible(testApp)
         }
     }
 
-    @FlakyTest
+    /** {@inheritDoc} */
+    @FlakyTest(bugId = 206753786)
     @Test
-    fun testAppIsVisibleAtEnd_ShellTransit() {
-        Assume.assumeTrue(isShellTransitionsEnabled)
-        testSpec.assertLayersEnd {
-            this.isVisible(testApp.component)
-        }
-    }
+    override fun navBarLayerIsVisibleAtStartAndEnd() =
+        super.navBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @FlakyTest(bugId = 206753786)
+    @Test
+    override fun navBarLayerPositionAtStartAndEnd() =
+        super.navBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @FlakyTest(bugId = 206753786)
+    @Test
+    override fun navBarWindowIsAlwaysVisible() =
+        super.navBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarLayerIsVisibleAtStartAndEnd() =
+        super.taskBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarWindowIsAlwaysVisible() =
+        super.taskBarWindowIsAlwaysVisible()
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt
index 0bb4d39..effd330 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt
@@ -41,6 +41,7 @@
 @Group4
 open class LaunchBubbleScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen(testSpec) {
 
+    /** {@inheritDoc} */
     override val transition: FlickerBuilder.() -> Unit
         get() = buildTransition {
             transitions {
@@ -53,7 +54,7 @@
     @Test
     open fun testAppIsAlwaysVisible() {
         testSpec.assertLayers {
-            this.isVisible(testApp.component)
+            this.isVisible(testApp)
         }
     }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreen.kt
index 8d1e315..a558450 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreen.kt
@@ -17,6 +17,7 @@
 package com.android.wm.shell.flicker.bubble
 
 import android.os.SystemClock
+import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import androidx.test.filters.RequiresDevice
 import androidx.test.uiautomator.By
@@ -28,8 +29,8 @@
 import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import org.junit.Assume
 import org.junit.Before
-import org.junit.runner.RunWith
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
 
 /**
@@ -51,6 +52,7 @@
         Assume.assumeFalse(isShellTransitionsEnabled)
     }
 
+    /** {@inheritDoc} */
     override val transition: FlickerBuilder.() -> Unit
         get() = buildTransition {
             setup {
@@ -59,15 +61,21 @@
                         val addBubbleBtn = waitAndGetAddBubbleBtn()
                         addBubbleBtn?.run { addBubbleBtn.click() } ?: error("Add Bubble not found")
                     }
-                    val showBubble = device.wait(Until.findObject(
-                            By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME)), FIND_OBJECT_TIMEOUT)
+                    val showBubble = device.wait(
+                        Until.findObject(
+                            By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME)
+                        ), FIND_OBJECT_TIMEOUT
+                    )
                     showBubble?.run { showBubble.click() } ?: error("Show bubble not found")
                     SystemClock.sleep(1000)
                 }
             }
             transitions {
-                val bubbles = device.wait(Until.findObjects(
-                        By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME)), FIND_OBJECT_TIMEOUT)
+                val bubbles = device.wait(
+                    Until.findObjects(
+                        By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME)
+                    ), FIND_OBJECT_TIMEOUT
+                )
                 for (entry in bubbles) {
                     entry?.run { entry.click() } ?: error("Bubble not found")
                     SystemClock.sleep(1000)
@@ -79,7 +87,73 @@
     @Test
     open fun testAppIsAlwaysVisible() {
         testSpec.assertLayers {
-            this.isVisible(testApp.component)
+            this.isVisible(testApp)
         }
     }
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun entireScreenCovered() =
+        super.entireScreenCovered()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerIsVisibleAtStartAndEnd() =
+        super.navBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerPositionAtStartAndEnd() =
+        super.navBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarWindowIsAlwaysVisible() =
+        super.navBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerIsVisibleAtStartAndEnd() =
+        super.statusBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarWindowIsAlwaysVisible() =
+        super.statusBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarLayerIsVisibleAtStartAndEnd() =
+        super.taskBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarWindowIsAlwaysVisible() =
+        super.taskBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt
index f4305ed..ffbac39 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt
@@ -17,10 +17,10 @@
 package com.android.wm.shell.flicker.helpers
 
 import android.app.Instrumentation
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
 
 class AppPairsHelper(
     instrumentation: Instrumentation,
     activityLabel: String,
-    component: FlickerComponentName
+    component: IComponentMatcher
 ) : BaseAppHelper(instrumentation, activityLabel, component)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt
index 912ba67..c4379e9 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt
@@ -19,7 +19,6 @@
 import android.app.Instrumentation
 import android.content.pm.PackageManager.FEATURE_LEANBACK
 import android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY
-import android.os.SystemProperties
 import android.support.test.launcherhelper.LauncherStrategyFactory
 import android.util.Log
 import androidx.test.uiautomator.By
@@ -27,13 +26,13 @@
 import androidx.test.uiautomator.Until
 import com.android.compatibility.common.util.SystemUtil
 import com.android.server.wm.flicker.helpers.StandardAppHelper
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
 import java.io.IOException
 
 abstract class BaseAppHelper(
     instrumentation: Instrumentation,
     launcherName: String,
-    component: FlickerComponentName
+    component: IComponentMatcher
 ) : StandardAppHelper(
     instrumentation,
     launcherName,
@@ -48,7 +47,7 @@
         }
 
     val defaultWindowName: String
-        get() = component.toWindowName()
+        get() = toWindowName()
 
     val ui: UiObject2?
         get() = uiDevice.findObject(appSelector)
@@ -60,9 +59,6 @@
     companion object {
         private const val APP_CLOSE_WAIT_TIME_MS = 3_000L
 
-        fun isShellTransitionsEnabled() =
-                SystemProperties.getBoolean("persist.wm.debug.shell_transit", false)
-
         fun executeShellCommand(instrumentation: Instrumentation, cmd: String) {
             try {
                 SystemUtil.runShellCommand(instrumentation, cmd)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/MultiWindowHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/MultiWindowHelper.kt
index 12ccbaf..92b1d21 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/MultiWindowHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/MultiWindowHelper.kt
@@ -19,12 +19,12 @@
 import android.app.Instrumentation
 import android.content.Context
 import android.provider.Settings
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
 
 class MultiWindowHelper(
     instrumentation: Instrumentation,
     activityLabel: String,
-    componentsInfo: FlickerComponentName
+    componentsInfo: IComponentMatcher
 ) : BaseAppHelper(instrumentation, activityLabel, componentsInfo) {
 
     companion object {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
index 216445f..bdc05e7 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
@@ -116,6 +116,10 @@
         clickObject(ENTER_PIP_ON_USER_LEAVE_HINT)
     }
 
+    fun enableAutoEnterForPipActivity() {
+        clickObject(ENTER_PIP_AUTOENTER)
+    }
+
     fun clickStartMediaSessionButton() {
         clickObject(MEDIA_SESSION_START_RADIO_BUTTON_ID)
     }
@@ -145,7 +149,7 @@
     }
 
     private fun getWindowRect(wmHelper: WindowManagerStateHelper): Rect {
-        val windowRegion = wmHelper.getWindowRegion(component)
+        val windowRegion = wmHelper.getWindowRegion(this)
         require(!windowRegion.isEmpty) {
             "Unable to find a PIP window in the current state"
         }
@@ -192,7 +196,7 @@
         uiDevice.click(expandButtonBounds.centerX(), expandButtonBounds.centerY())
         wmHelper.StateSyncBuilder()
             .withPipGone()
-            .withFullScreenApp(component)
+            .withFullScreenApp(this)
             .waitForAndVerify()
     }
 
@@ -214,5 +218,6 @@
         private const val WITH_CUSTOM_ACTIONS_BUTTON_ID = "with_custom_actions"
         private const val MEDIA_SESSION_START_RADIO_BUTTON_ID = "media_session_start"
         private const val ENTER_PIP_ON_USER_LEAVE_HINT = "enter_pip_on_leave_manual"
+        private const val ENTER_PIP_AUTOENTER = "enter_pip_on_leave_autoenter"
     }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt
index 49eca63..ccd5f02 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt
@@ -26,17 +26,16 @@
 import androidx.test.uiautomator.UiDevice
 import androidx.test.uiautomator.Until
 import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
 import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME
 import com.android.wm.shell.flicker.testapp.Components
-import org.junit.Assert
 
 class SplitScreenHelper(
     instrumentation: Instrumentation,
     activityLabel: String,
-    componentsInfo: FlickerComponentName
+    componentsInfo: IComponentMatcher
 ) : BaseAppHelper(instrumentation, activityLabel, componentsInfo) {
 
     companion object {
@@ -111,9 +110,9 @@
             }
 
             // Drag to split
-            var dragStart = notificationContent.visibleCenter
-            var dragMiddle = Point(dragStart.x + 50, dragStart.y)
-            var dragEnd = Point(displayBounds.width / 4, displayBounds.width / 4)
+            val dragStart = notificationContent.visibleCenter
+            val dragMiddle = Point(dragStart.x + 50, dragStart.y)
+            val dragEnd = Point(displayBounds.width / 4, displayBounds.width / 4)
             val downTime = SystemClock.uptimeMillis()
 
             touch(
@@ -199,10 +198,7 @@
             val allApps = taplInstrumentation.workspace.switchToAllApps()
             allApps.freeze()
             try {
-                val appIconSrc = allApps.getAppIcon(appName)
-                Assert.assertNotNull("Unable to find app icon", appIconSrc)
-                val appIconDest = appIconSrc.dragToHotseat(0)
-                Assert.assertNotNull("Unable to drag app icon on hotseat", appIconDest)
+                allApps.getAppIcon(appName).dragToHotseat(0)
             } finally {
                 allApps.unfreeze()
             }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
new file mode 100644
index 0000000..87fa548
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.pip
+
+import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.Postsubmit
+import androidx.test.filters.RequiresDevice
+import com.android.server.wm.flicker.FlickerParametersRunnerFactory
+import com.android.server.wm.flicker.FlickerTestParameter
+import com.android.server.wm.flicker.annotation.Group3
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import org.junit.Assume
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test entering pip from an app via auto-enter property when navigating to home.
+ *
+ * To run this test: `atest WMShellFlickerTests:AutoEnterPipOnGoToHomeTest`
+ *
+ * Actions:
+ *     Launch an app in full screen
+ *     Select "Auto-enter PiP" radio button
+ *     Press Home button or swipe up to go Home and put [pipApp] in pip mode
+ *
+ * Notes:
+ *     1. All assertions are inherited from [EnterPipTest]
+ *     2. Part of the test setup occurs automatically via
+ *        [com.android.server.wm.flicker.TransitionRunnerWithRules],
+ *        including configuring navigation mode, initial orientation and ensuring no
+ *        apps are running before setup
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 238367575)
+@Group3
+class AutoEnterPipOnGoToHomeTest(testSpec: FlickerTestParameter) : EnterPipTest(testSpec) {
+    /**
+     * Defines the transition used to run the test
+     */
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            setupAndTeardown(this)
+            setup {
+                eachRun {
+                    pipApp.launchViaIntent(wmHelper)
+                    pipApp.enableAutoEnterForPipActivity()
+                }
+            }
+            teardown {
+                eachRun {
+                    // close gracefully so that onActivityUnpinned() can be called before force exit
+                    pipApp.closePipWindow(wmHelper)
+                    pipApp.exit(wmHelper)
+                }
+            }
+            transitions {
+                tapl.goHome()
+            }
+        }
+
+    @Test
+    override fun pipLayerReduces() {
+        testSpec.assertLayers {
+            val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible }
+            pipLayerList.zipWithNext { previous, current ->
+                current.visibleRegion.notBiggerThan(previous.visibleRegion.region)
+            }
+        }
+    }
+
+    /**
+     * Checks that [pipApp] window is animated towards default position in right bottom corner
+     */
+    @Test
+    fun pipLayerMovesTowardsRightBottomCorner() {
+        // in gestural nav the swipe makes PiP first go upwards
+        Assume.assumeFalse(testSpec.isGesturalNavigation)
+        testSpec.assertLayers {
+            val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible }
+            // Pip animates towards the right bottom corner, but because it is being resized at the
+            // same time, it is possible it shrinks first quickly below the default position and get
+            // moved up after that in just few last frames
+            pipLayerList.zipWithNext { previous, current ->
+                current.visibleRegion.isToTheRightBottom(previous.visibleRegion.region, 3)
+            }
+        }
+    }
+
+    @Test
+    override fun focusChanges() {
+        // in gestural nav the focus goes to different activity on swipe up
+        Assume.assumeFalse(testSpec.isGesturalNavigation)
+        super.focusChanges()
+    }
+
+    @Postsubmit
+    @Test
+    override fun entireScreenCovered() = super.entireScreenCovered()
+
+    @Postsubmit
+    @Test
+    override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
+
+    @Postsubmit
+    @Test
+    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+
+    @Postsubmit
+    @Test
+    override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
+
+    @Postsubmit
+    @Test
+    override fun pipAppLayerAlwaysVisible() = super.pipAppLayerAlwaysVisible()
+
+    @Postsubmit
+    @Test
+    override fun pipLayerRemainInsideVisibleBounds() = super.pipLayerRemainInsideVisibleBounds()
+
+    @Postsubmit
+    @Test
+    override fun statusBarLayerIsVisibleAtStartAndEnd() =
+        super.statusBarLayerIsVisibleAtStartAndEnd()
+
+    @Postsubmit
+    @Test
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
+
+    @Postsubmit
+    @Test
+    override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+    @Postsubmit
+    @Test
+    override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
+
+    @Postsubmit
+    @Test
+    override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
+
+    @Postsubmit
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+    @Postsubmit
+    @Test
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
index cb84fc4..42aac57 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
@@ -16,13 +16,18 @@
 
 package com.android.wm.shell.flicker.pip
 
+import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.Postsubmit
+import android.platform.test.annotations.Presubmit
 import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.annotation.Group3
 import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import org.junit.Assume
 import org.junit.FixMethodOrder
+import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.MethodSorters
 import org.junit.runners.Parameterized
@@ -35,7 +40,7 @@
  * Actions:
  *     Launch an app in full screen
  *     Select "Via code behind" radio button
- *     Press Home button to put [pipApp] in pip mode
+ *     Press Home button or swipe up to go Home and put [pipApp] in pip mode
  *
  * Notes:
  *     1. All assertions are inherited from [EnterPipTest]
@@ -72,37 +77,64 @@
             }
         }
 
+    @Postsubmit
+    @Test
     override fun pipAppLayerAlwaysVisible() {
         if (!testSpec.isGesturalNavigation) super.pipAppLayerAlwaysVisible() else {
             // pip layer in gesture nav will disappear during transition
             testSpec.assertLayers {
-                this.isVisible(pipApp.component)
-                    .then().isInvisible(pipApp.component)
-                    .then().isVisible(pipApp.component)
+                this.isVisible(pipApp)
+                    .then().isInvisible(pipApp)
+                    .then().isVisible(pipApp)
             }
         }
     }
 
+    @Postsubmit
+    @Test
     override fun pipLayerReduces() {
         // in gestural nav the pip enters through alpha animation
         Assume.assumeFalse(testSpec.isGesturalNavigation)
         super.pipLayerReduces()
     }
 
+    @Postsubmit
+    @Test
     override fun focusChanges() {
         // in gestural nav the focus goes to different activity on swipe up
         Assume.assumeFalse(testSpec.isGesturalNavigation)
         super.focusChanges()
     }
 
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun pipAppWindowAlwaysVisible() = super.pipAppWindowAlwaysVisible()
+
+    @Presubmit
+    @Test
+    override fun entireScreenCovered() {
+        Assume.assumeFalse(isShellTransitionsEnabled)
+        super.entireScreenCovered()
+    }
+
+    @FlakyTest(bugId = 227313015)
+    @Test
+    fun entireScreenCovered_ShellTransit() {
+        Assume.assumeTrue(isShellTransitionsEnabled)
+        super.entireScreenCovered()
+    }
+
+    @Postsubmit
+    @Test
     override fun pipLayerRemainInsideVisibleBounds() {
         if (!testSpec.isGesturalNavigation) super.pipLayerRemainInsideVisibleBounds() else {
             // pip layer in gesture nav will disappear during transition
             testSpec.assertLayersStart {
-                this.visibleRegion(pipApp.component).coversAtMost(displayBounds)
+                this.visibleRegion(pipApp).coversAtMost(displayBounds)
             }
             testSpec.assertLayersEnd {
-                this.visibleRegion(pipApp.component).coversAtMost(displayBounds)
+                this.visibleRegion(pipApp).coversAtMost(displayBounds)
             }
         }
     }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
index 19c573b..edfa63a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
@@ -25,7 +25,7 @@
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group3
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.traces.common.FlickerComponentName.Companion.LAUNCHER
+import com.android.server.wm.traces.common.ComponentMatcher
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -56,9 +56,7 @@
 @Group3
 open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) {
 
-    /**
-     * Defines the transition used to run the test
-     */
+    /** {@inheritDoc}  */
     override val transition: FlickerBuilder.() -> Unit
         get() = {
             setupAndTeardown(this)
@@ -82,20 +80,20 @@
      */
     @Presubmit
     @Test
-    fun pipAppWindowAlwaysVisible() {
+    open fun pipAppWindowAlwaysVisible() {
         testSpec.assertWm {
-            this.isAppWindowVisible(pipApp.component)
+            this.isAppWindowVisible(pipApp)
         }
     }
 
     /**
      * Checks [pipApp] layer remains visible throughout the animation
      */
-    @Presubmit
+    @FlakyTest
     @Test
     open fun pipAppLayerAlwaysVisible() {
         testSpec.assertLayers {
-            this.isVisible(pipApp.component)
+            this.isVisible(pipApp)
         }
     }
 
@@ -106,7 +104,7 @@
     @Presubmit
     @Test
     fun pipWindowRemainInsideVisibleBounds() {
-        testSpec.assertWmVisibleRegion(pipApp.component) {
+        testSpec.assertWmVisibleRegion(pipApp) {
             coversAtMost(displayBounds)
         }
     }
@@ -118,7 +116,7 @@
     @Presubmit
     @Test
     open fun pipLayerRemainInsideVisibleBounds() {
-        testSpec.assertLayersVisibleRegion(pipApp.component) {
+        testSpec.assertLayersVisibleRegion(pipApp) {
             coversAtMost(displayBounds)
         }
     }
@@ -129,9 +127,8 @@
     @Presubmit
     @Test
     open fun pipLayerReduces() {
-        val layerName = pipApp.component.toLayerName()
         testSpec.assertLayers {
-            val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible }
+            val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible }
             pipLayerList.zipWithNext { previous, current ->
                 current.visibleRegion.coversAtMost(previous.visibleRegion.region)
             }
@@ -145,22 +142,22 @@
     @Test
     fun pipWindowBecomesPinned() {
         testSpec.assertWm {
-            invoke("pipWindowIsNotPinned") { it.isNotPinned(pipApp.component) }
+            invoke("pipWindowIsNotPinned") { it.isNotPinned(pipApp) }
                 .then()
-                .invoke("pipWindowIsPinned") { it.isPinned(pipApp.component) }
+                .invoke("pipWindowIsPinned") { it.isPinned(pipApp) }
         }
     }
 
     /**
-     * Checks [LAUNCHER] layer remains visible throughout the animation
+     * Checks [ComponentMatcher.LAUNCHER] layer remains visible throughout the animation
      */
     @Presubmit
     @Test
     fun launcherLayerBecomesVisible() {
         testSpec.assertLayers {
-            isInvisible(LAUNCHER)
+            isInvisible(ComponentMatcher.LAUNCHER)
                 .then()
-                .isVisible(LAUNCHER)
+                .isVisible(ComponentMatcher.LAUNCHER)
         }
     }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
index c2ed5a1..dff447b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
@@ -16,7 +16,9 @@
 
 package com.android.wm.shell.flicker.pip
 
+import android.app.Activity
 import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.view.Surface
 import androidx.test.filters.RequiresDevice
@@ -27,13 +29,15 @@
 import com.android.server.wm.flicker.dsl.FlickerBuilder
 import com.android.server.wm.flicker.entireScreenCovered
 import com.android.server.wm.flicker.helpers.WindowUtils
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.flicker.navBarLayerPositionAtStartAndEnd
+import com.android.server.wm.traces.common.ComponentMatcher
 import com.android.wm.shell.flicker.helpers.FixedAppHelper
 import com.android.wm.shell.flicker.pip.PipTransition.BroadcastActionTrigger.Companion.ORIENTATION_LANDSCAPE
 import com.android.wm.shell.flicker.pip.PipTransition.BroadcastActionTrigger.Companion.ORIENTATION_PORTRAIT
 import com.android.wm.shell.flicker.testapp.Components.FixedActivity.EXTRA_FIXED_ORIENTATION
 import com.android.wm.shell.flicker.testapp.Components.PipActivity.ACTION_ENTER_PIP
+import org.junit.Assume
+import org.junit.Before
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -80,11 +84,17 @@
             setup {
                 eachRun {
                     // Launch a portrait only app on the fullscreen stack
-                    testApp.launchViaIntent(wmHelper, stringExtras = mapOf(
-                        EXTRA_FIXED_ORIENTATION to ORIENTATION_PORTRAIT.toString()))
+                    testApp.launchViaIntent(
+                        wmHelper, stringExtras = mapOf(
+                            EXTRA_FIXED_ORIENTATION to ORIENTATION_PORTRAIT.toString()
+                        )
+                    )
                     // Launch the PiP activity fixed as landscape
-                    pipApp.launchViaIntent(wmHelper, stringExtras = mapOf(
-                        EXTRA_FIXED_ORIENTATION to ORIENTATION_LANDSCAPE.toString()))
+                    pipApp.launchViaIntent(
+                        wmHelper, stringExtras = mapOf(
+                            EXTRA_FIXED_ORIENTATION to ORIENTATION_LANDSCAPE.toString()
+                        )
+                    )
                 }
             }
             teardown {
@@ -100,19 +110,28 @@
                 // during rotation the status bar becomes invisible and reappears at the end
                 wmHelper.StateSyncBuilder()
                     .withPipShown()
-                    .withAppTransitionIdle()
-                    .withNavBarStatusBarVisible()
+                    .withNavOrTaskBarVisible()
+                    .withStatusBarVisible()
                     .waitForAndVerify()
             }
         }
 
     /**
-     * Checks that the [FlickerComponentName.NAV_BAR] has the correct position at
+     * This test is not compatible with Tablets. When using [Activity.setRequestedOrientation]
+     * to fix a orientation, Tablets instead keep the same orientation and add letterboxes
+     */
+    @Before
+    fun setup() {
+        Assume.assumeFalse(testSpec.isTablet)
+    }
+
+    /**
+     * Checks that the [ComponentMatcher.NAV_BAR] has the correct position at
      * the start and end of the transition
      */
     @FlakyTest
     @Test
-    override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
+    override fun navBarLayerPositionAtStartAndEnd() = testSpec.navBarLayerPositionAtStartAndEnd()
 
     /**
      * Checks that all parts of the screen are covered at the start and end of the transition
@@ -121,7 +140,7 @@
      */
     @Presubmit
     @Test
-    override fun entireScreenCovered() = testSpec.entireScreenCovered(allStates = false)
+    fun entireScreenCoveredAtStartAndEnd() = testSpec.entireScreenCovered(allStates = false)
 
     /**
      * Checks [pipApp] window remains visible and on top throughout the transition
@@ -130,7 +149,7 @@
     @Test
     fun pipAppWindowIsAlwaysOnTop() {
         testSpec.assertWm {
-            isAppWindowOnTop(pipApp.component)
+            isAppWindowOnTop(pipApp)
         }
     }
 
@@ -141,7 +160,7 @@
     @Test
     fun testAppWindowInvisibleOnStart() {
         testSpec.assertWmStart {
-            isAppWindowInvisible(testApp.component)
+            isAppWindowInvisible(testApp)
         }
     }
 
@@ -152,7 +171,7 @@
     @Test
     fun testAppWindowVisibleOnEnd() {
         testSpec.assertWmEnd {
-            isAppWindowVisible(testApp.component)
+            isAppWindowVisible(testApp)
         }
     }
 
@@ -163,7 +182,7 @@
     @Test
     fun testAppLayerInvisibleOnStart() {
         testSpec.assertLayersStart {
-            isInvisible(testApp.component)
+            isInvisible(testApp)
         }
     }
 
@@ -174,7 +193,7 @@
     @Test
     fun testAppLayerVisibleOnEnd() {
         testSpec.assertLayersEnd {
-            isVisible(testApp.component)
+            isVisible(testApp)
         }
     }
 
@@ -186,7 +205,7 @@
     @Test
     fun pipAppLayerCoversFullScreenOnStart() {
         testSpec.assertLayersStart {
-            visibleRegion(pipApp.component).coversExactly(startingBounds)
+            visibleRegion(pipApp).coversExactly(startingBounds)
         }
     }
 
@@ -198,13 +217,24 @@
     @Test
     fun testAppPlusPipLayerCoversFullScreenOnEnd() {
         testSpec.assertLayersEnd {
-            val pipRegion = visibleRegion(pipApp.component).region
-            visibleRegion(testApp.component)
+            val pipRegion = visibleRegion(pipApp).region
+            visibleRegion(testApp)
                 .plus(pipRegion)
                 .coversExactly(endingBounds)
         }
     }
 
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc}  */
+    @FlakyTest(bugId = 227313015)
+    @Test
+    override fun entireScreenCovered() = super.entireScreenCovered()
+
     companion object {
         /**
          * Creates the test configurations.
@@ -216,8 +246,10 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0),
-                    repetitions = 3)
+                .getConfigNonRotationTests(
+                    supportedRotations = listOf(Surface.ROTATION_0),
+                    repetitions = 3
+                )
         }
     }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt
index 990872f..45851c8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt
@@ -34,7 +34,7 @@
     @Presubmit
     @Test
     open fun pipAppWindowRemainInsideVisibleBounds() {
-        testSpec.assertWmVisibleRegion(pipApp.component) {
+        testSpec.assertWmVisibleRegion(pipApp) {
             coversAtMost(displayBounds)
         }
     }
@@ -46,7 +46,7 @@
     @Presubmit
     @Test
     open fun pipAppLayerRemainInsideVisibleBounds() {
-        testSpec.assertLayersVisibleRegion(pipApp.component) {
+        testSpec.assertLayersVisibleRegion(pipApp) {
             coversAtMost(displayBounds)
         }
     }
@@ -62,11 +62,11 @@
             // when the activity is STOPPING, sometimes it becomes invisible in an entry before
             // the window, sometimes in the same entry. This occurs because we log 1x per frame
             // thus we ignore activity here
-            isAppWindowVisible(testApp.component)
-                    .isAppWindowOnTop(pipApp.component)
-                    .then()
-                    .isAppWindowInvisible(testApp.component)
-                    .isAppWindowVisible(pipApp.component)
+            isAppWindowVisible(testApp)
+                .isAppWindowOnTop(pipApp)
+                .then()
+                .isAppWindowInvisible(testApp)
+                .isAppWindowVisible(pipApp)
         }
     }
 
@@ -78,11 +78,11 @@
     @Test
     open fun showBothAppLayersThenHidePip() {
         testSpec.assertLayers {
-            isVisible(testApp.component)
-                    .isVisible(pipApp.component)
-                    .then()
-                    .isInvisible(testApp.component)
-                    .isVisible(pipApp.component)
+            isVisible(testApp)
+                .isVisible(pipApp)
+                .then()
+                .isInvisible(testApp)
+                .isVisible(pipApp)
         }
     }
 
@@ -94,10 +94,10 @@
     @Test
     open fun testPlusPipAppsCoverFullScreenAtStart() {
         testSpec.assertLayersStart {
-            val pipRegion = visibleRegion(pipApp.component).region
-            visibleRegion(testApp.component)
-                    .plus(pipRegion)
-                    .coversExactly(displayBounds)
+            val pipRegion = visibleRegion(pipApp).region
+            visibleRegion(testApp)
+                .plus(pipRegion)
+                .coversExactly(displayBounds)
         }
     }
 
@@ -109,7 +109,7 @@
     @Test
     open fun pipAppCoversFullScreenAtEnd() {
         testSpec.assertLayersEnd {
-            visibleRegion(pipApp.component).coversExactly(displayBounds)
+            visibleRegion(pipApp).coversExactly(displayBounds)
         }
     }
 
@@ -119,12 +119,16 @@
     @Presubmit
     @Test
     open fun pipLayerExpands() {
-        val layerName = pipApp.component.toLayerName()
         testSpec.assertLayers {
-            val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible }
+            val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible }
             pipLayerList.zipWithNext { previous, current ->
                 current.visibleRegion.coversAtLeast(previous.visibleRegion.region)
             }
         }
     }
+
+    /** {@inheritDoc}  */
+    @Presubmit
+    @Test
+    override fun entireScreenCovered() = super.entireScreenCovered()
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt
index 47215b9..33f7871 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt
@@ -16,13 +16,14 @@
 
 package com.android.wm.shell.flicker.pip
 
+import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.view.Surface
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.dsl.FlickerBuilder
 import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.traces.common.FlickerComponentName.Companion.LAUNCHER
+import com.android.server.wm.traces.common.ComponentMatcher.Companion.LAUNCHER
 import org.junit.Test
 
 /**
@@ -57,21 +58,21 @@
             // and isAppWindowInvisible in the same assertion block.
             testSpec.assertWm {
                 this.invoke("hasPipWindow") {
-                    it.isPinned(pipApp.component)
-                            .isAppWindowVisible(pipApp.component)
-                            .isAppWindowOnTop(pipApp.component)
+                    it.isPinned(pipApp)
+                        .isAppWindowVisible(pipApp)
+                        .isAppWindowOnTop(pipApp)
                 }.then().invoke("!hasPipWindow") {
-                    it.isNotPinned(pipApp.component)
-                            .isAppWindowNotOnTop(pipApp.component)
+                    it.isNotPinned(pipApp)
+                        .isAppWindowNotOnTop(pipApp)
                 }
             }
-            testSpec.assertWmEnd { isAppWindowInvisible(pipApp.component) }
+            testSpec.assertWmEnd { isAppWindowInvisible(pipApp) }
         } else {
             testSpec.assertWm {
                 this.invoke("hasPipWindow") {
-                    it.isPinned(pipApp.component).isAppWindowVisible(pipApp.component)
+                    it.isPinned(pipApp).isAppWindowVisible(pipApp)
                 }.then().invoke("!hasPipWindow") {
-                    it.isNotPinned(pipApp.component).isAppWindowInvisible(pipApp.component)
+                    it.isNotPinned(pipApp).isAppWindowInvisible(pipApp)
                 }
             }
         }
@@ -86,11 +87,70 @@
     @Test
     open fun pipLayerBecomesInvisible() {
         testSpec.assertLayers {
-            this.isVisible(pipApp.component)
+            this.isVisible(pipApp)
                 .isVisible(LAUNCHER)
                 .then()
-                .isInvisible(pipApp.component)
+                .isInvisible(pipApp)
                 .isVisible(LAUNCHER)
         }
     }
+
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun entireScreenCovered() = super.entireScreenCovered()
+
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerIsVisibleAtStartAndEnd() =
+        super.statusBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
index 4e7a9ff..b5a3c78 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
@@ -54,7 +54,6 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group3
-@FlakyTest(bugId = 219750830)
 class ExitPipViaExpandButtonClickTest(
     testSpec: FlickerTestParameter
 ) : ExitPipToAppTransition(testSpec) {
@@ -75,12 +74,17 @@
                 pipApp.expandPipWindowToApp(wmHelper)
                 // Wait until the other app is no longer visible
                 wmHelper.StateSyncBuilder()
-                    .withWindowSurfaceDisappeared(testApp.component)
+                    .withWindowSurfaceDisappeared(testApp)
                     .waitForAndVerify()
             }
         }
 
     /** {@inheritDoc}  */
+    @FlakyTest(bugId = 227313015)
+    @Test
+    override fun entireScreenCovered() = super.entireScreenCovered()
+
+    /** {@inheritDoc}  */
     @FlakyTest(bugId = 197726610)
     @Test
     override fun pipLayerExpands() = super.pipLayerExpands()
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
index 3fbea48..1d26614 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
@@ -74,7 +74,7 @@
                 pipApp.exitPipToFullScreenViaIntent(wmHelper)
                 // Wait until the other app is no longer visible
                 wmHelper.StateSyncBuilder()
-                    .withWindowSurfaceDisappeared(testApp.component)
+                    .withWindowSurfaceDisappeared(testApp)
                     .waitForAndVerify()
             }
         }
@@ -82,16 +82,16 @@
     /** {@inheritDoc}  */
     @FlakyTest(bugId = 206753786)
     @Test
-    override fun statusBarLayerRotatesScales() {
+    override fun statusBarLayerPositionAtStartAndEnd() {
         Assume.assumeFalse(isShellTransitionsEnabled)
-        super.statusBarLayerRotatesScales()
+        super.statusBarLayerPositionAtStartAndEnd()
     }
 
     @Presubmit
     @Test
     fun statusBarLayerRotatesScales_ShellTransit() {
         Assume.assumeTrue(isShellTransitionsEnabled)
-        super.statusBarLayerRotatesScales()
+        super.statusBarLayerPositionAtStartAndEnd()
     }
 
     /** {@inheritDoc}  */
@@ -109,6 +109,11 @@
         super.pipLayerExpands()
     }
 
+    /** {@inheritDoc}  */
+    @FlakyTest(bugId = 227313015)
+    @Test
+    override fun entireScreenCovered() = super.entireScreenCovered()
+
     companion object {
         /**
          * Creates the test configurations.
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt
index b9e72a4..5b5b9fc 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt
@@ -16,7 +16,6 @@
 
 package com.android.wm.shell.flicker.pip
 
-import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.Presubmit
 import android.view.Surface
 import androidx.test.filters.RequiresDevice
@@ -25,6 +24,7 @@
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group3
 import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.traces.common.ComponentMatcher
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -58,28 +58,31 @@
         get() = {
             super.transition(this)
             transitions {
-                val pipRegion = wmHelper.getWindowRegion(pipApp.component).bounds
+                val pipRegion = wmHelper.getWindowRegion(pipApp).bounds
                 val pipCenterX = pipRegion.centerX()
                 val pipCenterY = pipRegion.centerY()
                 val displayCenterX = device.displayWidth / 2
-                device.swipe(pipCenterX, pipCenterY, displayCenterX, device.displayHeight, 10)
+                val barComponent = if (testSpec.isTablet) {
+                    ComponentMatcher.TASK_BAR
+                } else {
+                    ComponentMatcher.NAV_BAR
+                }
+                val barLayerHeight = wmHelper.currentState.layerState
+                    .getLayerWithBuffer(barComponent)
+                    ?.visibleRegion
+                    ?.height ?: error("Couldn't find Nav or Task bar layer")
+                // The dismiss button doesn't appear at the complete bottom of the screen,
+                val displayY = device.displayHeight - barLayerHeight
+                device.swipe(pipCenterX, pipCenterY, displayCenterX, displayY, 50)
                 // Wait until the other app is no longer visible
                 wmHelper.StateSyncBuilder()
                     .withPipGone()
-                    .withWindowSurfaceDisappeared(pipApp.component)
+                    .withWindowSurfaceDisappeared(pipApp)
                     .withAppTransitionIdle()
                     .waitForAndVerify()
             }
         }
 
-    @FlakyTest
-    @Test
-    override fun pipWindowBecomesInvisible() = super.pipWindowBecomesInvisible()
-
-    @FlakyTest
-    @Test
-    override fun pipLayerBecomesInvisible() = super.pipLayerBecomesInvisible()
-
     /**
      * Checks that the focus doesn't change between windows during the transition
      */
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
index 32900b1..1c0bd0c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
@@ -25,7 +25,7 @@
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group3
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.traces.common.FlickerComponentName.Companion.LAUNCHER
+import com.android.server.wm.traces.common.ComponentMatcher
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -69,7 +69,7 @@
     @Presubmit
     @Test
     fun pipWindowRemainInsideVisibleBounds() {
-        testSpec.assertWmVisibleRegion(pipApp.component) {
+        testSpec.assertWmVisibleRegion(pipApp) {
             coversAtMost(displayBounds)
         }
     }
@@ -81,7 +81,7 @@
     @Presubmit
     @Test
     fun pipLayerRemainInsideVisibleBounds() {
-        testSpec.assertLayersVisibleRegion(pipApp.component) {
+        testSpec.assertLayersVisibleRegion(pipApp) {
             coversAtMost(displayBounds)
         }
     }
@@ -93,7 +93,7 @@
     @Test
     fun pipWindowIsAlwaysVisible() {
         testSpec.assertWm {
-            isAppWindowVisible(pipApp.component)
+            isAppWindowVisible(pipApp)
         }
     }
 
@@ -104,7 +104,7 @@
     @Test
     fun pipLayerIsAlwaysVisible() {
         testSpec.assertLayers {
-            isVisible(pipApp.component)
+            isVisible(pipApp)
         }
     }
 
@@ -114,9 +114,8 @@
     @FlakyTest(bugId = 228012337)
     @Test
     fun pipLayerExpands() {
-        val layerName = pipApp.component.toLayerName()
         testSpec.assertLayers {
-            val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible }
+            val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible }
             pipLayerList.zipWithNext { previous, current ->
                 current.visibleRegion.coversAtLeast(previous.visibleRegion.region)
             }
@@ -126,9 +125,8 @@
     @Presubmit
     @Test
     fun pipSameAspectRatio() {
-        val layerName = pipApp.component.toLayerName()
         testSpec.assertLayers {
-            val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible }
+            val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible }
             pipLayerList.zipWithNext { previous, current ->
                 current.visibleRegion.isSameAspectRatio(previous.visibleRegion)
             }
@@ -142,18 +140,18 @@
     @Test
     fun windowIsAlwaysPinned() {
         testSpec.assertWm {
-            this.invoke("hasPipWindow") { it.isPinned(pipApp.component) }
+            this.invoke("hasPipWindow") { it.isPinned(pipApp) }
         }
     }
 
     /**
-     * Checks [LAUNCHER] layer remains visible throughout the animation
+     * Checks [ComponentMatcher.LAUNCHER] layer remains visible throughout the animation
      */
     @Presubmit
     @Test
     fun launcherIsAlwaysVisible() {
         testSpec.assertLayers {
-            isVisible(LAUNCHER)
+            isVisible(ComponentMatcher.LAUNCHER)
         }
     }
 
@@ -179,8 +177,10 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                    .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0),
-                            repetitions = 3)
+                .getConfigNonRotationTests(
+                    supportedRotations = listOf(Surface.ROTATION_0),
+                    repetitions = 3
+                )
         }
     }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt
index 768c090..b3f0fb9 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt
@@ -70,7 +70,7 @@
                 }
             }
             transitions {
-                taplInstrumentation.pressHome()
+                tapl.pressHome()
             }
         }
 
@@ -89,7 +89,8 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                    supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3)
+                supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3
+            )
         }
     }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt
index 0499e7d..9fb941e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt
@@ -17,7 +17,6 @@
 package com.android.wm.shell.flicker.pip
 
 import android.platform.test.annotations.Presubmit
-import com.android.launcher3.tapl.LauncherInstrumentation
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.traces.region.RegionSubject
 import com.android.wm.shell.flicker.helpers.FixedAppHelper
@@ -29,7 +28,6 @@
 abstract class MovePipShelfHeightTransition(
     testSpec: FlickerTestParameter
 ) : PipTransition(testSpec) {
-    protected val taplInstrumentation = LauncherInstrumentation()
     protected val testApp = FixedAppHelper(instrumentation)
 
     /**
@@ -44,7 +42,7 @@
     @Test
     open fun pipWindowIsAlwaysVisible() {
         testSpec.assertWm {
-            isAppWindowVisible(pipApp.component)
+            isAppWindowVisible(pipApp)
         }
     }
 
@@ -55,7 +53,7 @@
     @Test
     open fun pipLayerIsAlwaysVisible() {
         testSpec.assertLayers {
-            isVisible(pipApp.component)
+            isVisible(pipApp)
         }
     }
 
@@ -66,7 +64,7 @@
     @Presubmit
     @Test
     open fun pipWindowRemainInsideVisibleBounds() {
-        testSpec.assertWmVisibleRegion(pipApp.component) {
+        testSpec.assertWmVisibleRegion(pipApp) {
             coversAtMost(displayBounds)
         }
     }
@@ -78,7 +76,7 @@
     @Presubmit
     @Test
     open fun pipLayerRemainInsideVisibleBounds() {
-        testSpec.assertLayersVisibleRegion(pipApp.component) {
+        testSpec.assertLayersVisibleRegion(pipApp) {
             coversAtMost(displayBounds)
         }
     }
@@ -90,9 +88,8 @@
     @Presubmit
     @Test
     open fun pipWindowMoves() {
-        val windowName = pipApp.component.toWindowName()
         testSpec.assertWm {
-            val pipWindowList = this.windowStates { it.name.contains(windowName) && it.isVisible }
+            val pipWindowList = this.windowStates { pipApp.windowMatchesAnyOf(it) && it.isVisible }
             pipWindowList.zipWithNext { previous, current ->
                 assertRegionMovement(previous.frame, current.frame)
             }
@@ -105,12 +102,11 @@
     @Presubmit
     @Test
     open fun pipLayerMoves() {
-        val layerName = pipApp.component.toLayerName()
         testSpec.assertLayers {
-            val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible }
+            val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible }
             pipLayerList.zipWithNext { previous, current ->
                 assertRegionMovement(previous.visibleRegion, current.visibleRegion)
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt
index 4bc8eb1..8bd5c54 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt
@@ -73,7 +73,7 @@
         get() = buildTransition(eachRun = false) {
             teardown {
                 eachRun {
-                    taplInstrumentation.pressHome()
+                    tapl.pressHome()
                 }
                 test {
                     testApp.exit(wmHelper)
@@ -91,7 +91,8 @@
     /** {@inheritDoc}  */
     @FlakyTest(bugId = 206753786)
     @Test
-    override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
 
     companion object {
         /**
@@ -104,7 +105,8 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3)
+                supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3
+            )
         }
     }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
index 67c1c53..911d402 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
@@ -16,9 +16,9 @@
 
 package com.android.wm.shell.flicker.pip
 
+import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.Presubmit
 import android.view.Surface
-import android.platform.test.annotations.FlakyTest
 import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
@@ -28,7 +28,7 @@
 import com.android.server.wm.flicker.helpers.WindowUtils
 import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
 import com.android.wm.shell.flicker.helpers.ImeAppHelper
 import org.junit.Assume.assumeFalse
 import org.junit.Before
@@ -47,7 +47,6 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group4
-@FlakyTest(bugId = 218604389)
 open class PipKeyboardTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) {
     private val imeApp = ImeAppHelper(instrumentation)
 
@@ -56,6 +55,7 @@
         assumeFalse(isShellTransitionsEnabled)
     }
 
+    /** {@inheritDoc}  */
     override val transition: FlickerBuilder.() -> Unit
         get() = buildTransition(eachRun = false) {
             setup {
@@ -83,7 +83,8 @@
     /** {@inheritDoc}  */
     @FlakyTest(bugId = 206753786)
     @Test
-    override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
 
     /**
      * Ensure the pip window remains visible throughout any keyboard interactions
@@ -91,7 +92,7 @@
     @Presubmit
     @Test
     open fun pipInVisibleBounds() {
-        testSpec.assertWmVisibleRegion(pipApp.component) {
+        testSpec.assertWmVisibleRegion(pipApp) {
             val displayBounds = WindowUtils.getDisplayBounds(testSpec.startRotation)
             coversAtMost(displayBounds)
         }
@@ -104,7 +105,7 @@
     @Test
     open fun pipIsAboveAppWindow() {
         testSpec.assertWmTag(TAG_IME_VISIBLE) {
-            isAboveWindow(FlickerComponentName.IME, pipApp.component)
+            isAboveWindow(ComponentMatcher.IME, pipApp)
         }
     }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt
index fe51228..3e00b19 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt
@@ -44,5 +44,6 @@
 
     @Presubmit
     @Test
-    override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
-}
\ No newline at end of file
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
index 2c158b8..2abe6d5 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
@@ -16,9 +16,9 @@
 
 package com.android.wm.shell.flicker.pip
 
+import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.Presubmit
 import android.view.Surface
-import android.platform.test.annotations.FlakyTest
 import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
@@ -27,9 +27,11 @@
 import com.android.server.wm.flicker.dsl.FlickerBuilder
 import com.android.server.wm.flicker.entireScreenCovered
 import com.android.server.wm.flicker.helpers.WindowUtils
+import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
 import com.android.wm.shell.flicker.helpers.FixedAppHelper
+import org.junit.Assume
+import org.junit.Before
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -65,6 +67,11 @@
     private val screenBoundsStart = WindowUtils.getDisplayBounds(testSpec.startRotation)
     private val screenBoundsEnd = WindowUtils.getDisplayBounds(testSpec.endRotation)
 
+    @Before
+    open fun before() {
+        Assume.assumeFalse(isShellTransitionsEnabled)
+    }
+
     override val transition: FlickerBuilder.() -> Unit
         get() = buildTransition(eachRun = false) {
             setup {
@@ -92,16 +99,16 @@
      */
     @FlakyTest
     @Test
-    override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
+    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
 
     /**
      * Checks that [fixedApp] layer is within [screenBoundsStart] at the start of the transition
      */
     @Presubmit
     @Test
-    fun appLayerRotates_StartingBounds() {
+    fun fixedAppLayer_StartingBounds() {
         testSpec.assertLayersStart {
-            visibleRegion(fixedApp.component).coversExactly(screenBoundsStart)
+            visibleRegion(fixedApp).coversAtMost(screenBoundsStart)
         }
     }
 
@@ -110,9 +117,33 @@
      */
     @Presubmit
     @Test
-    fun appLayerRotates_EndingBounds() {
+    fun fixedAppLayer_EndingBounds() {
         testSpec.assertLayersEnd {
-            visibleRegion(fixedApp.component).coversExactly(screenBoundsEnd)
+            visibleRegion(fixedApp).coversAtMost(screenBoundsEnd)
+        }
+    }
+
+    /**
+     * Checks that [fixedApp] plus [pipApp] layers are within [screenBoundsEnd] at the start
+     * of the transition
+     */
+    @Presubmit
+    @Test
+    fun appLayers_StartingBounds() {
+        testSpec.assertLayersStart {
+            visibleRegion(fixedApp.or(pipApp)).coversExactly(screenBoundsStart)
+        }
+    }
+
+    /**
+     * Checks that [fixedApp] plus [pipApp] layers are within [screenBoundsEnd] at the end
+     * of the transition
+     */
+    @Presubmit
+    @Test
+    fun appLayers_EndingBounds() {
+        testSpec.assertLayersEnd {
+            visibleRegion(fixedApp.or(pipApp)).coversExactly(screenBoundsEnd)
         }
     }
 
@@ -121,7 +152,7 @@
      */
     private fun pipLayerRotates_StartingBounds_internal() {
         testSpec.assertLayersStart {
-            visibleRegion(pipApp.component).coversAtMost(screenBoundsStart)
+            visibleRegion(pipApp).coversAtMost(screenBoundsStart)
         }
     }
 
@@ -141,7 +172,7 @@
     @Test
     fun pipLayerRotates_EndingBounds() {
         testSpec.assertLayersEnd {
-            visibleRegion(pipApp.component).coversAtMost(screenBoundsEnd)
+            visibleRegion(pipApp).coversAtMost(screenBoundsEnd)
         }
     }
 
@@ -153,7 +184,7 @@
     @Test
     fun pipIsAboveFixedAppWindow_Start() {
         testSpec.assertWmStart {
-            isAboveWindow(pipApp.component, fixedApp.component)
+            isAboveWindow(pipApp, fixedApp)
         }
     }
 
@@ -165,7 +196,7 @@
     @Test
     fun pipIsAboveFixedAppWindow_End() {
         testSpec.assertWmEnd {
-            isAboveWindow(pipApp.component, fixedApp.component)
+            isAboveWindow(pipApp, fixedApp)
         }
     }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest_ShellTransit.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest_ShellTransit.kt
new file mode 100644
index 0000000..0dd38cd
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest_ShellTransit.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.pip
+
+import android.platform.test.annotations.FlakyTest
+import androidx.test.filters.RequiresDevice
+import com.android.server.wm.flicker.FlickerParametersRunnerFactory
+import com.android.server.wm.flicker.FlickerTestParameter
+import com.android.server.wm.flicker.annotation.Group4
+import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
+import org.junit.Assume
+import org.junit.Before
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test Pip Stack in bounds after rotations.
+ *
+ * To run this test: `atest WMShellFlickerTests:PipRotationTest_ShellTransit`
+ *
+ * Actions:
+ *     Launch a [pipApp] in pip mode
+ *     Launch another app [fixedApp] (appears below pip)
+ *     Rotate the screen from [testSpec.startRotation] to [testSpec.endRotation]
+ *     (usually, 0->90 and 90->0)
+ *
+ * Notes:
+ *     1. Some default assertions (e.g., nav bar, status bar and screen covered)
+ *        are inherited from [PipTransition]
+ *     2. Part of the test setup occurs automatically via
+ *        [com.android.server.wm.flicker.TransitionRunnerWithRules],
+ *        including configuring navigation mode, initial orientation and ensuring no
+ *        apps are running before setup
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@Group4
+@FlakyTest(bugId = 239575053)
+class PipRotationTest_ShellTransit(testSpec: FlickerTestParameter) : PipRotationTest(testSpec) {
+    @Before
+    override fun before() {
+        Assume.assumeTrue(isShellTransitionsEnabled)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt
deleted file mode 100644
index 7ba085d..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.flicker.pip
-
-import com.android.wm.shell.flicker.FlickerTestBase
-import com.android.wm.shell.flicker.helpers.PipAppHelper
-import org.junit.Before
-
-abstract class PipTestBase(
-    rotationName: String,
-    rotation: Int
-) : FlickerTestBase(rotationName, rotation) {
-    protected val testApp = PipAppHelper(instrumentation)
-
-    @Before
-    override fun televisionSetUp() {
-        /**
-         * The super implementation assumes ([org.junit.Assume]) that not running on TV, thus
-         * disabling the test on TV. This test, however, *should run on TV*, so we overriding this
-         * method and simply leaving it blank.
-         */
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
index fe5dd8b..9ade597 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
@@ -18,35 +18,22 @@
 
 import android.app.Instrumentation
 import android.content.Intent
-import android.platform.test.annotations.Presubmit
 import android.view.Surface
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.FlickerBuilderProvider
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
 import com.android.server.wm.flicker.helpers.WindowUtils
 import com.android.server.wm.flicker.helpers.setRotation
 import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
 import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
+import com.android.wm.shell.flicker.BaseTest
 import com.android.wm.shell.flicker.helpers.PipAppHelper
 import com.android.wm.shell.flicker.testapp.Components
-import org.junit.Test
 
-abstract class PipTransition(protected val testSpec: FlickerTestParameter) {
-    protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
-    protected val tapl = LauncherInstrumentation()
+abstract class PipTransition(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
     protected val pipApp = PipAppHelper(instrumentation)
     protected val displayBounds = WindowUtils.getDisplayBounds(testSpec.startRotation)
     protected val broadcastActionTrigger = BroadcastActionTrigger(instrumentation)
-    protected abstract val transition: FlickerBuilder.() -> Unit
+
     // Helper class to process test actions by broadcast.
     protected class BroadcastActionTrigger(private val instrumentation: Instrumentation) {
         private fun createIntentWithAction(broadcastAction: String): Intent {
@@ -69,13 +56,6 @@
         }
     }
 
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            transition(this)
-        }
-    }
-
     /**
      * Gets a configuration that handles basic setup and teardown of pip tests
      */
@@ -143,32 +123,4 @@
             extraSpec(this)
         }
     }
-
-    @Presubmit
-    @Test
-    open fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    open fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    open fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
-    @Presubmit
-    @Test
-    open fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible()
-
-    @Presubmit
-    @Test
-    open fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
-    @Presubmit
-    @Test
-    open fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
-    @Presubmit
-    @Test
-    open fun entireScreenCovered() = testSpec.entireScreenCovered()
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
index 1f078b4..6d64cb9 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
@@ -16,7 +16,9 @@
 
 package com.android.wm.shell.flicker.pip
 
+import android.app.Activity
 import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.view.Surface
 import androidx.test.filters.RequiresDevice
@@ -32,6 +34,8 @@
 import com.android.wm.shell.flicker.pip.PipTransition.BroadcastActionTrigger.Companion.ORIENTATION_LANDSCAPE
 import com.android.wm.shell.flicker.testapp.Components
 import com.android.wm.shell.flicker.testapp.Components.FixedActivity.EXTRA_FIXED_ORIENTATION
+import org.junit.Assume
+import org.junit.Before
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -53,6 +57,7 @@
     private val startingBounds = WindowUtils.getDisplayBounds(Surface.ROTATION_0)
     private val endingBounds = WindowUtils.getDisplayBounds(Surface.ROTATION_90)
 
+    /** {@inheritDoc}  */
     override val transition: FlickerBuilder.() -> Unit
         get() = {
             setup {
@@ -70,7 +75,8 @@
                     wmHelper.StateSyncBuilder()
                         .withPipShown()
                         .withRotation(Surface.ROTATION_0)
-                        .withNavBarStatusBarVisible()
+                        .withNavOrTaskBarVisible()
+                        .withStatusBarVisible()
                         .waitForAndVerify()
                 }
             }
@@ -88,14 +94,23 @@
                 pipApp.launchViaIntent(wmHelper)
                 // System bar may fade out during fixed rotation.
                 wmHelper.StateSyncBuilder()
-                    .withFullScreenApp(pipApp.component)
+                    .withFullScreenApp(pipApp)
                     .withRotation(Surface.ROTATION_90)
-                    .withAppTransitionIdle()
-                    .withNavBarStatusBarVisible()
+                    .withNavOrTaskBarVisible()
+                    .withStatusBarVisible()
                     .waitForAndVerify()
             }
         }
 
+    /**
+     * This test is not compatible with Tablets. When using [Activity.setRequestedOrientation]
+     * to fix a orientation, Tablets instead keep the same orientation and add letterboxes
+     */
+    @Before
+    fun setup() {
+        Assume.assumeFalse(testSpec.isTablet)
+    }
+
     @Presubmit
     @Test
     fun displayEndsAt90Degrees() {
@@ -104,23 +119,27 @@
         }
     }
 
+    /** {@inheritDoc}  */
     @Presubmit
     @Test
-    override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
+    override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
 
+    /** {@inheritDoc}  */
     @Presubmit
     @Test
-    override fun statusBarLayerIsVisible() = super.statusBarLayerIsVisible()
+    override fun statusBarLayerIsVisibleAtStartAndEnd() =
+        super.statusBarLayerIsVisibleAtStartAndEnd()
 
+    /** {@inheritDoc}  */
     @FlakyTest
     @Test
-    override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
+    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
 
     @Presubmit
     @Test
     fun pipWindowInsideDisplay() {
         testSpec.assertWmStart {
-            frameRegion(pipApp.component).coversAtMost(startingBounds)
+            visibleRegion(pipApp).coversAtMost(startingBounds)
         }
     }
 
@@ -128,7 +147,7 @@
     @Test
     fun pipAppShowsOnTop() {
         testSpec.assertWmEnd {
-            isAppWindowOnTop(pipApp.component)
+            isAppWindowOnTop(pipApp)
         }
     }
 
@@ -136,7 +155,7 @@
     @Test
     fun pipLayerInsideDisplay() {
         testSpec.assertLayersStart {
-            visibleRegion(pipApp.component).coversAtMost(startingBounds)
+            visibleRegion(pipApp).coversAtMost(startingBounds)
         }
     }
 
@@ -144,7 +163,7 @@
     @Test
     fun pipAlwaysVisible() {
         testSpec.assertWm {
-            this.isAppWindowVisible(pipApp.component)
+            this.isAppWindowVisible(pipApp)
         }
     }
 
@@ -152,10 +171,54 @@
     @Test
     fun pipAppLayerCoversFullScreen() {
         testSpec.assertLayersEnd {
-            visibleRegion(pipApp.component).coversExactly(endingBounds)
+            visibleRegion(pipApp).coversExactly(endingBounds)
         }
     }
 
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun entireScreenCovered() = super.entireScreenCovered()
+
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun navBarWindowIsAlwaysVisible() =
+        super.navBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc}  */
+    @Postsubmit
+    @Test
+    override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
     companion object {
         @Parameterized.Parameters(name = "{0}")
         @JvmStatic
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/PipTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/PipTestBase.kt
new file mode 100644
index 0000000..180ced0
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/PipTestBase.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.pip.tv
+
+import android.app.Instrumentation
+import android.content.pm.PackageManager
+import android.view.Surface
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.wm.shell.flicker.helpers.PipAppHelper
+import org.junit.Before
+import org.junit.runners.Parameterized
+
+abstract class PipTestBase(
+    protected val rotationName: String,
+    protected val rotation: Int
+) {
+    val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    val uiDevice = UiDevice.getInstance(instrumentation)
+    val packageManager: PackageManager = instrumentation.context.packageManager
+    protected val isTelevision: Boolean by lazy {
+        packageManager.run {
+            hasSystemFeature(PackageManager.FEATURE_LEANBACK) ||
+                hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY)
+        }
+    }
+    protected val testApp = PipAppHelper(instrumentation)
+
+    @Before
+    open fun televisionSetUp() {
+        /**
+         * The super implementation assumes ([org.junit.Assume]) that not running on TV, thus
+         * disabling the test on TV. This test, however, *should run on TV*, so we overriding this
+         * method and simply leaving it blank.
+         */
+    }
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): Collection<Array<Any>> {
+            val supportedRotations = intArrayOf(Surface.ROTATION_0, Surface.ROTATION_90)
+            return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt
index a97994e..aeff0ac 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt
@@ -25,7 +25,6 @@
 import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
 import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
 import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME
-import com.android.wm.shell.flicker.pip.PipTestBase
 import org.junit.After
 import org.junit.Assert.assertFalse
 import org.junit.Assume.assumeTrue
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
index cfba338..779be0a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
@@ -16,6 +16,7 @@
 
 package com.android.wm.shell.flicker.splitscreen
 
+import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.view.WindowManagerPolicyConstants
 import androidx.test.filters.RequiresDevice
@@ -57,7 +58,7 @@
 
     @Before
     fun before() {
-        Assume.assumeTrue(taplInstrumentation.isTablet)
+        Assume.assumeTrue(tapl.isTablet)
     }
 
     override val transition: FlickerBuilder.() -> Unit
@@ -65,12 +66,12 @@
             super.transition(this)
             setup {
                 eachRun {
-                    taplInstrumentation.goHome()
+                    tapl.goHome()
                     primaryApp.launchViaIntent(wmHelper)
                 }
             }
             transitions {
-                taplInstrumentation.launchedAppState.taskbar
+                tapl.launchedAppState.taskbar
                     .openAllApps()
                     .getAppIcon(secondaryApp.appName)
                     .dragToSplitscreen(secondaryApp.`package`, primaryApp.`package`)
@@ -83,30 +84,96 @@
 
     @Presubmit
     @Test
-    fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp.component)
+    fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp)
 
     @Presubmit
     @Test
-    fun secondaryAppLayerBecomesVisible() = testSpec.layerBecomesVisible(secondaryApp.component)
+    fun secondaryAppLayerBecomesVisible() = testSpec.layerBecomesVisible(secondaryApp)
 
     @Presubmit
     @Test
     fun primaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd(
-        testSpec.endRotation, primaryApp.component, false /* splitLeftTop */)
+        testSpec.endRotation, primaryApp, false /* splitLeftTop */)
 
     @Presubmit
     @Test
     fun secondaryAppBoundsBecomesVisible() = testSpec.splitAppLayerBoundsBecomesVisible(
-        testSpec.endRotation, secondaryApp.component, true /* splitLeftTop */)
+        testSpec.endRotation, secondaryApp, true /* splitLeftTop */)
 
     @Presubmit
     @Test
-    fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp.component)
+    fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp)
 
     @Presubmit
     @Test
     fun secondaryAppWindowBecomesVisible() =
-        testSpec.appWindowBecomesVisible(secondaryApp.component)
+        testSpec.appWindowBecomesVisible(secondaryApp)
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun entireScreenCovered() =
+        super.entireScreenCovered()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerIsVisibleAtStartAndEnd() =
+        super.navBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerPositionAtStartAndEnd() =
+        super.navBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarWindowIsAlwaysVisible() =
+        super.navBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerIsVisibleAtStartAndEnd() =
+        super.statusBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarWindowIsAlwaysVisible() =
+        super.statusBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarLayerIsVisibleAtStartAndEnd() =
+        super.taskBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarWindowIsAlwaysVisible() =
+        super.taskBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
 
     companion object {
         @Parameterized.Parameters(name = "{0}")
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
index 7323d99..d47d81b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
@@ -16,6 +16,7 @@
 
 package com.android.wm.shell.flicker.splitscreen
 
+import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.view.WindowManagerPolicyConstants
 import androidx.test.filters.RequiresDevice
@@ -60,9 +61,10 @@
 
     @Before
     fun before() {
-        Assume.assumeTrue(taplInstrumentation.isTablet)
+        Assume.assumeTrue(tapl.isTablet)
     }
 
+    /** {@inheritDoc} */
     override val transition: FlickerBuilder.() -> Unit
         get() = {
             super.transition(this)
@@ -76,7 +78,7 @@
                     )
                     sendNotification?.click() ?: error("Send notification button not found")
 
-                    taplInstrumentation.goHome()
+                    tapl.goHome()
                     primaryApp.launchViaIntent(wmHelper)
                 }
             }
@@ -96,33 +98,99 @@
 
     @Presubmit
     @Test
-    fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp.component)
+    fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp)
 
     @Presubmit
     @Test
     fun secondaryAppLayerBecomesVisible() =
-        testSpec.layerBecomesVisible(sendNotificationApp.component)
+        testSpec.layerBecomesVisible(sendNotificationApp)
 
     @Presubmit
     @Test
     fun primaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd(
-        testSpec.endRotation, primaryApp.component, false /* splitLeftTop */
+        testSpec.endRotation, primaryApp, false /* splitLeftTop */
     )
 
     @Presubmit
     @Test
     fun secondaryAppBoundsBecomesVisible() = testSpec.splitAppLayerBoundsBecomesVisible(
-        testSpec.endRotation, sendNotificationApp.component, true /* splitLeftTop */
+        testSpec.endRotation, sendNotificationApp, true /* splitLeftTop */
     )
 
     @Presubmit
     @Test
-    fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp.component)
+    fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp)
 
     @Presubmit
     @Test
     fun secondaryAppWindowIsVisibleAtEnd() =
-        testSpec.appWindowIsVisibleAtEnd(sendNotificationApp.component)
+        testSpec.appWindowIsVisibleAtEnd(sendNotificationApp)
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun entireScreenCovered() =
+        super.entireScreenCovered()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerIsVisibleAtStartAndEnd() =
+        super.navBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerPositionAtStartAndEnd() =
+        super.navBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarWindowIsAlwaysVisible() =
+        super.navBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerIsVisibleAtStartAndEnd() =
+        super.statusBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarWindowIsAlwaysVisible() =
+        super.statusBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarLayerIsVisibleAtStartAndEnd() =
+        super.taskBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarWindowIsAlwaysVisible() =
+        super.taskBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
 
     companion object {
         @Parameterized.Parameters(name = "{0}")
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
index 60b0f8e..1493d1f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
@@ -16,6 +16,7 @@
 
 package com.android.wm.shell.flicker.splitscreen
 
+import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.view.WindowManagerPolicyConstants
 import androidx.test.filters.RequiresDevice
@@ -57,23 +58,24 @@
 
     @Before
     fun before() {
-        Assume.assumeTrue(taplInstrumentation.isTablet)
+        Assume.assumeTrue(tapl.isTablet)
     }
 
+    /** {@inheritDoc} */
     override val transition: FlickerBuilder.() -> Unit
         get() = {
             super.transition(this)
             setup {
                 eachRun {
-                    taplInstrumentation.goHome()
+                    tapl.goHome()
                     SplitScreenHelper.createShortcutOnHotseatIfNotExist(
-                        taplInstrumentation, secondaryApp.appName
+                        tapl, secondaryApp.appName
                     )
                     primaryApp.launchViaIntent(wmHelper)
                 }
             }
             transitions {
-                taplInstrumentation.launchedAppState.taskbar
+                tapl.launchedAppState.taskbar
                     .getAppIcon(secondaryApp.appName)
                     .dragToSplitscreen(
                         secondaryApp.`package`,
@@ -88,32 +90,98 @@
 
     @Presubmit
     @Test
-    fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp.component)
+    fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp)
 
     @Presubmit
     @Test
-    fun secondaryAppLayerBecomesVisible() = testSpec.layerBecomesVisible(secondaryApp.component)
+    fun secondaryAppLayerBecomesVisible() = testSpec.layerBecomesVisible(secondaryApp)
 
     @Presubmit
     @Test
     fun primaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd(
-        testSpec.endRotation, primaryApp.component, false /* splitLeftTop */
+        testSpec.endRotation, primaryApp, splitLeftTop = false
     )
 
     @Presubmit
     @Test
     fun secondaryAppBoundsBecomesVisible() = testSpec.splitAppLayerBoundsBecomesVisible(
-        testSpec.endRotation, secondaryApp.component, true /* splitLeftTop */
+        testSpec.endRotation, secondaryApp, splitLeftTop = true
     )
 
     @Presubmit
     @Test
-    fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp.component)
+    fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp)
 
     @Presubmit
     @Test
     fun secondaryAppWindowBecomesVisible() =
-        testSpec.appWindowBecomesVisible(secondaryApp.component)
+        testSpec.appWindowBecomesVisible(secondaryApp)
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun entireScreenCovered() =
+        super.entireScreenCovered()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerIsVisibleAtStartAndEnd() =
+        super.navBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerPositionAtStartAndEnd() =
+        super.navBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarWindowIsAlwaysVisible() =
+        super.navBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerIsVisibleAtStartAndEnd() =
+        super.statusBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarWindowIsAlwaysVisible() =
+        super.statusBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarLayerIsVisibleAtStartAndEnd() =
+        super.taskBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarWindowIsAlwaysVisible() =
+        super.taskBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
 
     companion object {
         @Parameterized.Parameters(name = "{0}")
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt
index 52c2daf..81390b2 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt
@@ -16,37 +16,26 @@
 
 package com.android.wm.shell.flicker.splitscreen
 
-import android.app.Instrumentation
 import android.content.Context
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.FlickerBuilderProvider
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.dsl.FlickerBuilder
 import com.android.server.wm.flicker.helpers.setRotation
+import com.android.wm.shell.flicker.BaseTest
 import com.android.wm.shell.flicker.helpers.SplitScreenHelper
 
-abstract class SplitScreenBase(protected val testSpec: FlickerTestParameter) {
-    protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
-    protected val taplInstrumentation = LauncherInstrumentation()
+abstract class SplitScreenBase(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
     protected val context: Context = instrumentation.context
     protected val primaryApp = SplitScreenHelper.getPrimary(instrumentation)
     protected val secondaryApp = SplitScreenHelper.getSecondary(instrumentation)
 
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            transition(this)
-        }
-    }
-
-    protected open val transition: FlickerBuilder.() -> Unit
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit
         get() = {
             setup {
                 test {
-                    taplInstrumentation.setEnableRotation(true)
+                    tapl.setEnableRotation(true)
                     setRotation(testSpec.startRotation)
-                    taplInstrumentation.setExpectedRotation(testSpec.startRotation)
+                    tapl.setExpectedRotation(testSpec.startRotation)
                 }
             }
             teardown {
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml
index e9e7bb6..2290983 100644
--- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml
@@ -64,6 +64,13 @@
             android:layout_height="wrap_content"
             android:text="Via code behind"
             android:onClick="onAutoPipSelected"/>
+
+        <RadioButton
+            android:id="@+id/enter_pip_on_leave_autoenter"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Auto-enter PiP"
+            android:onClick="onAutoPipSelected"/>
     </RadioGroup>
 
     <RadioGroup
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java
index a39aa4d..615b173 100644
--- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java
@@ -236,6 +236,10 @@
                 mPipParamsBuilder.setAutoEnterEnabled(false);
                 setPictureInPictureParams(mPipParamsBuilder.build());
                 break;
+            case R.id.enter_pip_on_leave_autoenter:
+                mPipParamsBuilder.setAutoEnterEnabled(true);
+                setPictureInPictureParams(mPipParamsBuilder.build());
+                break;
         }
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/Android.bp b/libs/WindowManager/Shell/tests/unittest/Android.bp
index ea10be5..1a8b954 100644
--- a/libs/WindowManager/Shell/tests/unittest/Android.bp
+++ b/libs/WindowManager/Shell/tests/unittest/Android.bp
@@ -28,6 +28,9 @@
         "**/*.java",
         "**/*.kt",
     ],
+    resource_dirs: [
+        "res",
+    ],
 
     static_libs: [
         "WindowManager-Shell",
@@ -65,4 +68,9 @@
     optimize: {
         enabled: false,
     },
+
+    aaptflags: [
+        "--extra-packages",
+        "com.android.wm.shell.tests",
+    ],
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/MockSurfaceControlHelper.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/MockSurfaceControlHelper.java
new file mode 100644
index 0000000..4922872
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/MockSurfaceControlHelper.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell;
+
+import static org.mockito.Mockito.RETURNS_SELF;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import android.view.SurfaceControl;
+
+/**
+ * Helper class to provide mocks for {@link SurfaceControl.Builder} and
+ * {@link SurfaceControl.Transaction} with method chaining support.
+ */
+public class MockSurfaceControlHelper {
+    private MockSurfaceControlHelper() {}
+
+    /**
+     * Creates a mock {@link SurfaceControl.Builder} that supports method chaining and return the
+     * given {@link SurfaceControl} when calling {@link SurfaceControl.Builder#build()}.
+     *
+     * @param mockSurfaceControl the first {@link SurfaceControl} to return
+     * @param mockSurfaceControls following {@link SurfaceControl} to return
+     * @return the mock of {@link SurfaceControl.Builder}
+     */
+    public static SurfaceControl.Builder createMockSurfaceControlBuilder(
+            SurfaceControl mockSurfaceControl, SurfaceControl... mockSurfaceControls) {
+        final SurfaceControl.Builder mockBuilder = mock(SurfaceControl.Builder.class, RETURNS_SELF);
+        doReturn(mockSurfaceControl, (Object[]) mockSurfaceControls)
+                .when(mockBuilder)
+                .build();
+        return mockBuilder;
+    }
+
+    /**
+     * Creates a mock {@link SurfaceControl.Transaction} that supports method chaining.
+     * @return the mock of {@link SurfaceControl.Transaction}
+     */
+    public static SurfaceControl.Transaction createMockSurfaceControlTransaction() {
+        return mock(SurfaceControl.Transaction.class, RETURNS_SELF);
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellInitImplTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellInitImplTest.java
new file mode 100644
index 0000000..ace8d36
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellInitImplTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.activityembedding.ActivityEmbeddingController;
+import com.android.wm.shell.bubbles.BubbleController;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.DisplayInsetsController;
+import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.draganddrop.DragAndDropController;
+import com.android.wm.shell.freeform.FreeformTaskListener;
+import com.android.wm.shell.fullscreen.FullscreenTaskListener;
+import com.android.wm.shell.kidsmode.KidsModeTaskOrganizer;
+import com.android.wm.shell.pip.phone.PipTouchHandler;
+import com.android.wm.shell.recents.RecentTasksController;
+import com.android.wm.shell.splitscreen.SplitScreenController;
+import com.android.wm.shell.startingsurface.StartingWindowController;
+import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.unfold.UnfoldAnimationController;
+import com.android.wm.shell.unfold.UnfoldTransitionHandler;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.Optional;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+public class ShellInitImplTest extends ShellTestCase {
+
+    @Mock private DisplayController mDisplayController;
+    @Mock private DisplayImeController mDisplayImeController;
+    @Mock private DisplayInsetsController mDisplayInsetsController;
+    @Mock private DragAndDropController mDragAndDropController;
+    @Mock private ShellTaskOrganizer mShellTaskOrganizer;
+    @Mock private KidsModeTaskOrganizer mKidsModeTaskOrganizer;
+    @Mock private Optional<BubbleController> mBubblesOptional;
+    @Mock private Optional<SplitScreenController> mSplitScreenOptional;
+    @Mock private Optional<PipTouchHandler> mPipTouchHandlerOptional;
+    @Mock private FullscreenTaskListener mFullscreenTaskListener;
+    @Mock private Optional<UnfoldAnimationController> mUnfoldAnimationController;
+    @Mock private Optional<UnfoldTransitionHandler> mUnfoldTransitionHandler;
+    @Mock private Optional<FreeformTaskListener<?>> mFreeformTaskListenerOptional;
+    @Mock private Optional<RecentTasksController> mRecentTasks;
+    @Mock private Optional<ActivityEmbeddingController> mActivityEmbeddingController;
+    @Mock private Transitions mTransitions;
+    @Mock private StartingWindowController mStartingWindow;
+    @Mock private ShellExecutor mMainExecutor;
+
+    private ShellInitImpl mImpl;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mImpl = new ShellInitImpl(mDisplayController, mDisplayImeController,
+                mDisplayInsetsController, mDragAndDropController, mShellTaskOrganizer,
+                mKidsModeTaskOrganizer, mBubblesOptional, mSplitScreenOptional,
+                mPipTouchHandlerOptional, mFullscreenTaskListener, mUnfoldAnimationController,
+                mUnfoldTransitionHandler, mFreeformTaskListenerOptional, mRecentTasks,
+                mActivityEmbeddingController, mTransitions, mStartingWindow, mMainExecutor);
+    }
+
+    @Test
+    public void testAddInitCallbacks_expectCalledInOrder() {
+        ArrayList<Integer> results = new ArrayList<>();
+        mImpl.addInitCallback(() -> {
+            results.add(1);
+        }, new Object());
+        mImpl.addInitCallback(() -> {
+            results.add(2);
+        }, new Object());
+        mImpl.addInitCallback(() -> {
+            results.add(3);
+        }, new Object());
+        mImpl.init();
+        assertTrue(results.get(0) == 1);
+        assertTrue(results.get(1) == 2);
+        assertTrue(results.get(2) == 3);
+    }
+
+    @Test
+    public void testNoInitCallbacksAfterInit_expectException() {
+        mImpl.init();
+        try {
+            mImpl.addInitCallback(() -> {}, new Object());
+            fail("Expected exception when adding callback after init");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+    }
+
+    @Test
+    public void testDoubleInit_expectNoOp() {
+        ArrayList<Integer> results = new ArrayList<>();
+        mImpl.addInitCallback(() -> {
+            results.add(1);
+        }, new Object());
+        mImpl.init();
+        assertTrue(results.size() == 1);
+        mImpl.init();
+        assertTrue(results.size() == 1);
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
index 0b53c40..3dd0032 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
@@ -26,11 +26,13 @@
 import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN;
 import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_MULTI_WINDOW;
 import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_PIP;
+import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.mock;
@@ -46,6 +48,7 @@
 import android.os.RemoteException;
 import android.util.SparseArray;
 import android.view.SurfaceControl;
+import android.view.SurfaceSession;
 import android.window.ITaskOrganizer;
 import android.window.ITaskOrganizerController;
 import android.window.TaskAppearedInfo;
@@ -76,7 +79,7 @@
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public class ShellTaskOrganizerTests {
+public class ShellTaskOrganizerTests extends ShellTestCase {
 
     @Mock
     private ITaskOrganizerController mTaskOrganizerController;
@@ -137,13 +140,26 @@
     }
 
     @Test
-    public void registerOrganizer_sendRegisterTaskOrganizer() throws RemoteException {
+    public void testRegisterOrganizer_sendRegisterTaskOrganizer() throws RemoteException {
         mOrganizer.registerOrganizer();
 
         verify(mTaskOrganizerController).registerTaskOrganizer(any(ITaskOrganizer.class));
     }
 
     @Test
+    public void testTaskLeashReleasedAfterVanished() throws RemoteException {
+        assumeFalse(ENABLE_SHELL_TRANSITIONS);
+        RunningTaskInfo taskInfo = createTaskInfo(1, WINDOWING_MODE_MULTI_WINDOW);
+        SurfaceControl taskLeash = new SurfaceControl.Builder(new SurfaceSession())
+                .setName("task").build();
+        mOrganizer.registerOrganizer();
+        mOrganizer.onTaskAppeared(taskInfo, taskLeash);
+        assertTrue(taskLeash.isValid());
+        mOrganizer.onTaskVanished(taskInfo);
+        assertTrue(!taskLeash.isValid());
+    }
+
+    @Test
     public void testOneListenerPerType() {
         mOrganizer.addListenerForType(new TrackingTaskListener(), TASK_LISTENER_TYPE_MULTI_WINDOW);
         try {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTestCase.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTestCase.java
index 403dbf9..b5ee037 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTestCase.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTestCase.java
@@ -24,6 +24,8 @@
 
 import androidx.test.platform.app.InstrumentationRegistry;
 
+import com.android.internal.protolog.common.ProtoLog;
+
 import org.junit.After;
 import org.junit.Before;
 import org.mockito.MockitoAnnotations;
@@ -37,6 +39,9 @@
 
     @Before
     public void shellSetup() {
+        // Disable protolog tool when running the tests from studio
+        ProtoLog.REQUIRE_PROTOLOGTOOL = false;
+
         MockitoAnnotations.initMocks(this);
         final Context context =
                 InstrumentationRegistry.getInstrumentation().getTargetContext();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
index 51eec27..c0720cf 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
@@ -25,8 +25,10 @@
 
 import android.app.ActivityManager;
 import android.app.WindowConfiguration;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.IBinder;
+import android.view.Display;
 import android.window.IWindowContainerToken;
 import android.window.WindowContainerToken;
 
@@ -38,6 +40,10 @@
     private int mParentTaskId = INVALID_TASK_ID;
     private @WindowConfiguration.ActivityType int mActivityType = ACTIVITY_TYPE_STANDARD;
     private @WindowConfiguration.WindowingMode int mWindowingMode = WINDOWING_MODE_UNDEFINED;
+    private int mDisplayId = Display.DEFAULT_DISPLAY;
+    private ActivityManager.TaskDescription.Builder mTaskDescriptionBuilder = null;
+    private final Point mPositionInParent = new Point();
+    private boolean mIsVisible = false;
 
     public static WindowContainerToken createMockWCToken() {
         final IWindowContainerToken itoken = mock(IWindowContainerToken.class);
@@ -68,17 +74,42 @@
         return this;
     }
 
+    public TestRunningTaskInfoBuilder setDisplayId(int displayId) {
+        mDisplayId = displayId;
+        return this;
+    }
+
+    public TestRunningTaskInfoBuilder setTaskDescriptionBuilder(
+            ActivityManager.TaskDescription.Builder builder) {
+        mTaskDescriptionBuilder = builder;
+        return this;
+    }
+
+    public TestRunningTaskInfoBuilder setPositionInParent(int x, int y) {
+        mPositionInParent.set(x, y);
+        return this;
+    }
+
+    public TestRunningTaskInfoBuilder setVisible(boolean isVisible) {
+        mIsVisible = isVisible;
+        return this;
+    }
+
     public ActivityManager.RunningTaskInfo build() {
         final ActivityManager.RunningTaskInfo info = new ActivityManager.RunningTaskInfo();
-        info.parentTaskId = INVALID_TASK_ID;
         info.taskId = sNextTaskId++;
         info.parentTaskId = mParentTaskId;
+        info.displayId = mDisplayId;
         info.configuration.windowConfiguration.setBounds(mBounds);
         info.configuration.windowConfiguration.setActivityType(mActivityType);
         info.configuration.windowConfiguration.setWindowingMode(mWindowingMode);
         info.token = mToken;
         info.isResizeable = true;
         info.supportsMultiWindow = true;
+        info.taskDescription =
+                mTaskDescriptionBuilder != null ? mTaskDescriptionBuilder.build() : null;
+        info.positionInParent = mPositionInParent;
+        info.isVisible = mIsVisible;
         return info;
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
index e7c5cb2..31e55e7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
@@ -57,6 +57,7 @@
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.TestShellExecutor;
 
 import org.junit.Before;
@@ -74,7 +75,7 @@
 @TestableLooper.RunWithLooper
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
-public class BackAnimationControllerTest {
+public class BackAnimationControllerTest extends ShellTestCase {
 
     private static final String ANIMATION_ENABLED = "1";
     private final TestShellExecutor mShellExecutor = new TestShellExecutor();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblesTestActivity.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblesTestActivity.java
index d5fbe55..0537d0e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblesTestActivity.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblesTestActivity.java
@@ -20,7 +20,7 @@
 import android.content.Intent;
 import android.os.Bundle;
 
-import com.android.wm.shell.R;
+import com.android.wm.shell.tests.R;
 
 /**
  * Referenced by NotificationTestHelper#makeBubbleMetadata
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
index b888450..587782c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
@@ -39,6 +39,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.view.IInputMethodManager;
+import com.android.wm.shell.ShellTestCase;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -46,7 +47,7 @@
 import java.util.concurrent.Executor;
 
 @SmallTest
-public class DisplayImeControllerTest {
+public class DisplayImeControllerTest extends ShellTestCase {
 
     private SurfaceControl.Transaction mT;
     private DisplayImeController.PerDisplay mPerDisplay;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayInsetsControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayInsetsControllerTest.java
index 3bf06cc..4a7fd3d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayInsetsControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayInsetsControllerTest.java
@@ -24,6 +24,7 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
+import android.content.ComponentName;
 import android.os.RemoteException;
 import android.util.SparseArray;
 import android.view.IDisplayWindowInsetsController;
@@ -34,6 +35,7 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.TestShellExecutor;
 
 import org.junit.Before;
@@ -45,7 +47,7 @@
 import java.util.List;
 
 @SmallTest
-public class DisplayInsetsControllerTest {
+public class DisplayInsetsControllerTest extends ShellTestCase {
 
     private static final int SECOND_DISPLAY = DEFAULT_DISPLAY + 10;
 
@@ -164,7 +166,7 @@
         int hideInsetsCount = 0;
 
         @Override
-        public void topFocusedWindowChanged(String packageName,
+        public void topFocusedWindowChanged(ComponentName component,
                 InsetsVisibilities requestedVisibilities) {
             topFocusedWindowChangedCount++;
         }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayLayoutTest.java
index 0ffa5b3..514390f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayLayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayLayoutTest.java
@@ -41,6 +41,7 @@
 
 import com.android.internal.R;
 import com.android.internal.policy.SystemBarUtils;
+import com.android.wm.shell.ShellTestCase;
 
 import org.junit.After;
 import org.junit.Before;
@@ -54,7 +55,7 @@
  *  atest WMShellUnitTests:DisplayLayoutTest
  */
 @SmallTest
-public class DisplayLayoutTest {
+public class DisplayLayoutTest extends ShellTestCase {
     private MockitoSession mMockitoSession;
 
     @Before
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/TaskStackListenerImplTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/TaskStackListenerImplTest.java
index 96938eb..1347e06 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/TaskStackListenerImplTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/TaskStackListenerImplTest.java
@@ -35,6 +35,8 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.wm.shell.ShellTestCase;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -47,7 +49,7 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 @SmallTest
-public class TaskStackListenerImplTest {
+public class TaskStackListenerImplTest extends ShellTestCase {
 
     @Mock
     private IActivityTaskManager mActivityTaskManager;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
index f1e602f..95725bb 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
@@ -133,7 +133,7 @@
 
         mSplitLayout.snapToTarget(0 /* currentPosition */, snapTarget);
         waitDividerFlingFinished();
-        verify(mSplitLayoutHandler).onSnappedToDismiss(eq(false));
+        verify(mSplitLayoutHandler).onSnappedToDismiss(eq(false), anyInt());
     }
 
     @Test
@@ -145,7 +145,7 @@
 
         mSplitLayout.snapToTarget(0 /* currentPosition */, snapTarget);
         waitDividerFlingFinished();
-        verify(mSplitLayoutHandler).onSnappedToDismiss(eq(true));
+        verify(mSplitLayoutHandler).onSnappedToDismiss(eq(true), anyInt());
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
index 596100d..828c13e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
@@ -53,6 +53,7 @@
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.compatui.letterboxedu.LetterboxEduWindowManager;
+import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.transition.Transitions;
 
 import org.junit.Before;
@@ -78,6 +79,7 @@
     private static final int TASK_ID = 12;
 
     private CompatUIController mController;
+    private @Mock ShellController mMockShellController;
     private @Mock DisplayController mMockDisplayController;
     private @Mock DisplayInsetsController mMockDisplayInsetsController;
     private @Mock DisplayLayout mMockDisplayLayout;
@@ -105,7 +107,7 @@
         doReturn(TASK_ID).when(mMockLetterboxEduLayout).getTaskId();
         doReturn(true).when(mMockLetterboxEduLayout).createLayout(anyBoolean());
         doReturn(true).when(mMockLetterboxEduLayout).updateCompatInfo(any(), any(), anyBoolean());
-        mController = new CompatUIController(mContext, mMockDisplayController,
+        mController = new CompatUIController(mContext, mMockShellController, mMockDisplayController,
                 mMockDisplayInsetsController, mMockImeController, mMockSyncQueue, mMockExecutor,
                 mMockTransitionsLazy) {
             @Override
@@ -124,6 +126,11 @@
     }
 
     @Test
+    public void instantiateController_registerKeyguardChangeListener() {
+        verify(mMockShellController, times(1)).addKeyguardChangeListener(any());
+    }
+
+    @Test
     public void testListenerRegistered() {
         verify(mMockDisplayController).addDisplayWindowListener(mController);
         verify(mMockImeController).addPositionProcessor(mController);
@@ -324,7 +331,7 @@
                 /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
 
         // Verify that the restart button is hidden after keyguard becomes showing.
-        mController.onKeyguardShowingChanged(true);
+        mController.onKeyguardVisibilityChanged(true, false, false);
 
         verify(mMockCompatLayout).updateVisibility(false);
         verify(mMockLetterboxEduLayout).updateVisibility(false);
@@ -340,7 +347,7 @@
                 false);
 
         // Verify button is shown after keyguard becomes not showing.
-        mController.onKeyguardShowingChanged(false);
+        mController.onKeyguardVisibilityChanged(false, false, false);
 
         verify(mMockCompatLayout).updateVisibility(true);
         verify(mMockLetterboxEduLayout).updateVisibility(true);
@@ -352,7 +359,7 @@
                 /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
 
         mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ true);
-        mController.onKeyguardShowingChanged(true);
+        mController.onKeyguardVisibilityChanged(true, false, false);
 
         verify(mMockCompatLayout, times(2)).updateVisibility(false);
         verify(mMockLetterboxEduLayout, times(2)).updateVisibility(false);
@@ -360,7 +367,7 @@
         clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout);
 
         // Verify button remains hidden after keyguard becomes not showing since IME is showing.
-        mController.onKeyguardShowingChanged(false);
+        mController.onKeyguardVisibilityChanged(false, false, false);
 
         verify(mMockCompatLayout).updateVisibility(false);
         verify(mMockLetterboxEduLayout).updateVisibility(false);
@@ -378,7 +385,7 @@
                 /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
 
         mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ true);
-        mController.onKeyguardShowingChanged(true);
+        mController.onKeyguardVisibilityChanged(true, false, false);
 
         verify(mMockCompatLayout, times(2)).updateVisibility(false);
         verify(mMockLetterboxEduLayout, times(2)).updateVisibility(false);
@@ -392,7 +399,7 @@
         verify(mMockLetterboxEduLayout).updateVisibility(false);
 
         // Verify button is shown after keyguard becomes not showing.
-        mController.onKeyguardShowingChanged(false);
+        mController.onKeyguardVisibilityChanged(false, false, false);
 
         verify(mMockCompatLayout).updateVisibility(true);
         verify(mMockLetterboxEduLayout).updateVisibility(true);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropControllerTest.java
index aaeebef..e20997199 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropControllerTest.java
@@ -21,6 +21,7 @@
 import static android.view.DragEvent.ACTION_DRAG_STARTED;
 
 import static org.junit.Assert.assertFalse;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -44,9 +45,11 @@
 
 import com.android.internal.logging.UiEventLogger;
 import com.android.launcher3.icons.IconProvider;
+import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.splitscreen.SplitScreenController;
+import com.android.wm.shell.sysui.ShellController;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -61,28 +64,38 @@
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public class DragAndDropControllerTest {
+public class DragAndDropControllerTest extends ShellTestCase {
 
     @Mock
     private Context mContext;
-
+    @Mock
+    private ShellController mShellController;
     @Mock
     private DisplayController mDisplayController;
-
     @Mock
     private UiEventLogger mUiEventLogger;
-
     @Mock
     private DragAndDropController.DragAndDropListener mDragAndDropListener;
+    @Mock
+    private IconProvider mIconProvider;
+    @Mock
+    private ShellExecutor mMainExecutor;
+    @Mock
+    private SplitScreenController mSplitScreenController;
 
     private DragAndDropController mController;
 
     @Before
     public void setUp() throws RemoteException {
         MockitoAnnotations.initMocks(this);
-        mController = new DragAndDropController(mContext, mDisplayController, mUiEventLogger,
-                mock(IconProvider.class), mock(ShellExecutor.class));
-        mController.initialize(Optional.of(mock(SplitScreenController.class)));
+        mController = new DragAndDropController(mContext, mShellController, mDisplayController,
+                mUiEventLogger, mIconProvider, mMainExecutor);
+        mController.initialize(Optional.of(mSplitScreenController));
+    }
+
+    @Test
+    public void instantiateController_registerConfigChangeListener() {
+        verify(mShellController, times(1)).addConfigurationChangeListener(any());
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
index 7e6595f..9e988e8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
@@ -34,7 +34,6 @@
 import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_RIGHT;
 import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_TOP;
 
-import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
 import static junit.framework.Assert.fail;
 
@@ -57,7 +56,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
-import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Insets;
@@ -68,6 +66,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.InstanceId;
+import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.draganddrop.DragAndDropPolicy.Target;
 import com.android.wm.shell.splitscreen.SplitScreenController;
@@ -87,7 +86,7 @@
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public class DragAndDropPolicyTest {
+public class DragAndDropPolicyTest extends ShellTestCase {
 
     @Mock
     private Context mContext;
@@ -265,62 +264,6 @@
         }
     }
 
-    @Test
-    public void testLaunchMultipleTask_differentActivity() {
-        setRunningTask(mFullscreenAppTask);
-        mPolicy.start(mLandscapeDisplayLayout, mActivityClipData, mLoggerSessionId);
-        Intent fillInIntent = mPolicy.getStartIntentFillInIntent(mock(PendingIntent.class), 0);
-        assertNull(fillInIntent);
-    }
-
-    @Test
-    public void testLaunchMultipleTask_differentActivity_inSplitscreen() {
-        setRunningTask(mFullscreenAppTask);
-        doReturn(true).when(mSplitScreenStarter).isSplitScreenVisible();
-        doReturn(mFullscreenAppTask).when(mSplitScreenStarter).getTaskInfo(anyInt());
-        mPolicy.start(mLandscapeDisplayLayout, mActivityClipData, mLoggerSessionId);
-        Intent fillInIntent = mPolicy.getStartIntentFillInIntent(mock(PendingIntent.class), 0);
-        assertNull(fillInIntent);
-    }
-
-    @Test
-    public void testLaunchMultipleTask_sameActivity() {
-        setRunningTask(mFullscreenAppTask);
-
-        // Replace the mocked drag pending intent and ensure it resolves to the same activity
-        PendingIntent launchIntent = mock(PendingIntent.class);
-        ResolveInfo launchInfo = new ResolveInfo();
-        launchInfo.activityInfo = mFullscreenAppTask.topActivityInfo;
-        doReturn(Collections.singletonList(launchInfo))
-                .when(launchIntent).queryIntentComponents(anyInt());
-        mActivityClipData.getItemAt(0).getIntent().putExtra(ClipDescription.EXTRA_PENDING_INTENT,
-                launchIntent);
-
-        mPolicy.start(mLandscapeDisplayLayout, mActivityClipData, mLoggerSessionId);
-        Intent fillInIntent = mPolicy.getStartIntentFillInIntent(launchIntent, 0);
-        assertTrue((fillInIntent.getFlags() & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) != 0);
-    }
-
-    @Test
-    public void testLaunchMultipleTask_sameActivity_inSplitScreen() {
-        setRunningTask(mFullscreenAppTask);
-
-        // Replace the mocked drag pending intent and ensure it resolves to the same activity
-        PendingIntent launchIntent = mock(PendingIntent.class);
-        ResolveInfo launchInfo = new ResolveInfo();
-        launchInfo.activityInfo = mFullscreenAppTask.topActivityInfo;
-        doReturn(Collections.singletonList(launchInfo))
-                .when(launchIntent).queryIntentComponents(anyInt());
-        mActivityClipData.getItemAt(0).getIntent().putExtra(ClipDescription.EXTRA_PENDING_INTENT,
-                launchIntent);
-
-        doReturn(true).when(mSplitScreenStarter).isSplitScreenVisible();
-        doReturn(mFullscreenAppTask).when(mSplitScreenStarter).getTaskInfo(anyInt());
-        mPolicy.start(mLandscapeDisplayLayout, mActivityClipData, mLoggerSessionId);
-        Intent fillInIntent = mPolicy.getStartIntentFillInIntent(launchIntent, 0);
-        assertTrue((fillInIntent.getFlags() & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) != 0);
-    }
-
     private Target filterTargetByType(ArrayList<Target> targets, int type) {
         for (Target t : targets) {
             if (type == t.type) {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutControllerTest.java
index b976c12..dcc504a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutControllerTest.java
@@ -16,10 +16,11 @@
 
 package com.android.wm.shell.hidedisplaycutout;
 
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-import android.platform.test.annotations.Presubmit;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableContext;
 import android.testing.TestableLooper;
@@ -27,7 +28,8 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
-import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.sysui.ShellController;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -35,25 +37,30 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-@Presubmit
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
-public class HideDisplayCutoutControllerTest {
+public class HideDisplayCutoutControllerTest extends ShellTestCase {
     private TestableContext mContext = new TestableContext(
             InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
 
-    private HideDisplayCutoutController mHideDisplayCutoutController;
+    @Mock
+    private ShellController mShellController;
     @Mock
     private HideDisplayCutoutOrganizer mMockDisplayAreaOrganizer;
-    @Mock
-    private ShellExecutor mMockMainExecutor;
+
+    private HideDisplayCutoutController mHideDisplayCutoutController;
 
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         mHideDisplayCutoutController = new HideDisplayCutoutController(
-                mContext, mMockDisplayAreaOrganizer, mMockMainExecutor);
+                mContext, mShellController, mMockDisplayAreaOrganizer);
+    }
+
+    @Test
+    public void instantiateController_registerConfigChangeListener() {
+        verify(mShellController, times(1)).addConfigurationChangeListener(any());
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizerTest.java
index 16e9239..49521cf 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizerTest.java
@@ -32,7 +32,6 @@
 import android.graphics.Insets;
 import android.graphics.Rect;
 import android.os.Binder;
-import android.platform.test.annotations.Presubmit;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableContext;
 import android.testing.TestableLooper;
@@ -48,6 +47,7 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
+import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.ShellExecutor;
@@ -61,11 +61,10 @@
 
 import java.util.ArrayList;
 
-@Presubmit
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
-public class HideDisplayCutoutOrganizerTest {
+public class HideDisplayCutoutOrganizerTest extends ShellTestCase {
     private TestableContext mContext = new TestableContext(
             InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java
index 1eadeed..184a8df 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java
@@ -44,6 +44,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayInsetsController;
 import com.android.wm.shell.common.ShellExecutor;
@@ -61,7 +62,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public class KidsModeTaskOrganizerTest {
+public class KidsModeTaskOrganizerTest extends ShellTestCase {
     @Mock private ITaskOrganizerController mTaskOrganizerController;
     @Mock private Context mContext;
     @Mock private Handler mHandler;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java
index 8a2bbd7..dbf93ae 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java
@@ -30,6 +30,7 @@
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -48,6 +49,7 @@
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.TaskStackListenerImpl;
+import com.android.wm.shell.sysui.ShellController;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -68,6 +70,8 @@
     OneHandedState mSpiedTransitionState;
 
     @Mock
+    ShellController mMockShellController;
+    @Mock
     DisplayLayout mDisplayLayout;
     @Mock
     DisplayController mMockDisplayController;
@@ -123,6 +127,7 @@
         mOneHandedAccessibilityUtil = new OneHandedAccessibilityUtil(mContext);
         mSpiedOneHandedController = spy(new OneHandedController(
                 mContext,
+                mMockShellController,
                 mMockDisplayController,
                 mMockDisplayAreaOrganizer,
                 mMockTouchHandler,
@@ -139,6 +144,16 @@
     }
 
     @Test
+    public void testControllerRegistersConfigChangeListener() {
+        verify(mMockShellController, times(1)).addConfigurationChangeListener(any());
+    }
+
+    @Test
+    public void testControllerRegistersKeyguardChangeListener() {
+        verify(mMockShellController, times(1)).addKeyguardChangeListener(any());
+    }
+
+    @Test
     public void testDefaultShouldNotInOneHanded() {
         // Assert default transition state is STATE_NONE
         assertThat(mSpiedTransitionState.getState()).isEqualTo(STATE_NONE);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java
index 7ee7536..e6a8220 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java
@@ -31,7 +31,6 @@
 
 import android.graphics.Rect;
 import android.os.Handler;
-import android.os.UserHandle;
 import android.testing.AndroidTestingRunner;
 import android.util.ArrayMap;
 import android.view.Display;
@@ -42,6 +41,7 @@
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.TaskStackListenerImpl;
+import com.android.wm.shell.sysui.ShellController;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -52,7 +52,6 @@
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 public class OneHandedStateTest extends OneHandedTestCase {
-    private int mCurrentUser = UserHandle.myUserId();
 
     Display mDisplay;
     DisplayLayout mDisplayLayout;
@@ -62,6 +61,8 @@
     OneHandedState mSpiedState;
 
     @Mock
+    ShellController mMockShellController;
+    @Mock
     DisplayController mMockDisplayController;
     @Mock
     OneHandedDisplayAreaOrganizer mMockDisplayAreaOrganizer;
@@ -110,6 +111,7 @@
         mOneHandedAccessibilityUtil = new OneHandedAccessibilityUtil(mContext);
         mSpiedOneHandedController = spy(new OneHandedController(
                 mContext,
+                mMockShellController,
                 mMockDisplayController,
                 mMockDisplayAreaOrganizer,
                 mMockTouchHandler,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTestCase.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTestCase.java
index 8b03dc5..808ab21 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTestCase.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTestCase.java
@@ -30,6 +30,8 @@
 
 import androidx.test.platform.app.InstrumentationRegistry;
 
+import com.android.wm.shell.ShellTestCase;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.mockito.Answers;
@@ -38,7 +40,7 @@
 /**
  * Base class that does One Handed specific setup.
  */
-public abstract class OneHandedTestCase {
+public abstract class OneHandedTestCase extends ShellTestCase {
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     protected Context mContext;
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
index c685fdc..52d78ca 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
@@ -21,6 +21,7 @@
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
 
+import static com.android.wm.shell.MockSurfaceControlHelper.createMockSurfaceControlTransaction;
 import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_LEAVE_PIP;
 import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP;
 
@@ -37,6 +38,7 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.wm.shell.MockSurfaceControlHelper;
 import com.android.wm.shell.ShellTestCase;
 
 import org.junit.Before;
@@ -103,7 +105,8 @@
         final PipAnimationController.PipTransitionAnimator oldAnimator = mPipAnimationController
                 .getAnimator(mTaskInfo, mLeash, baseValue, startValue, endValue1, null,
                         TRANSITION_DIRECTION_TO_PIP, 0, ROTATION_0);
-        oldAnimator.setSurfaceControlTransactionFactory(PipDummySurfaceControlTx::new);
+        oldAnimator.setSurfaceControlTransactionFactory(
+                MockSurfaceControlHelper::createMockSurfaceControlTransaction);
         oldAnimator.start();
 
         final PipAnimationController.PipTransitionAnimator newAnimator = mPipAnimationController
@@ -133,7 +136,7 @@
 
     @Test
     public void pipTransitionAnimator_rotatedEndValue() {
-        final PipDummySurfaceControlTx tx = new PipDummySurfaceControlTx();
+        final SurfaceControl.Transaction tx = createMockSurfaceControlTransaction();
         final Rect startBounds = new Rect(200, 700, 400, 800);
         final Rect endBounds = new Rect(0, 0, 500, 1000);
         // Fullscreen to PiP.
@@ -183,7 +186,8 @@
         final PipAnimationController.PipTransitionAnimator animator = mPipAnimationController
                 .getAnimator(mTaskInfo, mLeash, baseValue, startValue, endValue, null,
                         TRANSITION_DIRECTION_TO_PIP, 0, ROTATION_0);
-        animator.setSurfaceControlTransactionFactory(PipDummySurfaceControlTx::new);
+        animator.setSurfaceControlTransactionFactory(
+                MockSurfaceControlHelper::createMockSurfaceControlTransaction);
 
         animator.setPipAnimationCallback(mPipAnimationCallback);
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipDummySurfaceControlTx.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipDummySurfaceControlTx.java
deleted file mode 100644
index ccf8f6e..0000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipDummySurfaceControlTx.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.pip;
-
-import android.graphics.Matrix;
-import android.view.SurfaceControl;
-
-/**
- * A dummy {@link SurfaceControl.Transaction} class for testing purpose and supports
- * method chaining.
- */
-public class PipDummySurfaceControlTx extends SurfaceControl.Transaction {
-    @Override
-    public SurfaceControl.Transaction setAlpha(SurfaceControl leash, float alpha) {
-        return this;
-    }
-
-    @Override
-    public SurfaceControl.Transaction setPosition(SurfaceControl leash, float x, float y) {
-        return this;
-    }
-
-    @Override
-    public SurfaceControl.Transaction setWindowCrop(SurfaceControl leash, int w, int h) {
-        return this;
-    }
-
-    @Override
-    public SurfaceControl.Transaction setCornerRadius(SurfaceControl leash, float radius) {
-        return this;
-    }
-
-    @Override
-    public SurfaceControl.Transaction setShadowRadius(SurfaceControl leash, float radius) {
-        return this;
-    }
-
-    @Override
-    public SurfaceControl.Transaction setMatrix(SurfaceControl leash, Matrix matrix,
-            float[] float9) {
-        return this;
-    }
-
-    @Override
-    public SurfaceControl.Transaction setFrameTimelineVsync(long frameTimelineVsyncId) {
-        return this;
-    }
-
-    @Override
-    public void apply() {}
-}
-
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
index e8e6254..b351f8f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
@@ -44,6 +44,7 @@
 import android.view.DisplayInfo;
 import android.window.WindowContainerToken;
 
+import com.android.wm.shell.MockSurfaceControlHelper;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.TestShellExecutor;
@@ -246,7 +247,8 @@
         mPipBoundsState.setDisplayLayout(new DisplayLayout(info,
                 mContext.getResources(), true, true));
         mSpiedPipTaskOrganizer.setOneShotAnimationType(PipAnimationController.ANIM_TYPE_ALPHA);
-        mSpiedPipTaskOrganizer.setSurfaceControlTransactionFactory(PipDummySurfaceControlTx::new);
+        mSpiedPipTaskOrganizer.setSurfaceControlTransactionFactory(
+                MockSurfaceControlHelper::createMockSurfaceControlTransaction);
         doNothing().when(mSpiedPipTaskOrganizer).enterPipWithAlphaAnimation(any(), anyLong());
         doNothing().when(mSpiedPipTaskOrganizer).scheduleAnimateResizePip(any(), anyInt(), any());
     }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
index babc970..f192514 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
@@ -24,6 +24,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -54,6 +55,7 @@
 import com.android.wm.shell.pip.PipTaskOrganizer;
 import com.android.wm.shell.pip.PipTransitionController;
 import com.android.wm.shell.pip.PipTransitionState;
+import com.android.wm.shell.sysui.ShellController;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -73,6 +75,7 @@
 public class PipControllerTest extends ShellTestCase {
     private PipController mPipController;
 
+    @Mock private ShellController mMockShellController;
     @Mock private DisplayController mMockDisplayController;
     @Mock private PhonePipMenuController mMockPhonePipMenuController;
     @Mock private PipAppOpsListener mMockPipAppOpsListener;
@@ -102,7 +105,7 @@
             ((Runnable) invocation.getArgument(0)).run();
             return null;
         }).when(mMockExecutor).execute(any());
-        mPipController = new PipController(mContext, mMockDisplayController,
+        mPipController = new PipController(mContext, mMockShellController, mMockDisplayController,
                 mMockPipAppOpsListener, mMockPipBoundsAlgorithm,
                 mMockPipKeepClearAlgorithm,
                 mMockPipBoundsState, mMockPipMotionHelper, mMockPipMediaController,
@@ -115,6 +118,16 @@
     }
 
     @Test
+    public void instantiatePipController_registerConfigChangeListener() {
+        verify(mMockShellController, times(1)).addConfigurationChangeListener(any());
+    }
+
+    @Test
+    public void instantiatePipController_registerKeyguardChangeListener() {
+        verify(mMockShellController, times(1)).addKeyguardChangeListener(any());
+    }
+
+    @Test
     public void instantiatePipController_registersPipTransitionCallback() {
         verify(mMockPipTransitionController).registerPipTransitionCallback(any());
     }
@@ -136,7 +149,7 @@
         when(mockPackageManager.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)).thenReturn(false);
         when(spyContext.getPackageManager()).thenReturn(mockPackageManager);
 
-        assertNull(PipController.create(spyContext, mMockDisplayController,
+        assertNull(PipController.create(spyContext, mMockShellController, mMockDisplayController,
                 mMockPipAppOpsListener, mMockPipBoundsAlgorithm,
                 mMockPipKeepClearAlgorithm,
                 mMockPipBoundsState, mMockPipMotionHelper, mMockPipMediaController,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/SplitBoundsTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/SplitBoundsTest.java
index 068a60a..50d02ae 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/SplitBoundsTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/SplitBoundsTest.java
@@ -9,6 +9,7 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.util.SplitBounds;
 
 import org.junit.Before;
@@ -17,7 +18,7 @@
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
-public class SplitBoundsTest {
+public class SplitBoundsTest extends ShellTestCase {
     private static final int DEVICE_WIDTH = 100;
     private static final int DEVICE_LENGTH = 200;
     private static final int DIVIDER_SIZE = 20;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
new file mode 100644
index 0000000..c7a261f
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.splitscreen;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+
+import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.launcher3.icons.IconProvider;
+import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.DisplayInsetsController;
+import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.recents.RecentTasksController;
+import com.android.wm.shell.sysui.ShellController;
+import com.android.wm.shell.transition.Transitions;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Optional;
+
+/**
+ * Tests for {@link SplitScreenController}
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SplitScreenControllerTests extends ShellTestCase {
+
+    @Mock ShellController mShellController;
+    @Mock ShellTaskOrganizer mTaskOrganizer;
+    @Mock SyncTransactionQueue mSyncQueue;
+    @Mock RootTaskDisplayAreaOrganizer mRootTDAOrganizer;
+    @Mock ShellExecutor mMainExecutor;
+    @Mock DisplayController mDisplayController;
+    @Mock DisplayImeController mDisplayImeController;
+    @Mock DisplayInsetsController mDisplayInsetsController;
+    @Mock Transitions mTransitions;
+    @Mock TransactionPool mTransactionPool;
+    @Mock IconProvider mIconProvider;
+    @Mock Optional<RecentTasksController> mRecentTasks;
+
+    private SplitScreenController mSplitScreenController;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mSplitScreenController = spy(new SplitScreenController(mShellController, mTaskOrganizer,
+                mSyncQueue, mContext, mRootTDAOrganizer, mMainExecutor, mDisplayController,
+                mDisplayImeController, mDisplayInsetsController, mTransitions, mTransactionPool,
+                mIconProvider, mRecentTasks));
+    }
+
+    @Test
+    public void testControllerRegistersKeyguardChangeListener() {
+        when(mDisplayController.getDisplayLayout(anyInt())).thenReturn(new DisplayLayout());
+        mSplitScreenController.onOrganizerRegistered();
+        verify(mShellController, times(1)).addKeyguardChangeListener(any());
+    }
+
+    @Test
+    public void testIsLaunchingAdjacently_notInSplitScreen() {
+        doReturn(false).when(mSplitScreenController).isSplitScreenVisible();
+        doReturn(true).when(mSplitScreenController).isValidToEnterSplitScreen(any());
+
+        // Verify launching the same activity returns true.
+        Intent startIntent = createStartIntent("startActivity");
+        ActivityManager.RunningTaskInfo focusTaskInfo =
+                createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, startIntent);
+        doReturn(focusTaskInfo).when(mSplitScreenController).getFocusingTaskInfo();
+        assertTrue(mSplitScreenController.isLaunchingAdjacently(
+                startIntent, SPLIT_POSITION_TOP_OR_LEFT));
+
+        // Verify launching different activity returns false.
+        Intent diffIntent = createStartIntent("diffActivity");
+        focusTaskInfo =
+                createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, diffIntent);
+        doReturn(focusTaskInfo).when(mSplitScreenController).getFocusingTaskInfo();
+        assertFalse(mSplitScreenController.isLaunchingAdjacently(
+                startIntent, SPLIT_POSITION_TOP_OR_LEFT));
+    }
+
+    @Test
+    public void testIsLaunchingAdjacently_inSplitScreen() {
+        doReturn(true).when(mSplitScreenController).isSplitScreenVisible();
+
+        // Verify launching the same activity returns true.
+        Intent startIntent = createStartIntent("startActivity");
+        ActivityManager.RunningTaskInfo pairingTaskInfo =
+                createTaskInfo(WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD, startIntent);
+        doReturn(pairingTaskInfo).when(mSplitScreenController).getTaskInfo(anyInt());
+        assertTrue(mSplitScreenController.isLaunchingAdjacently(
+                startIntent, SPLIT_POSITION_TOP_OR_LEFT));
+
+        // Verify launching different activity returns false.
+        Intent diffIntent = createStartIntent("diffActivity");
+        pairingTaskInfo =
+                createTaskInfo(WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD, diffIntent);
+        doReturn(pairingTaskInfo).when(mSplitScreenController).getTaskInfo(anyInt());
+        assertFalse(mSplitScreenController.isLaunchingAdjacently(
+                startIntent, SPLIT_POSITION_TOP_OR_LEFT));
+    }
+
+    private Intent createStartIntent(String activityName) {
+        Intent intent = new Intent();
+        intent.setComponent(new ComponentName(mContext, activityName));
+        return intent;
+    }
+
+    private ActivityManager.RunningTaskInfo createTaskInfo(int winMode, int actType,
+            Intent strIntent) {
+        ActivityManager.RunningTaskInfo info = new ActivityManager.RunningTaskInfo();
+        info.configuration.windowConfiguration.setActivityType(actType);
+        info.configuration.windowConfiguration.setWindowingMode(winMode);
+        info.supportsMultiWindow = true;
+        info.baseIntent = strIntent;
+        info.baseActivity = strIntent.getComponent();
+        ActivityInfo activityInfo = new ActivityInfo();
+        activityInfo.packageName = info.baseActivity.getPackageName();
+        activityInfo.name = info.baseActivity.getClassName();
+        info.topActivityInfo = activityInfo;
+        return info;
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
index af2c495..4b68870 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
@@ -127,6 +127,9 @@
         mRootTask = new TestRunningTaskInfoBuilder().build();
         mRootLeash = new SurfaceControl.Builder(mSurfaceSession).setName("test").build();
         mStageCoordinator.onTaskAppeared(mRootTask, mRootLeash);
+
+        mSideStage.mRootTaskInfo = new TestRunningTaskInfoBuilder().build();
+        mMainStage.mRootTaskInfo = new TestRunningTaskInfoBuilder().build();
     }
 
     @Test
@@ -224,8 +227,8 @@
         mStageCoordinator.exitSplitScreen(testTaskId, EXIT_REASON_RETURN_HOME);
         verify(mMainStage).reorderChild(eq(testTaskId), eq(true),
                 any(WindowContainerTransaction.class));
-        verify(mSideStage).removeAllTasks(any(WindowContainerTransaction.class), eq(false));
-        verify(mMainStage).deactivate(any(WindowContainerTransaction.class), eq(true));
+        verify(mSideStage).dismiss(any(WindowContainerTransaction.class), eq(false));
+        verify(mMainStage).resetBounds(any(WindowContainerTransaction.class));
     }
 
     @Test
@@ -237,8 +240,8 @@
         mStageCoordinator.exitSplitScreen(testTaskId, EXIT_REASON_RETURN_HOME);
         verify(mSideStage).reorderChild(eq(testTaskId), eq(true),
                 any(WindowContainerTransaction.class));
-        verify(mSideStage).removeAllTasks(any(WindowContainerTransaction.class), eq(true));
-        verify(mMainStage).deactivate(any(WindowContainerTransaction.class), eq(false));
+        verify(mSideStage).resetBounds(any(WindowContainerTransaction.class));
+        verify(mMainStage).dismiss(any(WindowContainerTransaction.class), eq(false));
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
index 14d8ce4..46b040f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
@@ -73,6 +73,7 @@
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.launcher3.icons.IconProvider;
+import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.HandlerExecutor;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.TransactionPool;
@@ -91,7 +92,7 @@
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public class StartingSurfaceDrawerTests {
+public class StartingSurfaceDrawerTests extends ShellTestCase {
     @Mock
     private IBinder mBinder;
     @Mock
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/TaskSnapshotWindowTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/TaskSnapshotWindowTest.java
index 78e27c9..3de50bb 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/TaskSnapshotWindowTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/TaskSnapshotWindowTest.java
@@ -47,6 +47,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.TestShellExecutor;
 
 import org.junit.Test;
@@ -58,7 +59,7 @@
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public class TaskSnapshotWindowTest {
+public class TaskSnapshotWindowTest extends ShellTestCase {
 
     private TaskSnapshotWindow mWindow;
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/sysui/ShellControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/sysui/ShellControllerTest.java
new file mode 100644
index 0000000..1c0e46f
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/sysui/ShellControllerTest.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.sysui;
+
+import static org.junit.Assert.assertTrue;
+
+import android.content.res.Configuration;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.common.ShellExecutor;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Locale;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+public class ShellControllerTest extends ShellTestCase {
+
+    @Mock
+    private ShellExecutor mExecutor;
+
+    private ShellController mController;
+    private TestConfigurationChangeListener mConfigChangeListener;
+    private TestKeyguardChangeListener mKeyguardChangeListener;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mKeyguardChangeListener = new TestKeyguardChangeListener();
+        mConfigChangeListener = new TestConfigurationChangeListener();
+        mController = new ShellController(mExecutor);
+        mController.onConfigurationChanged(getConfigurationCopy());
+    }
+
+    @After
+    public void tearDown() {
+        // Do nothing
+    }
+
+    @Test
+    public void testAddKeyguardChangeListener_ensureCallback() {
+        mController.addKeyguardChangeListener(mKeyguardChangeListener);
+
+        mController.onKeyguardVisibilityChanged(true, false, false);
+        assertTrue(mKeyguardChangeListener.visibilityChanged == 1);
+        assertTrue(mKeyguardChangeListener.dismissAnimationFinished == 0);
+    }
+
+    @Test
+    public void testDoubleAddKeyguardChangeListener_ensureSingleCallback() {
+        mController.addKeyguardChangeListener(mKeyguardChangeListener);
+        mController.addKeyguardChangeListener(mKeyguardChangeListener);
+
+        mController.onKeyguardVisibilityChanged(true, false, false);
+        assertTrue(mKeyguardChangeListener.visibilityChanged == 1);
+        assertTrue(mKeyguardChangeListener.dismissAnimationFinished == 0);
+    }
+
+    @Test
+    public void testAddRemoveKeyguardChangeListener_ensureNoCallback() {
+        mController.addKeyguardChangeListener(mKeyguardChangeListener);
+        mController.removeKeyguardChangeListener(mKeyguardChangeListener);
+
+        mController.onKeyguardVisibilityChanged(true, false, false);
+        assertTrue(mKeyguardChangeListener.visibilityChanged == 0);
+        assertTrue(mKeyguardChangeListener.dismissAnimationFinished == 0);
+    }
+
+    @Test
+    public void testKeyguardVisibilityChanged() {
+        mController.addKeyguardChangeListener(mKeyguardChangeListener);
+
+        mController.onKeyguardVisibilityChanged(true, true, true);
+        assertTrue(mKeyguardChangeListener.visibilityChanged == 1);
+        assertTrue(mKeyguardChangeListener.lastAnimatingDismiss);
+        assertTrue(mKeyguardChangeListener.lastOccluded);
+        assertTrue(mKeyguardChangeListener.lastAnimatingDismiss);
+        assertTrue(mKeyguardChangeListener.dismissAnimationFinished == 0);
+    }
+
+    @Test
+    public void testKeyguardDismissAnimationFinished() {
+        mController.addKeyguardChangeListener(mKeyguardChangeListener);
+
+        mController.onKeyguardDismissAnimationFinished();
+        assertTrue(mKeyguardChangeListener.visibilityChanged == 0);
+        assertTrue(mKeyguardChangeListener.dismissAnimationFinished == 1);
+    }
+
+    @Test
+    public void testAddConfigurationChangeListener_ensureCallback() {
+        mController.addConfigurationChangeListener(mConfigChangeListener);
+
+        Configuration newConfig = getConfigurationCopy();
+        newConfig.densityDpi = 200;
+        mController.onConfigurationChanged(newConfig);
+        assertTrue(mConfigChangeListener.configChanges == 1);
+    }
+
+    @Test
+    public void testDoubleAddConfigurationChangeListener_ensureSingleCallback() {
+        mController.addConfigurationChangeListener(mConfigChangeListener);
+        mController.addConfigurationChangeListener(mConfigChangeListener);
+
+        Configuration newConfig = getConfigurationCopy();
+        newConfig.densityDpi = 200;
+        mController.onConfigurationChanged(newConfig);
+        assertTrue(mConfigChangeListener.configChanges == 1);
+    }
+
+    @Test
+    public void testAddRemoveConfigurationChangeListener_ensureNoCallback() {
+        mController.addConfigurationChangeListener(mConfigChangeListener);
+        mController.removeConfigurationChangeListener(mConfigChangeListener);
+
+        Configuration newConfig = getConfigurationCopy();
+        newConfig.densityDpi = 200;
+        mController.onConfigurationChanged(newConfig);
+        assertTrue(mConfigChangeListener.configChanges == 0);
+    }
+
+    @Test
+    public void testMultipleConfigurationChangeListeners() {
+        TestConfigurationChangeListener listener2 = new TestConfigurationChangeListener();
+        mController.addConfigurationChangeListener(mConfigChangeListener);
+        mController.addConfigurationChangeListener(listener2);
+
+        Configuration newConfig = getConfigurationCopy();
+        newConfig.densityDpi = 200;
+        mController.onConfigurationChanged(newConfig);
+        assertTrue(mConfigChangeListener.configChanges == 1);
+        assertTrue(listener2.configChanges == 1);
+    }
+
+    @Test
+    public void testRemoveListenerDuringCallback() {
+        TestConfigurationChangeListener badListener = new TestConfigurationChangeListener() {
+            @Override
+            public void onConfigurationChanged(Configuration newConfiguration) {
+                mController.removeConfigurationChangeListener(this);
+            }
+        };
+        mController.addConfigurationChangeListener(badListener);
+        mController.addConfigurationChangeListener(mConfigChangeListener);
+
+        // Ensure we don't fail just because a listener was removed mid-callback
+        Configuration newConfig = getConfigurationCopy();
+        newConfig.densityDpi = 200;
+        mController.onConfigurationChanged(newConfig);
+    }
+
+    @Test
+    public void testDensityChangeCallback() {
+        mController.addConfigurationChangeListener(mConfigChangeListener);
+
+        Configuration newConfig = getConfigurationCopy();
+        newConfig.densityDpi = 200;
+        mController.onConfigurationChanged(newConfig);
+        assertTrue(mConfigChangeListener.configChanges == 1);
+        assertTrue(mConfigChangeListener.densityChanges == 1);
+        assertTrue(mConfigChangeListener.smallestWidthChanges == 0);
+        assertTrue(mConfigChangeListener.themeChanges == 0);
+        assertTrue(mConfigChangeListener.localeChanges == 0);
+    }
+
+    @Test
+    public void testFontScaleChangeCallback() {
+        mController.addConfigurationChangeListener(mConfigChangeListener);
+
+        Configuration newConfig = getConfigurationCopy();
+        newConfig.fontScale = 2;
+        mController.onConfigurationChanged(newConfig);
+        assertTrue(mConfigChangeListener.configChanges == 1);
+        assertTrue(mConfigChangeListener.densityChanges == 1);
+        assertTrue(mConfigChangeListener.smallestWidthChanges == 0);
+        assertTrue(mConfigChangeListener.themeChanges == 0);
+        assertTrue(mConfigChangeListener.localeChanges == 0);
+    }
+
+    @Test
+    public void testSmallestWidthChangeCallback() {
+        mController.addConfigurationChangeListener(mConfigChangeListener);
+
+        Configuration newConfig = getConfigurationCopy();
+        newConfig.smallestScreenWidthDp = 100;
+        mController.onConfigurationChanged(newConfig);
+        assertTrue(mConfigChangeListener.configChanges == 1);
+        assertTrue(mConfigChangeListener.densityChanges == 0);
+        assertTrue(mConfigChangeListener.smallestWidthChanges == 1);
+        assertTrue(mConfigChangeListener.themeChanges == 0);
+        assertTrue(mConfigChangeListener.localeChanges == 0);
+    }
+
+    @Test
+    public void testThemeChangeCallback() {
+        mController.addConfigurationChangeListener(mConfigChangeListener);
+
+        Configuration newConfig = getConfigurationCopy();
+        newConfig.assetsSeq++;
+        mController.onConfigurationChanged(newConfig);
+        assertTrue(mConfigChangeListener.configChanges == 1);
+        assertTrue(mConfigChangeListener.densityChanges == 0);
+        assertTrue(mConfigChangeListener.smallestWidthChanges == 0);
+        assertTrue(mConfigChangeListener.themeChanges == 1);
+        assertTrue(mConfigChangeListener.localeChanges == 0);
+    }
+
+    @Test
+    public void testNightModeChangeCallback() {
+        mController.addConfigurationChangeListener(mConfigChangeListener);
+
+        Configuration newConfig = getConfigurationCopy();
+        newConfig.uiMode = Configuration.UI_MODE_NIGHT_YES;
+        mController.onConfigurationChanged(newConfig);
+        assertTrue(mConfigChangeListener.configChanges == 1);
+        assertTrue(mConfigChangeListener.densityChanges == 0);
+        assertTrue(mConfigChangeListener.smallestWidthChanges == 0);
+        assertTrue(mConfigChangeListener.themeChanges == 1);
+        assertTrue(mConfigChangeListener.localeChanges == 0);
+    }
+
+    @Test
+    public void testLocaleChangeCallback() {
+        mController.addConfigurationChangeListener(mConfigChangeListener);
+
+        Configuration newConfig = getConfigurationCopy();
+        // Just change the locales to be different
+        if (newConfig.locale == Locale.CANADA) {
+            newConfig.locale = Locale.US;
+        } else {
+            newConfig.locale = Locale.CANADA;
+        }
+        mController.onConfigurationChanged(newConfig);
+        assertTrue(mConfigChangeListener.configChanges == 1);
+        assertTrue(mConfigChangeListener.densityChanges == 0);
+        assertTrue(mConfigChangeListener.smallestWidthChanges == 0);
+        assertTrue(mConfigChangeListener.themeChanges == 0);
+        assertTrue(mConfigChangeListener.localeChanges == 1);
+    }
+
+    private Configuration getConfigurationCopy() {
+        final Configuration c = new Configuration(InstrumentationRegistry.getInstrumentation()
+                .getTargetContext().getResources().getConfiguration());
+        // In tests this might be undefined so make sure it's valid
+        c.assetsSeq = 1;
+        return c;
+    }
+
+    private class TestConfigurationChangeListener implements ConfigurationChangeListener {
+        // Counts of number of times each of the callbacks are called
+        public int configChanges;
+        public int densityChanges;
+        public int smallestWidthChanges;
+        public int themeChanges;
+        public int localeChanges;
+
+        @Override
+        public void onConfigurationChanged(Configuration newConfiguration) {
+            configChanges++;
+        }
+
+        @Override
+        public void onDensityOrFontScaleChanged() {
+            densityChanges++;
+        }
+
+        @Override
+        public void onSmallestScreenWidthChanged() {
+            smallestWidthChanges++;
+        }
+
+        @Override
+        public void onThemeChanged() {
+            themeChanges++;
+        }
+
+        @Override
+        public void onLocaleOrLayoutDirectionChanged() {
+            localeChanges++;
+        }
+    }
+
+    private class TestKeyguardChangeListener implements KeyguardChangeListener {
+        // Counts of number of times each of the callbacks are called
+        public int visibilityChanged;
+        public boolean lastVisibility;
+        public boolean lastOccluded;
+        public boolean lastAnimatingDismiss;
+        public int dismissAnimationFinished;
+
+        @Override
+        public void onKeyguardVisibilityChanged(boolean visible, boolean occluded,
+                boolean animatingDismiss) {
+            lastVisibility = visible;
+            lastOccluded = occluded;
+            lastAnimatingDismiss = animatingDismiss;
+            visibilityChanged++;
+        }
+
+        @Override
+        public void onKeyguardDismissAnimationFinished() {
+            dismissAnimationFinished++;
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/tasksurfacehelper/TaskSurfaceHelperControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/tasksurfacehelper/TaskSurfaceHelperControllerTest.java
deleted file mode 100644
index d614275..0000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/tasksurfacehelper/TaskSurfaceHelperControllerTest.java
+++ /dev/null
@@ -1,58 +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 com.android.wm.shell.tasksurfacehelper;
-
-import static org.mockito.Mockito.verify;
-
-import android.platform.test.annotations.Presubmit;
-import android.testing.AndroidTestingRunner;
-import android.view.SurfaceControl;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.common.ShellExecutor;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@Presubmit
-@RunWith(AndroidTestingRunner.class)
-@SmallTest
-public class TaskSurfaceHelperControllerTest {
-    private TaskSurfaceHelperController mTaskSurfaceHelperController;
-    @Mock
-    private ShellTaskOrganizer mMockTaskOrganizer;
-    @Mock
-    private ShellExecutor mMockShellExecutor;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        mTaskSurfaceHelperController = new TaskSurfaceHelperController(
-                mMockTaskOrganizer, mMockShellExecutor);
-    }
-
-    @Test
-    public void testSetGameModeForTask() {
-        mTaskSurfaceHelperController.setGameModeForTask(/*taskId*/1, /*gameMode*/3);
-        verify(mMockTaskOrganizer).setSurfaceMetadata(1, SurfaceControl.METADATA_GAME_MODE, 3);
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
index a0b1297..e2f2b71 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
@@ -79,6 +79,7 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
+import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.TestShellExecutor;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.ShellExecutor;
@@ -98,7 +99,7 @@
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public class ShellTransitionTests {
+public class ShellTransitionTests extends ShellTestCase {
 
     private final WindowOrganizer mOrganizer = mock(WindowOrganizer.class);
     private final TransactionPool mTransactionPool = mock(TransactionPool.class);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
new file mode 100644
index 0000000..680034bd
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor;
+
+import static com.android.wm.shell.MockSurfaceControlHelper.createMockSurfaceControlBuilder;
+import static com.android.wm.shell.MockSurfaceControlHelper.createMockSurfaceControlTransaction;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.same;
+import static org.mockito.Mockito.verify;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.testing.AndroidTestingRunner;
+import android.view.Display;
+import android.view.SurfaceControl;
+import android.view.SurfaceControlViewHost;
+import android.view.View;
+import android.window.WindowContainerTransaction;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.TestRunningTaskInfoBuilder;
+import com.android.wm.shell.common.DisplayController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+
+import java.util.function.Supplier;
+
+/**
+ * Tests for {@link WindowDecoration}.
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:WindowDecorationTests
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class WindowDecorationTests extends ShellTestCase {
+    private static final int CAPTION_HEIGHT_DP = 32;
+    private static final int SHADOW_RADIUS_DP = 5;
+
+    private final Rect mOutsetsDp = new Rect();
+    private final WindowDecoration.RelayoutResult<TestView> mRelayoutResult =
+            new WindowDecoration.RelayoutResult<>();
+
+    @Mock
+    private DisplayController mMockDisplayController;
+    @Mock
+    private ShellTaskOrganizer mMockShellTaskOrganizer;
+    @Mock
+    private WindowDecoration.SurfaceControlViewHostFactory mMockSurfaceControlViewHostFactory;
+    @Mock
+    private SurfaceControlViewHost mMockSurfaceControlViewHost;
+    @Mock
+    private TestView mMockView;
+    @Mock
+    private WindowContainerTransaction mMockWindowContainerTransaction;
+
+    private SurfaceControl.Builder mMockSurfaceControlBuilder;
+    private SurfaceControl.Transaction mMockSurfaceControlTransaction;
+
+    @Before
+    public void setUp() {
+        mMockSurfaceControlBuilder = createMockSurfaceControlBuilder(mock(SurfaceControl.class));
+        mMockSurfaceControlTransaction = createMockSurfaceControlTransaction();
+
+        doReturn(mMockSurfaceControlViewHost).when(mMockSurfaceControlViewHostFactory)
+                .create(any(), any(), any(), anyBoolean());
+    }
+
+    @Test
+    public void testNotCrashWhenDisplayAppearsAfterTask() {
+        doReturn(mock(Display.class)).when(mMockDisplayController)
+                .getDisplay(Display.DEFAULT_DISPLAY);
+
+        final int displayId = Display.DEFAULT_DISPLAY + 1;
+        final ActivityManager.TaskDescription.Builder taskDescriptionBuilder =
+                new ActivityManager.TaskDescription.Builder()
+                        .setBackgroundColor(Color.BLACK);
+        final ActivityManager.RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
+                .setDisplayId(displayId)
+                .setTaskDescriptionBuilder(taskDescriptionBuilder)
+                .setVisible(true)
+                .build();
+
+        final TestWindowDecoration windowDecor =
+                createWindowDecoration(taskInfo, new SurfaceControl());
+        windowDecor.relayout(taskInfo);
+
+        // It shouldn't show the window decoration when it can't obtain the display instance.
+        assertThat(mRelayoutResult.mRootView).isNull();
+
+        final ArgumentCaptor<DisplayController.OnDisplaysChangedListener> listenerArgumentCaptor =
+                ArgumentCaptor.forClass(DisplayController.OnDisplaysChangedListener.class);
+        verify(mMockDisplayController).addDisplayWindowListener(listenerArgumentCaptor.capture());
+        final DisplayController.OnDisplaysChangedListener listener =
+                listenerArgumentCaptor.getValue();
+
+        // Adding an irrelevant display shouldn't change the result.
+        listener.onDisplayAdded(Display.DEFAULT_DISPLAY);
+        assertThat(mRelayoutResult.mRootView).isNull();
+
+        final Display mockDisplay = mock(Display.class);
+        doReturn(mockDisplay).when(mMockDisplayController).getDisplay(displayId);
+
+        listener.onDisplayAdded(displayId);
+
+        // The listener should be removed when the display shows up.
+        verify(mMockDisplayController).removeDisplayWindowListener(same(listener));
+
+        assertThat(mRelayoutResult.mRootView).isSameInstanceAs(mMockView);
+        verify(mMockSurfaceControlViewHostFactory)
+                .create(any(), eq(mockDisplay), any(), anyBoolean());
+        verify(mMockSurfaceControlViewHost).setView(same(mMockView), any());
+    }
+
+    private TestWindowDecoration createWindowDecoration(
+            ActivityManager.RunningTaskInfo taskInfo, SurfaceControl testSurface) {
+        return new TestWindowDecoration(mContext, mMockDisplayController, mMockShellTaskOrganizer,
+                taskInfo, testSurface, () -> mMockSurfaceControlBuilder,
+                mMockSurfaceControlViewHostFactory);
+    }
+
+    private static class TestView extends View implements TaskFocusStateConsumer {
+        private TestView(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void setTaskFocusState(boolean focused) {}
+    }
+
+    private class TestWindowDecoration extends WindowDecoration<TestView> {
+        TestWindowDecoration(Context context, DisplayController displayController,
+                ShellTaskOrganizer taskOrganizer, ActivityManager.RunningTaskInfo taskInfo,
+                SurfaceControl taskSurface,
+                Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier,
+                SurfaceControlViewHostFactory surfaceControlViewHostFactory) {
+            super(context, displayController, taskOrganizer, taskInfo, taskSurface,
+                    surfaceControlBuilderSupplier, surfaceControlViewHostFactory);
+        }
+
+        @Override
+        void relayout(ActivityManager.RunningTaskInfo taskInfo) {
+            relayout(null /* taskInfo */, 0 /* layoutResId */, mMockView, CAPTION_HEIGHT_DP,
+                    mOutsetsDp, SHADOW_RADIUS_DP, mMockSurfaceControlTransaction,
+                    mMockWindowContainerTransaction, mRelayoutResult);
+        }
+    }
+}
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index 79953aa..1191b92 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/Readback.cpp
@@ -102,11 +102,36 @@
 
     SkRect srcRect = inSrcRect.toSkRect();
 
-    SkRect imageSrcRect =
-            SkRect::MakeLTRB(cropRect.left, cropRect.top, cropRect.right, cropRect.bottom);
-    if (imageSrcRect.isEmpty()) {
-        imageSrcRect = SkRect::MakeIWH(description.width, description.height);
+    SkRect imageSrcRect = SkRect::MakeIWH(description.width, description.height);
+    SkISize imageWH = SkISize::Make(description.width, description.height);
+    if (cropRect.left < cropRect.right && cropRect.top < cropRect.bottom) {
+        imageSrcRect =
+                SkRect::MakeLTRB(cropRect.left, cropRect.top, cropRect.right, cropRect.bottom);
+        imageWH = SkISize::Make(cropRect.right - cropRect.left, cropRect.bottom - cropRect.top);
+
+        // Chroma channels of YUV420 images are subsampled we may need to shrink the crop region by
+        // a whole texel on each side. Since skia still adds its own 0.5 inset, we apply an
+        // additional 0.5 inset. See GLConsumer::computeTransformMatrix for details.
+        float shrinkAmount = 0.0f;
+        switch (description.format) {
+            // Use HAL formats since some AHB formats are only available in vndk
+            case HAL_PIXEL_FORMAT_YCBCR_420_888:
+            case HAL_PIXEL_FORMAT_YV12:
+            case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
+                shrinkAmount = 0.5f;
+                break;
+            default:
+                break;
+        }
+
+        // Shrink the crop if it has more than 1-px and differs from the buffer size.
+        if (imageWH.width() > 1 && imageWH.width() < (int32_t)description.width)
+            imageSrcRect = imageSrcRect.makeInset(shrinkAmount, 0);
+
+        if (imageWH.height() > 1 && imageWH.height() < (int32_t)description.height)
+            imageSrcRect = imageSrcRect.makeInset(0, shrinkAmount);
     }
+
     ALOGV("imageSrcRect = " RECT_STRING, SK_RECT_ARGS(imageSrcRect));
 
     // Represents the "logical" width/height of the texture. That is, the dimensions of the buffer
@@ -165,7 +190,7 @@
      */
 
     SkMatrix m;
-    const SkRect imageDstRect = SkRect::MakeIWH(imageSrcRect.width(), imageSrcRect.height());
+    const SkRect imageDstRect = SkRect::Make(imageWH);
     const float px = imageDstRect.centerX();
     const float py = imageDstRect.centerY();
     if (windowTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) {
diff --git a/libs/hwui/jni/Paint.cpp b/libs/hwui/jni/Paint.cpp
index 0aa1465..ed453b1 100644
--- a/libs/hwui/jni/Paint.cpp
+++ b/libs/hwui/jni/Paint.cpp
@@ -497,16 +497,29 @@
         return true;
     }
 
-    static jfloat doRunAdvance(const Paint* paint, const Typeface* typeface, const jchar buf[],
-            jint start, jint count, jint bufSize, jboolean isRtl, jint offset) {
+    static jfloat doRunAdvance(JNIEnv* env, const Paint* paint, const Typeface* typeface,
+                               const jchar buf[], jint start, jint count, jint bufSize,
+                               jboolean isRtl, jint offset, jfloatArray advances,
+                               jint advancesIndex) {
+        if (advances) {
+            size_t advancesLength = env->GetArrayLength(advances);
+            if ((size_t)(count + advancesIndex) > advancesLength) {
+                doThrowAIOOBE(env);
+                return 0;
+            }
+        }
         minikin::Bidi bidiFlags = isRtl ? minikin::Bidi::FORCE_RTL : minikin::Bidi::FORCE_LTR;
-        if (offset == start + count) {
+        if (offset == start + count && advances == nullptr) {
             return MinikinUtils::measureText(paint, bidiFlags, typeface, buf, start, count,
                     bufSize, nullptr);
         }
         std::unique_ptr<float[]> advancesArray(new float[count]);
         MinikinUtils::measureText(paint, bidiFlags, typeface, buf, start, count, bufSize,
                 advancesArray.get());
+
+        if (advances) {
+            env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray.get());
+        }
         return minikin::getRunAdvance(advancesArray.get(), buf, start, count, offset);
     }
 
@@ -515,9 +528,23 @@
         const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
         const Typeface* typeface = paint->getAndroidTypeface();
         ScopedCharArrayRO textArray(env, text);
-        jfloat result = doRunAdvance(paint, typeface, textArray.get() + contextStart,
-                start - contextStart, end - start, contextEnd - contextStart, isRtl,
-                offset - contextStart);
+        jfloat result = doRunAdvance(env, paint, typeface, textArray.get() + contextStart,
+                                     start - contextStart, end - start, contextEnd - contextStart,
+                                     isRtl, offset - contextStart, nullptr, 0);
+        return result;
+    }
+
+    static jfloat getRunCharacterAdvance___CIIIIZI_FI_F(JNIEnv* env, jclass, jlong paintHandle,
+                                                        jcharArray text, jint start, jint end,
+                                                        jint contextStart, jint contextEnd,
+                                                        jboolean isRtl, jint offset,
+                                                        jfloatArray advances, jint advancesIndex) {
+        const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
+        const Typeface* typeface = paint->getAndroidTypeface();
+        ScopedCharArrayRO textArray(env, text);
+        jfloat result = doRunAdvance(env, paint, typeface, textArray.get() + contextStart,
+                                     start - contextStart, end - start, contextEnd - contextStart,
+                                     isRtl, offset - contextStart, advances, advancesIndex);
         return result;
     }
 
@@ -1034,113 +1061,112 @@
 }; // namespace PaintGlue
 
 static const JNINativeMethod methods[] = {
-    {"nGetNativeFinalizer", "()J", (void*) PaintGlue::getNativeFinalizer},
-    {"nInit","()J", (void*) PaintGlue::init},
-    {"nInitWithPaint","(J)J", (void*) PaintGlue::initWithPaint},
-    {"nBreakText","(J[CIIFI[F)I", (void*) PaintGlue::breakTextC},
-    {"nBreakText","(JLjava/lang/String;ZFI[F)I", (void*) PaintGlue::breakTextS},
-    {"nGetTextAdvances","(J[CIIIII[FI)F",
-            (void*) PaintGlue::getTextAdvances___CIIIII_FI},
-    {"nGetTextAdvances","(JLjava/lang/String;IIIII[FI)F",
-            (void*) PaintGlue::getTextAdvances__StringIIIII_FI},
+        {"nGetNativeFinalizer", "()J", (void*)PaintGlue::getNativeFinalizer},
+        {"nInit", "()J", (void*)PaintGlue::init},
+        {"nInitWithPaint", "(J)J", (void*)PaintGlue::initWithPaint},
+        {"nBreakText", "(J[CIIFI[F)I", (void*)PaintGlue::breakTextC},
+        {"nBreakText", "(JLjava/lang/String;ZFI[F)I", (void*)PaintGlue::breakTextS},
+        {"nGetTextAdvances", "(J[CIIIII[FI)F", (void*)PaintGlue::getTextAdvances___CIIIII_FI},
+        {"nGetTextAdvances", "(JLjava/lang/String;IIIII[FI)F",
+         (void*)PaintGlue::getTextAdvances__StringIIIII_FI},
 
-    {"nGetTextRunCursor", "(J[CIIIII)I", (void*) PaintGlue::getTextRunCursor___C},
-    {"nGetTextRunCursor", "(JLjava/lang/String;IIIII)I",
-            (void*) PaintGlue::getTextRunCursor__String},
-    {"nGetTextPath", "(JI[CIIFFJ)V", (void*) PaintGlue::getTextPath___C},
-    {"nGetTextPath", "(JILjava/lang/String;IIFFJ)V", (void*) PaintGlue::getTextPath__String},
-    {"nGetStringBounds", "(JLjava/lang/String;IIILandroid/graphics/Rect;)V",
-            (void*) PaintGlue::getStringBounds },
-    {"nGetCharArrayBounds", "(J[CIIILandroid/graphics/Rect;)V",
-            (void*) PaintGlue::getCharArrayBounds },
-    {"nHasGlyph", "(JILjava/lang/String;)Z", (void*) PaintGlue::hasGlyph },
-    {"nGetRunAdvance", "(J[CIIIIZI)F", (void*) PaintGlue::getRunAdvance___CIIIIZI_F},
-    {"nGetOffsetForAdvance", "(J[CIIIIZF)I",
-            (void*) PaintGlue::getOffsetForAdvance___CIIIIZF_I},
-    {"nGetFontMetricsIntForText", "(J[CIIIIZLandroid/graphics/Paint$FontMetricsInt;)V",
-      (void*)PaintGlue::getFontMetricsIntForText___C},
-    {"nGetFontMetricsIntForText",
-      "(JLjava/lang/String;IIIIZLandroid/graphics/Paint$FontMetricsInt;)V",
-      (void*)PaintGlue::getFontMetricsIntForText___String},
+        {"nGetTextRunCursor", "(J[CIIIII)I", (void*)PaintGlue::getTextRunCursor___C},
+        {"nGetTextRunCursor", "(JLjava/lang/String;IIIII)I",
+         (void*)PaintGlue::getTextRunCursor__String},
+        {"nGetTextPath", "(JI[CIIFFJ)V", (void*)PaintGlue::getTextPath___C},
+        {"nGetTextPath", "(JILjava/lang/String;IIFFJ)V", (void*)PaintGlue::getTextPath__String},
+        {"nGetStringBounds", "(JLjava/lang/String;IIILandroid/graphics/Rect;)V",
+         (void*)PaintGlue::getStringBounds},
+        {"nGetCharArrayBounds", "(J[CIIILandroid/graphics/Rect;)V",
+         (void*)PaintGlue::getCharArrayBounds},
+        {"nHasGlyph", "(JILjava/lang/String;)Z", (void*)PaintGlue::hasGlyph},
+        {"nGetRunAdvance", "(J[CIIIIZI)F", (void*)PaintGlue::getRunAdvance___CIIIIZI_F},
+        {"nGetRunCharacterAdvance", "(J[CIIIIZI[FI)F",
+         (void*)PaintGlue::getRunCharacterAdvance___CIIIIZI_FI_F},
+        {"nGetOffsetForAdvance", "(J[CIIIIZF)I", (void*)PaintGlue::getOffsetForAdvance___CIIIIZF_I},
+        {"nGetFontMetricsIntForText", "(J[CIIIIZLandroid/graphics/Paint$FontMetricsInt;)V",
+         (void*)PaintGlue::getFontMetricsIntForText___C},
+        {"nGetFontMetricsIntForText",
+         "(JLjava/lang/String;IIIIZLandroid/graphics/Paint$FontMetricsInt;)V",
+         (void*)PaintGlue::getFontMetricsIntForText___String},
 
-    // --------------- @FastNative ----------------------
+        // --------------- @FastNative ----------------------
 
-    {"nSetTextLocales","(JLjava/lang/String;)I", (void*) PaintGlue::setTextLocales},
-    {"nSetFontFeatureSettings","(JLjava/lang/String;)V",
-                (void*) PaintGlue::setFontFeatureSettings},
-    {"nGetFontMetrics", "(JLandroid/graphics/Paint$FontMetrics;)F",
-                (void*)PaintGlue::getFontMetrics},
-    {"nGetFontMetricsInt", "(JLandroid/graphics/Paint$FontMetricsInt;)I",
-            (void*)PaintGlue::getFontMetricsInt},
+        {"nSetTextLocales", "(JLjava/lang/String;)I", (void*)PaintGlue::setTextLocales},
+        {"nSetFontFeatureSettings", "(JLjava/lang/String;)V",
+         (void*)PaintGlue::setFontFeatureSettings},
+        {"nGetFontMetrics", "(JLandroid/graphics/Paint$FontMetrics;)F",
+         (void*)PaintGlue::getFontMetrics},
+        {"nGetFontMetricsInt", "(JLandroid/graphics/Paint$FontMetricsInt;)I",
+         (void*)PaintGlue::getFontMetricsInt},
 
-    // --------------- @CriticalNative ------------------
+        // --------------- @CriticalNative ------------------
 
-    {"nReset","(J)V", (void*) PaintGlue::reset},
-    {"nSet","(JJ)V", (void*) PaintGlue::assign},
-    {"nGetFlags","(J)I", (void*) PaintGlue::getFlags},
-    {"nSetFlags","(JI)V", (void*) PaintGlue::setFlags},
-    {"nGetHinting","(J)I", (void*) PaintGlue::getHinting},
-    {"nSetHinting","(JI)V", (void*) PaintGlue::setHinting},
-    {"nSetAntiAlias","(JZ)V", (void*) PaintGlue::setAntiAlias},
-    {"nSetSubpixelText","(JZ)V", (void*) PaintGlue::setSubpixelText},
-    {"nSetLinearText","(JZ)V", (void*) PaintGlue::setLinearText},
-    {"nSetUnderlineText","(JZ)V", (void*) PaintGlue::setUnderlineText},
-    {"nSetStrikeThruText","(JZ)V", (void*) PaintGlue::setStrikeThruText},
-    {"nSetFakeBoldText","(JZ)V", (void*) PaintGlue::setFakeBoldText},
-    {"nSetFilterBitmap","(JZ)V", (void*) PaintGlue::setFilterBitmap},
-    {"nSetDither","(JZ)V", (void*) PaintGlue::setDither},
-    {"nGetStyle","(J)I", (void*) PaintGlue::getStyle},
-    {"nSetStyle","(JI)V", (void*) PaintGlue::setStyle},
-    {"nSetColor","(JI)V", (void*) PaintGlue::setColor},
-    {"nSetColor","(JJJ)V", (void*) PaintGlue::setColorLong},
-    {"nSetAlpha","(JI)V", (void*) PaintGlue::setAlpha},
-    {"nGetStrokeWidth","(J)F", (void*) PaintGlue::getStrokeWidth},
-    {"nSetStrokeWidth","(JF)V", (void*) PaintGlue::setStrokeWidth},
-    {"nGetStrokeMiter","(J)F", (void*) PaintGlue::getStrokeMiter},
-    {"nSetStrokeMiter","(JF)V", (void*) PaintGlue::setStrokeMiter},
-    {"nGetStrokeCap","(J)I", (void*) PaintGlue::getStrokeCap},
-    {"nSetStrokeCap","(JI)V", (void*) PaintGlue::setStrokeCap},
-    {"nGetStrokeJoin","(J)I", (void*) PaintGlue::getStrokeJoin},
-    {"nSetStrokeJoin","(JI)V", (void*) PaintGlue::setStrokeJoin},
-    {"nGetFillPath","(JJJ)Z", (void*) PaintGlue::getFillPath},
-    {"nSetShader","(JJ)J", (void*) PaintGlue::setShader},
-    {"nSetColorFilter","(JJ)J", (void*) PaintGlue::setColorFilter},
-    {"nSetXfermode","(JI)V", (void*) PaintGlue::setXfermode},
-    {"nSetPathEffect","(JJ)J", (void*) PaintGlue::setPathEffect},
-    {"nSetMaskFilter","(JJ)J", (void*) PaintGlue::setMaskFilter},
-    {"nSetTypeface","(JJ)V", (void*) PaintGlue::setTypeface},
-    {"nGetTextAlign","(J)I", (void*) PaintGlue::getTextAlign},
-    {"nSetTextAlign","(JI)V", (void*) PaintGlue::setTextAlign},
-    {"nSetTextLocalesByMinikinLocaleListId","(JI)V",
-            (void*) PaintGlue::setTextLocalesByMinikinLocaleListId},
-    {"nIsElegantTextHeight","(J)Z", (void*) PaintGlue::isElegantTextHeight},
-    {"nSetElegantTextHeight","(JZ)V", (void*) PaintGlue::setElegantTextHeight},
-    {"nGetTextSize","(J)F", (void*) PaintGlue::getTextSize},
-    {"nSetTextSize","(JF)V", (void*) PaintGlue::setTextSize},
-    {"nGetTextScaleX","(J)F", (void*) PaintGlue::getTextScaleX},
-    {"nSetTextScaleX","(JF)V", (void*) PaintGlue::setTextScaleX},
-    {"nGetTextSkewX","(J)F", (void*) PaintGlue::getTextSkewX},
-    {"nSetTextSkewX","(JF)V", (void*) PaintGlue::setTextSkewX},
-    {"nGetLetterSpacing","(J)F", (void*) PaintGlue::getLetterSpacing},
-    {"nSetLetterSpacing","(JF)V", (void*) PaintGlue::setLetterSpacing},
-    {"nGetWordSpacing","(J)F", (void*) PaintGlue::getWordSpacing},
-    {"nSetWordSpacing","(JF)V", (void*) PaintGlue::setWordSpacing},
-    {"nGetStartHyphenEdit", "(J)I", (void*) PaintGlue::getStartHyphenEdit},
-    {"nGetEndHyphenEdit", "(J)I", (void*) PaintGlue::getEndHyphenEdit},
-    {"nSetStartHyphenEdit", "(JI)V", (void*) PaintGlue::setStartHyphenEdit},
-    {"nSetEndHyphenEdit", "(JI)V", (void*) PaintGlue::setEndHyphenEdit},
-    {"nAscent","(J)F", (void*) PaintGlue::ascent},
-    {"nDescent","(J)F", (void*) PaintGlue::descent},
-    {"nGetUnderlinePosition","(J)F", (void*) PaintGlue::getUnderlinePosition},
-    {"nGetUnderlineThickness","(J)F", (void*) PaintGlue::getUnderlineThickness},
-    {"nGetStrikeThruPosition","(J)F", (void*) PaintGlue::getStrikeThruPosition},
-    {"nGetStrikeThruThickness","(J)F", (void*) PaintGlue::getStrikeThruThickness},
-    {"nSetShadowLayer", "(JFFFJJ)V", (void*)PaintGlue::setShadowLayer},
-    {"nHasShadowLayer", "(J)Z", (void*)PaintGlue::hasShadowLayer},
-    {"nEqualsForTextMeasurement", "(JJ)Z", (void*)PaintGlue::equalsForTextMeasurement},
+        {"nReset", "(J)V", (void*)PaintGlue::reset},
+        {"nSet", "(JJ)V", (void*)PaintGlue::assign},
+        {"nGetFlags", "(J)I", (void*)PaintGlue::getFlags},
+        {"nSetFlags", "(JI)V", (void*)PaintGlue::setFlags},
+        {"nGetHinting", "(J)I", (void*)PaintGlue::getHinting},
+        {"nSetHinting", "(JI)V", (void*)PaintGlue::setHinting},
+        {"nSetAntiAlias", "(JZ)V", (void*)PaintGlue::setAntiAlias},
+        {"nSetSubpixelText", "(JZ)V", (void*)PaintGlue::setSubpixelText},
+        {"nSetLinearText", "(JZ)V", (void*)PaintGlue::setLinearText},
+        {"nSetUnderlineText", "(JZ)V", (void*)PaintGlue::setUnderlineText},
+        {"nSetStrikeThruText", "(JZ)V", (void*)PaintGlue::setStrikeThruText},
+        {"nSetFakeBoldText", "(JZ)V", (void*)PaintGlue::setFakeBoldText},
+        {"nSetFilterBitmap", "(JZ)V", (void*)PaintGlue::setFilterBitmap},
+        {"nSetDither", "(JZ)V", (void*)PaintGlue::setDither},
+        {"nGetStyle", "(J)I", (void*)PaintGlue::getStyle},
+        {"nSetStyle", "(JI)V", (void*)PaintGlue::setStyle},
+        {"nSetColor", "(JI)V", (void*)PaintGlue::setColor},
+        {"nSetColor", "(JJJ)V", (void*)PaintGlue::setColorLong},
+        {"nSetAlpha", "(JI)V", (void*)PaintGlue::setAlpha},
+        {"nGetStrokeWidth", "(J)F", (void*)PaintGlue::getStrokeWidth},
+        {"nSetStrokeWidth", "(JF)V", (void*)PaintGlue::setStrokeWidth},
+        {"nGetStrokeMiter", "(J)F", (void*)PaintGlue::getStrokeMiter},
+        {"nSetStrokeMiter", "(JF)V", (void*)PaintGlue::setStrokeMiter},
+        {"nGetStrokeCap", "(J)I", (void*)PaintGlue::getStrokeCap},
+        {"nSetStrokeCap", "(JI)V", (void*)PaintGlue::setStrokeCap},
+        {"nGetStrokeJoin", "(J)I", (void*)PaintGlue::getStrokeJoin},
+        {"nSetStrokeJoin", "(JI)V", (void*)PaintGlue::setStrokeJoin},
+        {"nGetFillPath", "(JJJ)Z", (void*)PaintGlue::getFillPath},
+        {"nSetShader", "(JJ)J", (void*)PaintGlue::setShader},
+        {"nSetColorFilter", "(JJ)J", (void*)PaintGlue::setColorFilter},
+        {"nSetXfermode", "(JI)V", (void*)PaintGlue::setXfermode},
+        {"nSetPathEffect", "(JJ)J", (void*)PaintGlue::setPathEffect},
+        {"nSetMaskFilter", "(JJ)J", (void*)PaintGlue::setMaskFilter},
+        {"nSetTypeface", "(JJ)V", (void*)PaintGlue::setTypeface},
+        {"nGetTextAlign", "(J)I", (void*)PaintGlue::getTextAlign},
+        {"nSetTextAlign", "(JI)V", (void*)PaintGlue::setTextAlign},
+        {"nSetTextLocalesByMinikinLocaleListId", "(JI)V",
+         (void*)PaintGlue::setTextLocalesByMinikinLocaleListId},
+        {"nIsElegantTextHeight", "(J)Z", (void*)PaintGlue::isElegantTextHeight},
+        {"nSetElegantTextHeight", "(JZ)V", (void*)PaintGlue::setElegantTextHeight},
+        {"nGetTextSize", "(J)F", (void*)PaintGlue::getTextSize},
+        {"nSetTextSize", "(JF)V", (void*)PaintGlue::setTextSize},
+        {"nGetTextScaleX", "(J)F", (void*)PaintGlue::getTextScaleX},
+        {"nSetTextScaleX", "(JF)V", (void*)PaintGlue::setTextScaleX},
+        {"nGetTextSkewX", "(J)F", (void*)PaintGlue::getTextSkewX},
+        {"nSetTextSkewX", "(JF)V", (void*)PaintGlue::setTextSkewX},
+        {"nGetLetterSpacing", "(J)F", (void*)PaintGlue::getLetterSpacing},
+        {"nSetLetterSpacing", "(JF)V", (void*)PaintGlue::setLetterSpacing},
+        {"nGetWordSpacing", "(J)F", (void*)PaintGlue::getWordSpacing},
+        {"nSetWordSpacing", "(JF)V", (void*)PaintGlue::setWordSpacing},
+        {"nGetStartHyphenEdit", "(J)I", (void*)PaintGlue::getStartHyphenEdit},
+        {"nGetEndHyphenEdit", "(J)I", (void*)PaintGlue::getEndHyphenEdit},
+        {"nSetStartHyphenEdit", "(JI)V", (void*)PaintGlue::setStartHyphenEdit},
+        {"nSetEndHyphenEdit", "(JI)V", (void*)PaintGlue::setEndHyphenEdit},
+        {"nAscent", "(J)F", (void*)PaintGlue::ascent},
+        {"nDescent", "(J)F", (void*)PaintGlue::descent},
+        {"nGetUnderlinePosition", "(J)F", (void*)PaintGlue::getUnderlinePosition},
+        {"nGetUnderlineThickness", "(J)F", (void*)PaintGlue::getUnderlineThickness},
+        {"nGetStrikeThruPosition", "(J)F", (void*)PaintGlue::getStrikeThruPosition},
+        {"nGetStrikeThruThickness", "(J)F", (void*)PaintGlue::getStrikeThruThickness},
+        {"nSetShadowLayer", "(JFFFJJ)V", (void*)PaintGlue::setShadowLayer},
+        {"nHasShadowLayer", "(J)Z", (void*)PaintGlue::hasShadowLayer},
+        {"nEqualsForTextMeasurement", "(JJ)Z", (void*)PaintGlue::equalsForTextMeasurement},
 };
 
-
 int register_android_graphics_Paint(JNIEnv* env) {
     return RegisterMethodsOrDie(env, "android/graphics/Paint", methods, NELEM(methods));
 }
diff --git a/libs/hwui/jni/Typeface.cpp b/libs/hwui/jni/Typeface.cpp
index d86d9ee..30d6d00 100644
--- a/libs/hwui/jni/Typeface.cpp
+++ b/libs/hwui/jni/Typeface.cpp
@@ -20,18 +20,20 @@
 #include <minikin/FontCollection.h>
 #include <minikin/FontFamily.h>
 #include <minikin/FontFileParser.h>
+#include <minikin/LocaleList.h>
 #include <minikin/SystemFonts.h>
 #include <nativehelper/ScopedPrimitiveArray.h>
 #include <nativehelper/ScopedUtfChars.h>
+
+#include <mutex>
+#include <unordered_map>
+
 #include "FontUtils.h"
 #include "GraphicsJNI.h"
 #include "SkData.h"
 #include "SkTypeface.h"
 #include "fonts/Font.h"
 
-#include <mutex>
-#include <unordered_map>
-
 #ifdef __ANDROID__
 #include <sys/stat.h>
 #endif
@@ -109,15 +111,15 @@
     std::vector<std::shared_ptr<minikin::FontFamily>> familyVec;
     Typeface* typeface = (fallbackPtr == 0) ? nullptr : toTypeface(fallbackPtr);
     if (typeface != nullptr) {
-        const std::vector<std::shared_ptr<minikin::FontFamily>>& fallbackFamilies =
-            toTypeface(fallbackPtr)->fFontCollection->getFamilies();
-        familyVec.reserve(families.size() + fallbackFamilies.size());
+        const std::shared_ptr<minikin::FontCollection>& fallbackCollection =
+                toTypeface(fallbackPtr)->fFontCollection;
+        familyVec.reserve(families.size() + fallbackCollection->getFamilyCount());
         for (size_t i = 0; i < families.size(); i++) {
             FontFamilyWrapper* family = reinterpret_cast<FontFamilyWrapper*>(families[i]);
             familyVec.emplace_back(family->family);
         }
-        for (size_t i = 0; i < fallbackFamilies.size(); i++) {
-            familyVec.emplace_back(fallbackFamilies[i]);
+        for (size_t i = 0; i < fallbackCollection->getFamilyCount(); i++) {
+            familyVec.emplace_back(fallbackCollection->getFamilyAt(i));
         }
     } else {
         familyVec.reserve(families.size());
@@ -358,13 +360,13 @@
 
 // Critical Native
 static jint Typeface_getFamilySize(CRITICAL_JNI_PARAMS_COMMA jlong faceHandle) {
-    return toTypeface(faceHandle)->fFontCollection->getFamilies().size();
+    return toTypeface(faceHandle)->fFontCollection->getFamilyCount();
 }
 
 // Critical Native
 static jlong Typeface_getFamily(CRITICAL_JNI_PARAMS_COMMA jlong faceHandle, jint index) {
     std::shared_ptr<minikin::FontFamily> family =
-            toTypeface(faceHandle)->fFontCollection->getFamilies()[index];
+            toTypeface(faceHandle)->fFontCollection->getFamilyAt(index);
     return reinterpret_cast<jlong>(new FontFamilyWrapper(std::move(family)));
 }
 
@@ -380,6 +382,12 @@
     minikin::SystemFonts::addFontMap(std::move(collection));
 }
 
+// Fast Native
+static void Typeface_registerLocaleList(JNIEnv* env, jobject, jstring jLocales) {
+    ScopedUtfChars locales(env, jLocales);
+    minikin::registerLocaleList(locales.c_str());
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 static const JNINativeMethod gTypefaceMethods[] = {
@@ -405,6 +413,7 @@
         {"nativeGetFamily", "(JI)J", (void*)Typeface_getFamily},
         {"nativeWarmUpCache", "(Ljava/lang/String;)V", (void*)Typeface_warmUpCache},
         {"nativeAddFontCollections", "(J)V", (void*)Typeface_addFontCollection},
+        {"nativeRegisterLocaleList", "(Ljava/lang/String;)V", (void*)Typeface_registerLocaleList},
 };
 
 int register_android_graphics_Typeface(JNIEnv* env)
diff --git a/libs/incident/libincident.map.txt b/libs/incident/libincident.map.txt
index f157763..f75ccea 100644
--- a/libs/incident/libincident.map.txt
+++ b/libs/incident/libincident.map.txt
@@ -1,15 +1,15 @@
 LIBINCIDENT {
     global:
-        AIncidentReportArgs_init; # apex # introduced=30
-        AIncidentReportArgs_clone; # apex # introduced=30
-        AIncidentReportArgs_delete; # apex # introduced=30
-        AIncidentReportArgs_setAll; # apex # introduced=30
-        AIncidentReportArgs_setPrivacyPolicy; # apex # introduced=30
-        AIncidentReportArgs_addSection; # apex # introduced=30
-        AIncidentReportArgs_setReceiverPackage; # apex # introduced=30
-        AIncidentReportArgs_setReceiverClass; # apex # introduced=30
-        AIncidentReportArgs_addHeader; # apex # introduced=30
-        AIncidentReportArgs_takeReport; # apex # introduced=30
+        AIncidentReportArgs_init; # systemapi # introduced=30
+        AIncidentReportArgs_clone; # systemapi # introduced=30
+        AIncidentReportArgs_delete; # systemapi # introduced=30
+        AIncidentReportArgs_setAll; # systemapi # introduced=30
+        AIncidentReportArgs_setPrivacyPolicy; # systemapi # introduced=30
+        AIncidentReportArgs_addSection; # systemapi # introduced=30
+        AIncidentReportArgs_setReceiverPackage; # systemapi # introduced=30
+        AIncidentReportArgs_setReceiverClass; # systemapi # introduced=30
+        AIncidentReportArgs_addHeader; # systemapi # introduced=30
+        AIncidentReportArgs_takeReport; # systemapi # introduced=30
     local:
         *;
 };
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index f4e965f..2b9f159 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -59,6 +59,7 @@
     void registerLocationPendingIntent(String provider, in LocationRequest request, in PendingIntent pendingIntent, String packageName, @nullable String attributionTag);
     void unregisterLocationPendingIntent(in PendingIntent pendingIntent);
 
+    @EnforcePermission(allOf={"LOCATION_HARDWARE", "ACCESS_FINE_LOCATION"})
     void injectLocation(in Location location);
 
     void requestListenerFlush(String provider, in ILocationListener listener, int requestCode);
@@ -113,8 +114,10 @@
     boolean isProviderPackage(@nullable String provider, String packageName, @nullable String attributionTag);
     List<String> getProviderPackages(String provider);
 
+    @EnforcePermission("LOCATION_HARDWARE")
     void setExtraLocationControllerPackage(String packageName);
     String getExtraLocationControllerPackage();
+    @EnforcePermission("LOCATION_HARDWARE")
     void setExtraLocationControllerPackageEnabled(boolean enabled);
     boolean isExtraLocationControllerPackageEnabled();
 
@@ -125,7 +128,9 @@
     boolean isAdasGnssLocationEnabledForUser(int userId);
     void setAdasGnssLocationEnabledForUser(boolean enabled, int userId);
 
+    @EnforcePermission("CONTROL_AUTOMOTIVE_GNSS")
     boolean isAutomotiveGnssSuspended();
+    @EnforcePermission("CONTROL_AUTOMOTIVE_GNSS")
     void setAutomotiveGnssSuspended(boolean suspended);
 
     void addTestProvider(String name, in ProviderProperties properties,
diff --git a/location/java/android/location/SatellitePvt.java b/location/java/android/location/SatellitePvt.java
index f3e1508..2031929 100644
--- a/location/java/android/location/SatellitePvt.java
+++ b/location/java/android/location/SatellitePvt.java
@@ -539,7 +539,7 @@
      *
      * <p>This field is valid if {@link #hasIssueOfDataEphemeris()} is true.
      */
-    @IntRange(from = 0, to = 255)
+    @IntRange(from = 0, to = 1023)
     public int getIssueOfDataEphemeris() {
         return mIssueOfDataEphemeris;
     }
@@ -847,8 +847,8 @@
          */
         @NonNull
         public Builder setIssueOfDataEphemeris(
-                @IntRange(from = 0, to = 255) int issueOfDataEphemeris) {
-            Preconditions.checkArgumentInRange(issueOfDataEphemeris, 0, 255,
+                @IntRange(from = 0, to = 1023) int issueOfDataEphemeris) {
+            Preconditions.checkArgumentInRange(issueOfDataEphemeris, 0, 1023,
                     "issueOfDataEphemeris");
             mIssueOfDataEphemeris = issueOfDataEphemeris;
             mFlags = (byte) (mFlags | HAS_ISSUE_OF_DATA_EPHEMERIS);
diff --git a/location/java/android/location/SettingInjectorService.java b/location/java/android/location/SettingInjectorService.java
index d6f8a7c..2aa812b 100644
--- a/location/java/android/location/SettingInjectorService.java
+++ b/location/java/android/location/SettingInjectorService.java
@@ -179,7 +179,7 @@
      * intent.
      */
     private void sendStatus(Intent intent, String summary, boolean enabled) {
-        Messenger messenger = intent.getParcelableExtra(MESSENGER_KEY);
+        Messenger messenger = intent.getParcelableExtra(MESSENGER_KEY, android.os.Messenger.class);
         // Bail out to avoid crashing GmsCore with incoming malicious Intent.
         if (messenger == null) {
             return;
diff --git a/media/TEST_MAPPING b/media/TEST_MAPPING
index a2b2ed5..6f0e623 100644
--- a/media/TEST_MAPPING
+++ b/media/TEST_MAPPING
@@ -25,11 +25,15 @@
         }
       ],
       "file_patterns": ["(?i)drm|crypto"]
-    }
-  ],
-  "imports": [
+    },
     {
-      "path": "frameworks/av/drm/mediadrm/plugins"
+      "name": "CtsMediaDrmFrameworkTestCases",
+      "options" : [
+        {
+          "include-annotation": "android.platform.test.annotations.Presubmit"
+        }
+      ],
+      "file_patterns": ["(?i)drm|crypto"]
     }
   ]
 }
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index ded9597..546f0c6 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -1286,6 +1286,8 @@
         /**
          * Specifying if haptic should be muted or not when playing audio-haptic coupled data.
          * By default, haptic channels are disabled.
+         * <p>This will be ignored if the caller doesn't have the
+         * {@link android.Manifest.permission#VIBRATE} permission.
          * @param muted true to force muting haptic channels.
          * @return the same Builder instance.
          */
diff --git a/media/java/android/media/AudioPlaybackConfiguration.java b/media/java/android/media/AudioPlaybackConfiguration.java
index d18d7e4..457fccf 100644
--- a/media/java/android/media/AudioPlaybackConfiguration.java
+++ b/media/java/android/media/AudioPlaybackConfiguration.java
@@ -167,6 +167,11 @@
      * The state used to update device id, does not actually change the state of the player
      */
     public static final int PLAYER_UPDATE_DEVICE_ID = 5;
+    /**
+     * @hide
+     * The state used to update port id, does not actually change the state of the player
+     */
+    public static final int PLAYER_UPDATE_PORT_ID = 6;
 
     /** @hide */
     @IntDef({
@@ -176,7 +181,8 @@
         PLAYER_STATE_STARTED,
         PLAYER_STATE_PAUSED,
         PLAYER_STATE_STOPPED,
-        PLAYER_UPDATE_DEVICE_ID
+        PLAYER_UPDATE_DEVICE_ID,
+        PLAYER_UPDATE_PORT_ID,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface PlayerState {}
@@ -191,6 +197,7 @@
             case PLAYER_STATE_PAUSED: return "PLAYER_STATE_PAUSED";
             case PLAYER_STATE_STOPPED: return "PLAYER_STATE_STOPPED";
             case PLAYER_UPDATE_DEVICE_ID: return "PLAYER_UPDATE_DEVICE_ID";
+            case PLAYER_UPDATE_PORT_ID: return "PLAYER_UPDATE_PORT_ID";
             default:
                 return "invalid state " + state;
         }
@@ -669,7 +676,8 @@
             case PLAYER_STATE_STARTED: return "started";
             case PLAYER_STATE_PAUSED: return "paused";
             case PLAYER_STATE_STOPPED: return "stopped";
-            case PLAYER_UPDATE_DEVICE_ID: return "device";
+            case PLAYER_UPDATE_DEVICE_ID: return "device updated";
+            case PLAYER_UPDATE_PORT_ID: return "port updated";
             default:
                 return "unknown player state - FIXME";
         }
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index e28178a..92d81c6 100755
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -74,7 +74,7 @@
 
     oneway void playerAttributes(in int piid, in AudioAttributes attr);
 
-    oneway void playerEvent(in int piid, in int event, in int deviceId);
+    oneway void playerEvent(in int piid, in int event, in int eventId);
 
     oneway void releasePlayer(in int piid);
 
@@ -107,6 +107,7 @@
 
     boolean isMasterMute();
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     void setMasterMute(boolean mute, int flags, String callingPackage, int userId,
             in String attributionTag);
 
@@ -118,27 +119,37 @@
     @UnsupportedAppUsage
     int getStreamMaxVolume(int streamType);
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     List<AudioVolumeGroup> getAudioVolumeGroups();
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     void setVolumeIndexForAttributes(in AudioAttributes aa, int index, int flags,
             String callingPackage, in String attributionTag);
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     int getVolumeIndexForAttributes(in AudioAttributes aa);
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     int getMaxVolumeIndexForAttributes(in AudioAttributes aa);
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     int getMinVolumeIndexForAttributes(in AudioAttributes aa);
 
+    @EnforcePermission("QUERY_AUDIO_STATE")
     int getLastAudibleStreamVolume(int streamType);
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     void setSupportedSystemUsages(in int[] systemUsages);
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     int[] getSupportedSystemUsages();
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     List<AudioProductStrategy> getAudioProductStrategies();
 
     boolean isMicrophoneMuted();
 
+    @EnforcePermission("ACCESS_ULTRASOUND")
     boolean isUltrasoundSupported();
 
     void setMicrophoneMute(boolean on, String callingPackage, int userId, in String attributionTag);
@@ -220,6 +231,7 @@
     IRingtonePlayer getRingtonePlayer();
     int getUiSoundsStreamType();
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     void setWiredDeviceConnectionState(in AudioDeviceAttributes aa, int state, String caller);
 
     @UnsupportedAppUsage
@@ -306,8 +318,10 @@
 
     int setPreferredDevicesForStrategy(in int strategy, in List<AudioDeviceAttributes> device);
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     int removePreferredDevicesForStrategy(in int strategy);
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     List<AudioDeviceAttributes> getPreferredDevicesForStrategy(in int strategy);
 
     List<AudioDeviceAttributes> getDevicesForAttributes(in AudioAttributes attributes);
@@ -325,6 +339,7 @@
 
     oneway void setRttEnabled(in boolean rttEnabled);
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     void setDeviceVolumeBehavior(in AudioDeviceAttributes device,
              in int deviceVolumeBehavior, in String pkgName);
 
@@ -333,13 +348,16 @@
     // WARNING: read warning at top of file, new methods that need to be used by native
     // code via IAudioManager.h need to be added to the top section.
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     oneway void setMultiAudioFocusEnabled(in boolean enabled);
 
     int setPreferredDevicesForCapturePreset(
             in int capturePreset, in List<AudioDeviceAttributes> devices);
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     int clearPreferredDevicesForCapturePreset(in int capturePreset);
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(in int capturePreset);
 
     void registerCapturePresetDevicesRoleDispatcher(ICapturePresetDevicesRoleDispatcher dispatcher);
@@ -407,12 +425,16 @@
 
     boolean isSpatializerAvailable();
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     boolean isSpatializerAvailableForDevice(in AudioDeviceAttributes device);
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     boolean hasHeadTracker(in AudioDeviceAttributes device);
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     void setHeadTrackerEnabled(boolean enabled, in AudioDeviceAttributes device);
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     boolean isHeadTrackerEnabled(in AudioDeviceAttributes device);
 
     boolean isHeadTrackerAvailable();
@@ -420,6 +442,7 @@
     void registerSpatializerHeadTrackerAvailableCallback(
             in ISpatializerHeadTrackerAvailableCallback cb, boolean register);
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     void setSpatializerEnabled(boolean enabled);
 
     boolean canBeSpatialized(in AudioAttributes aa, in AudioFormat af);
@@ -428,46 +451,65 @@
 
     void unregisterSpatializerCallback(in ISpatializerCallback cb);
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     void registerSpatializerHeadTrackingCallback(in ISpatializerHeadTrackingModeCallback cb);
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     void unregisterSpatializerHeadTrackingCallback(in ISpatializerHeadTrackingModeCallback cb);
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     void registerHeadToSoundstagePoseCallback(in ISpatializerHeadToSoundStagePoseCallback cb);
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     void unregisterHeadToSoundstagePoseCallback(in ISpatializerHeadToSoundStagePoseCallback cb);
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     List<AudioDeviceAttributes> getSpatializerCompatibleAudioDevices();
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     void addSpatializerCompatibleAudioDevice(in AudioDeviceAttributes ada);
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     void removeSpatializerCompatibleAudioDevice(in AudioDeviceAttributes ada);
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     void setDesiredHeadTrackingMode(int mode);
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     int getDesiredHeadTrackingMode();
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     int[] getSupportedHeadTrackingModes();
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     int getActualHeadTrackingMode();
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     oneway void setSpatializerGlobalTransform(in float[] transform);
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     oneway void recenterHeadTracker();
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     void setSpatializerParameter(int key, in byte[] value);
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     void getSpatializerParameter(int key, inout byte[] value);
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     int getSpatializerOutput();
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     void registerSpatializerOutputCallback(in ISpatializerOutputCallback cb);
 
+    @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
     void unregisterSpatializerOutputCallback(in ISpatializerOutputCallback cb);
 
     boolean isVolumeFixed();
 
     VolumeInfo getDefaultVolumeInfo();
 
+    @EnforcePermission("CALL_AUDIO_INTERCEPTION")
     boolean isPstnCallAudioInterceptable();
 
     oneway void muteAwaitConnection(in int[] usagesToMute, in AudioDeviceAttributes dev,
@@ -475,8 +517,10 @@
 
     oneway void cancelMuteAwaitConnection(in AudioDeviceAttributes dev);
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     AudioDeviceAttributes getMutingExpectedDevice();
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     void registerMuteAwaitConnectionDispatcher(in IMuteAwaitConnectionCallback cb,
             boolean register);
 
@@ -486,22 +530,28 @@
     void registerDeviceVolumeBehaviorDispatcher(boolean register,
             in IDeviceVolumeBehaviorDispatcher dispatcher);
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     List<AudioFocusInfo> getFocusStack();
 
     boolean sendFocusLoss(in AudioFocusInfo focusLoser, in IAudioPolicyCallback apcb);
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)")
     void addAssistantServicesUids(in int[] assistantUID);
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)")
     void removeAssistantServicesUids(in int[] assistantUID);
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)")
     void setActiveAssistantServiceUids(in int[] activeUids);
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)")
     int[] getAssistantServicesUids();
 
+    @EnforcePermission("MODIFY_AUDIO_ROUTING")
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)")
     int[] getActiveAssistantServiceUids();
 
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index d7f3338..7b27358 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -445,6 +445,14 @@
     <td class=NA>Not Used</td>
     <td class=NA>Not Used</td>
    </tr>
+   <tr>
+    <td>AV1</td>
+    <td>AV1 <a href="https://aomediacodec.github.io/av1-isobmff/#av1codecconfigurationbox-syntax">
+        AV1CodecConfigurationRecord</a> Data (optional)
+    </td>
+    <td class=NA>Not Used</td>
+    <td class=NA>Not Used</td>
+   </tr>
   </tbody>
  </table>
 
diff --git a/media/java/android/media/MediaMetadata.java b/media/java/android/media/MediaMetadata.java
index db5e52a..7b3a568 100644
--- a/media/java/android/media/MediaMetadata.java
+++ b/media/java/android/media/MediaMetadata.java
@@ -500,7 +500,7 @@
     public Rating getRating(@RatingKey String key) {
         Rating rating = null;
         try {
-            rating = mBundle.getParcelable(key);
+            rating = mBundle.getParcelable(key, android.media.Rating.class);
         } catch (Exception e) {
             // ignore, value was not a bitmap
             Log.w(TAG, "Failed to retrieve a key as Rating.", e);
@@ -518,7 +518,7 @@
     public Bitmap getBitmap(@BitmapKey String key) {
         Bitmap bmp = null;
         try {
-            bmp = mBundle.getParcelable(key);
+            bmp = mBundle.getParcelable(key, android.graphics.Bitmap.class);
         } catch (Exception e) {
             // ignore, value was not a bitmap
             Log.w(TAG, "Failed to retrieve a key as Bitmap.", e);
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index 7d57734..d7fc205 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -3184,7 +3184,7 @@
         public void onReceive(Context context, Intent intent) {
             if (intent.getAction().equals(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED)) {
                 updateWifiDisplayStatus((WifiDisplayStatus) intent.getParcelableExtra(
-                        DisplayManager.EXTRA_WIFI_DISPLAY_STATUS));
+                        DisplayManager.EXTRA_WIFI_DISPLAY_STATUS, android.hardware.display.WifiDisplayStatus.class));
             }
         }
     }
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index d8995b4..57f1056 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -102,6 +102,12 @@
 
     private final String mPackageName;
 
+    /**
+     * Stores the latest copy of all routes received from {@link MediaRouter2ServiceImpl}, without
+     * any filtering, sorting, or deduplication.
+     *
+     * <p>Uses {@link MediaRoute2Info#getId()} to set each entry's key.
+     */
     @GuardedBy("mLock")
     final Map<String, MediaRoute2Info> mRoutes = new ArrayMap<>();
 
@@ -121,7 +127,22 @@
 
     final Handler mHandler;
 
+    /**
+     * Stores an auxiliary copy of {@link #mFilteredRoutes} at the time of the last route callback
+     * dispatch. This is only used to determine what callback a route should be assigned to (added,
+     * removed, changed) in {@link #dispatchFilteredRoutesChangedLocked(List)}.
+     */
     private volatile ArrayMap<String, MediaRoute2Info> mPreviousRoutes = new ArrayMap<>();
+
+    /**
+     * Stores the latest copy of exposed routes after filtering, sorting, and deduplication. Can be
+     * accessed through {@link #getRoutes()}.
+     *
+     * <p>This list is a copy of {@link #mRoutes} which has undergone filtering, sorting, and
+     * deduplication using criteria in {@link #mDiscoveryPreference}.
+     *
+     * @see #filterRoutesWithCompositePreferenceLocked(List)
+     */
     private volatile List<MediaRoute2Info> mFilteredRoutes = Collections.emptyList();
     private volatile OnGetControllerHintsListener mOnGetControllerHintsListener;
 
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
index 071667a..c84f5b0 100644
--- a/media/java/android/media/MediaRouter2Manager.java
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -172,7 +172,7 @@
             try {
                 mMediaRouterService.startScan(client);
             } catch (RemoteException ex) {
-                Log.e(TAG, "Unable to get sessions. Service probably died.", ex);
+                throw ex.rethrowFromSystemServer();
             }
         }
     }
@@ -196,7 +196,7 @@
             try {
                 mMediaRouterService.stopScan(client);
             } catch (RemoteException ex) {
-                Log.e(TAG, "Unable to get sessions. Service probably died.", ex);
+                throw ex.rethrowFromSystemServer();
             }
         }
     }
@@ -361,9 +361,8 @@
             return mMediaRouterService.getSystemSessionInfoForPackage(
                     getOrCreateClient(), packageName);
         } catch (RemoteException ex) {
-            Log.e(TAG, "Unable to get current system session info", ex);
+            throw ex.rethrowFromSystemServer();
         }
-        return null;
     }
 
     /**
@@ -429,7 +428,7 @@
             try {
                 return mMediaRouterService.getRemoteSessions(client);
             } catch (RemoteException ex) {
-                Log.e(TAG, "Unable to get sessions. Service probably died.", ex);
+                throw ex.rethrowFromSystemServer();
             }
         }
         return Collections.emptyList();
@@ -521,7 +520,7 @@
                 int requestId = mNextRequestId.getAndIncrement();
                 mMediaRouterService.setRouteVolumeWithManager(client, requestId, route, volume);
             } catch (RemoteException ex) {
-                Log.e(TAG, "Unable to set route volume.", ex);
+                throw ex.rethrowFromSystemServer();
             }
         }
     }
@@ -551,7 +550,7 @@
                 mMediaRouterService.setSessionVolumeWithManager(
                         client, requestId, sessionInfo.getId(), volume);
             } catch (RemoteException ex) {
-                Log.e(TAG, "Unable to set session volume.", ex);
+                throw ex.rethrowFromSystemServer();
             }
         }
     }
@@ -816,7 +815,7 @@
                 mMediaRouterService.selectRouteWithManager(
                         client, requestId, sessionInfo.getId(), route);
             } catch (RemoteException ex) {
-                Log.e(TAG, "selectRoute: Failed to send a request.", ex);
+                throw ex.rethrowFromSystemServer();
             }
         }
     }
@@ -858,7 +857,7 @@
                 mMediaRouterService.deselectRouteWithManager(
                         client, requestId, sessionInfo.getId(), route);
             } catch (RemoteException ex) {
-                Log.e(TAG, "deselectRoute: Failed to send a request.", ex);
+                throw ex.rethrowFromSystemServer();
             }
         }
     }
@@ -883,7 +882,7 @@
                 mMediaRouterService.releaseSessionWithManager(
                         client, requestId, sessionInfo.getId());
             } catch (RemoteException ex) {
-                Log.e(TAG, "releaseSession: Failed to send a request", ex);
+                throw ex.rethrowFromSystemServer();
             }
         }
     }
@@ -903,7 +902,7 @@
                 mMediaRouterService.transferToRouteWithManager(
                         client, requestId, session.getId(), route);
             } catch (RemoteException ex) {
-                Log.e(TAG, "transferToRoute: Failed to send a request.", ex);
+                throw ex.rethrowFromSystemServer();
             }
         }
     }
@@ -923,7 +922,7 @@
                 mMediaRouterService.requestCreateSessionWithManager(
                         client, requestId, oldSession, route);
             } catch (RemoteException ex) {
-                Log.e(TAG, "requestCreateSession: Failed to send a request", ex);
+                throw ex.rethrowFromSystemServer();
             }
         }
     }
@@ -979,10 +978,9 @@
                 mClient = client;
                 return client;
             } catch (RemoteException ex) {
-                Log.e(TAG, "Unable to register media router manager.", ex);
+                throw ex.rethrowFromSystemServer();
             }
         }
-        return null;
     }
 
     /**
diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java
index 00fc275..a6e8fa0 100644
--- a/media/java/android/media/RemoteController.java
+++ b/media/java/android/media/RemoteController.java
@@ -407,7 +407,7 @@
             mEditableKeys = editableKeys;
 
             mEditorArtwork = (Bitmap) metadata.getParcelable(
-                    String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK));
+                    String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK), android.graphics.Bitmap.class);
             if (mEditorArtwork != null) {
                 cleanupBitmapFromBundle(MediaMetadataEditor.BITMAP_KEY_ARTWORK);
             }
diff --git a/media/java/android/media/audiofx/HapticGenerator.java b/media/java/android/media/audiofx/HapticGenerator.java
index fe7f29e..d2523ef 100644
--- a/media/java/android/media/audiofx/HapticGenerator.java
+++ b/media/java/android/media/audiofx/HapticGenerator.java
@@ -91,7 +91,8 @@
     }
 
     /**
-     * Enable or disable the effect.
+     * Enable or disable the effect. The effect can only be enabled if the caller has the
+     * {@link android.Manifest.permission#VIBRATE} permission.
      *
      * @param enabled the requested enable state
      * @return {@link #SUCCESS} in case of success, {@link #ERROR_INVALID_OPERATION}
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index bc00c40..9e265d8 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -917,7 +917,7 @@
         public boolean onMediaButtonEvent(@NonNull Intent mediaButtonIntent) {
             if (mSession != null && mHandler != null
                     && Intent.ACTION_MEDIA_BUTTON.equals(mediaButtonIntent.getAction())) {
-                KeyEvent ke = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
+                KeyEvent ke = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT, android.view.KeyEvent.class);
                 if (ke != null && ke.getAction() == KeyEvent.ACTION_DOWN) {
                     PlaybackState state = mSession.mPlaybackState;
                     long validActions = state == null ? 0 : state.getActions();
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 13f7ee6..bbb4d1f 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -1161,6 +1161,10 @@
     public int tune(@NonNull FrontendSettings settings) {
         mFrontendLock.lock();
         try {
+            if (mFeOwnerTuner != null) {
+                Log.d(TAG, "Operation cannot be done by sharee of tuner");
+                return RESULT_INVALID_STATE;
+            }
             final int type = settings.getType();
             if (mFrontendHandle != null && type != mFrontendType) {
                 Log.e(TAG, "Frontend was opened with type " + mFrontendType
@@ -1204,6 +1208,10 @@
     public int cancelTuning() {
         mFrontendLock.lock();
         try {
+            if (mFeOwnerTuner != null) {
+                Log.d(TAG, "Operation cannot be done by sharee of tuner");
+                return RESULT_INVALID_STATE;
+            }
             return nativeStopTune();
         } finally {
             mFrontendLock.unlock();
@@ -1237,6 +1245,10 @@
 
         mFrontendLock.lock();
         try {
+            if (mFeOwnerTuner != null) {
+                Log.d(TAG, "Operation cannot be done by sharee of tuner");
+                return RESULT_INVALID_STATE;
+            }
             synchronized (mScanCallbackLock) {
                 // Scan can be called again for blink scan if scanCallback and executor are same as
                 //before.
@@ -1287,6 +1299,10 @@
     public int cancelScanning() {
         mFrontendLock.lock();
         try {
+            if (mFeOwnerTuner != null) {
+                Log.d(TAG, "Operation cannot be done by sharee of tuner");
+                return RESULT_INVALID_STATE;
+            }
             synchronized (mScanCallbackLock) {
                 FrameworkStatsLog.write(FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId,
                         FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__SCAN_STOPPED);
@@ -1377,6 +1393,9 @@
             if (mFrontend == null) {
                 throw new IllegalStateException("frontend is not initialized");
             }
+            if (mFeOwnerTuner != null) {
+                throw new IllegalStateException("Operation cannot be done by sharee of tuner");
+            }
             return nativeGetFrontendStatus(statusTypes);
         } finally {
             mFrontendLock.unlock();
@@ -1480,6 +1499,10 @@
         mFrontendCiCamLock.lock();
         mFrontendLock.lock();
         try {
+            if (mFeOwnerTuner != null) {
+                Log.d(TAG, "Operation cannot be done by sharee of tuner");
+                return RESULT_INVALID_STATE;
+            }
             if (TunerVersionChecker.checkHigherOrEqualVersionTo(
                     TunerVersionChecker.TUNER_VERSION_1_1,
                     "linkFrontendToCiCam")) {
@@ -1543,6 +1566,10 @@
     public int disconnectFrontendToCiCam(int ciCamId) {
         acquireTRMSLock("disconnectFrontendToCiCam()");
         try {
+            if (mFeOwnerTuner != null) {
+                Log.d(TAG, "Operation cannot be done by sharee of tuner");
+                return RESULT_INVALID_STATE;
+            }
             if (TunerVersionChecker.checkHigherOrEqualVersionTo(
                     TunerVersionChecker.TUNER_VERSION_1_1,
                     "unlinkFrontendToCiCam")) {
@@ -1591,6 +1618,10 @@
             if (mFrontend == null) {
                 throw new IllegalStateException("frontend is not initialized");
             }
+            if (mFeOwnerTuner != null) {
+                Log.d(TAG, "Operation cannot be done by sharee of tuner");
+                return RESULT_INVALID_STATE;
+            }
             return nativeRemoveOutputPid(pid);
         } finally {
             mFrontendLock.unlock();
@@ -1621,6 +1652,9 @@
             if (mFrontend == null) {
                 throw new IllegalStateException("frontend is not initialized");
             }
+            if (mFeOwnerTuner != null) {
+                throw new IllegalStateException("Operation cannot be done by sharee of tuner");
+            }
             FrontendStatusReadiness[] readiness = nativeGetFrontendStatusReadiness(statusTypes);
             if (readiness == null) {
                 return Collections.EMPTY_LIST;
@@ -1697,6 +1731,9 @@
             if (mFrontend == null) {
                 throw new IllegalStateException("frontend is not initialized");
             }
+            if (mFeOwnerTuner != null) {
+                throw new IllegalStateException("Operation cannot be done by sharee of tuner");
+            }
             return nativeGetFrontendHardwareInfo();
         } finally {
             mFrontendLock.unlock();
@@ -1726,6 +1763,10 @@
         if (maxNumber < 0) {
             return RESULT_INVALID_ARGUMENT;
         }
+        if (mFeOwnerTuner != null) {
+            Log.d(TAG, "Operation cannot be done by sharee of tuner");
+            return RESULT_INVALID_STATE;
+        }
         int res = nativeSetMaxNumberOfFrontends(frontendType, maxNumber);
         if (res == RESULT_SUCCESS) {
             if (!mTunerResourceManager.setMaxNumberOfFrontends(frontendType, maxNumber)) {
diff --git a/native/android/system_fonts.cpp b/native/android/system_fonts.cpp
index 9fe7929..4df745f 100644
--- a/native/android/system_fonts.cpp
+++ b/native/android/system_fonts.cpp
@@ -248,9 +248,10 @@
     minikin::SystemFonts::getFontMap(
             [&fonts](const std::vector<std::shared_ptr<minikin::FontCollection>>& collections) {
                 for (const auto& fc : collections) {
-                    for (const auto& family : fc->getFamilies()) {
-                        for (uint32_t i = 0; i < family->getNumFonts(); ++i) {
-                            const minikin::Font* font = family->getFont(i);
+                    for (uint32_t i = 0; i < fc->getFamilyCount(); ++i) {
+                        const auto& family = fc->getFamilyAt(i);
+                        for (uint32_t j = 0; j < family->getNumFonts(); ++j) {
+                            const minikin::Font* font = family->getFont(j);
 
                             std::optional<std::string> locale;
                             uint32_t localeId = font->getLocaleListId();
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedBackupTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedBackupTaskTest.java
index f6914ef..23d6e34 100644
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedBackupTaskTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedBackupTaskTest.java
@@ -22,8 +22,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupTaskTest.java
index 096b2da..bfc5d0d 100644
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupTaskTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupTaskTest.java
@@ -18,9 +18,9 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertThrows;
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTaskTest.java
index fa4fef5..222b882 100644
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTaskTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTaskTest.java
@@ -19,8 +19,8 @@
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertFalse;
@@ -41,13 +41,6 @@
 import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
 import com.android.server.backup.testing.CryptoTestUtils;
 
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import javax.crypto.SecretKey;
-
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -59,6 +52,14 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.crypto.SecretKey;
+
+
 @RunWith(RobolectricTestRunner.class)
 public class EncryptedKvBackupTaskTest {
     private static final boolean INCREMENTAL = true;
diff --git a/packages/CompanionDeviceManager/res/values-af/strings.xml b/packages/CompanionDeviceManager/res/values-af/strings.xml
index 03d8d50..f51266c 100644
--- a/packages/CompanionDeviceManager/res/values-af/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-af/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Stroom jou foon se programme"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Gee &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang tot hierdie inligting op jou foon"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Oorkruistoestel-dienste"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toegang tot jou foon se foto\'s, media en kennisgewings"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om programme tussen jou toestelle te stroom"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Gee &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang tot hierdie inligting op jou foon"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Foto\'s en media"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Dienste"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om programme tussen jou toestelle te stroom"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toegang tot jou foon se foto\'s, media en kennisgewings"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"toestel"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Laat toe"</string>
diff --git a/packages/CompanionDeviceManager/res/values-am/strings.xml b/packages/CompanionDeviceManager/res/values-am/strings.xml
index 2b106bc..b84ba92 100644
--- a/packages/CompanionDeviceManager/res/values-am/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-am/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"የስልክዎን መተግበሪያዎች በዥረት ይልቀቁ"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ይህን መረጃ ከስልክዎ እንዲደርስበት ይፍቀዱለት"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"መሣሪያ ተሻጋሪ አገልግሎቶች"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> የእርስዎን ስልክ ፎቶዎች፣ ሚዲያ እና ማሳወቂያዎች ለመድረስ የእርስዎን <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ወክሎ ፈቃድ እየጠየቀ ነው"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ይህን መረጃ ከስልክዎ ላይ እንዲደርስ ይፍቀዱለት"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"ፎቶዎች እና ሚዲያ"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"የGoogle Play አገልግሎቶች"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> በእርስዎ መሣሪያዎች መካከል መተግበሪያዎችን በዥረት ለመልቀቅ የእርስዎን <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ወክሎ ፈቃድ እየጠየቀ ነው"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"መሣሪያ"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"ፍቀድ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml
index d69ec1b..7c2f0ff 100644
--- a/packages/CompanionDeviceManager/res/values-ar/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"بث تطبيقات هاتفك"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"‏السماح لتطبيق &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; بالوصول إلى هذه المعلومات من هاتفك"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"الخدمات التي تعمل بين الأجهزة"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"تطلب \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" الحصول على إذن نيابةً عن <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> للوصول إلى الصور والوسائط والإشعارات في هاتفك."</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"‏السماح لتطبيق &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; بالوصول إلى هذه المعلومات من هاتفك"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"الصور والوسائط"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"‏خدمات Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"يطلب التطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> الحصول على إذن نيابةً عن <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> لمشاركة التطبيقات بين أجهزتك."</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"جهاز"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"السماح"</string>
diff --git a/packages/CompanionDeviceManager/res/values-as/strings.xml b/packages/CompanionDeviceManager/res/values-as/strings.xml
index fcdd8cd..e79780c 100644
--- a/packages/CompanionDeviceManager/res/values-as/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-as/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"আপোনাৰ ফ’নৰ এপ্‌ ষ্ট্ৰীম কৰক"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ক আপোনাৰ ফ’নৰ পৰা এই তথ্যখিনি এক্সেছ কৰাৰ অনুমতি দিয়ক"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"ক্ৰছ-ডিভাইচ সেৱাসমূহ"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ আপোনৰ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>ৰ হৈ আপোনাৰ ফ’নৰ ফট’, মিডিয়া আৰু জাননী এক্সেছ কৰাৰ বাবে অনুৰোধ জনাইছে"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ক আপোনাৰ ফ’নৰ পৰা এই তথ্যখিনি এক্সেছ কৰাৰ অনুমতি দিয়ক"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"ফট’ আৰু মিডিয়া"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play সেৱা"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ আপোনৰ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>ৰ হৈ আপোনাৰ ডিভাইচসমূহৰ মাজত এপ্‌ ষ্ট্ৰীম কৰাৰ বাবে অনুৰোধ জনাইছে"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইচ"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"অনুমতি দিয়ক"</string>
diff --git a/packages/CompanionDeviceManager/res/values-az/strings.xml b/packages/CompanionDeviceManager/res/values-az/strings.xml
index e8c11e8..4ef3111 100644
--- a/packages/CompanionDeviceManager/res/values-az/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-az/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Telefonunuzun tətbiqlərini yayımlayın"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tətbiqinə telefonunuzdan bu məlumata giriş icazəsi verin"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cihazlararası xidmətlər"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> adından telefonunuzun fotoları, mediası və bildirişlərinə giriş üçün icazə istəyir"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> adından cihazlarınız arasında tətbiqləri yayımlamaq üçün icazə istəyir"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tətbiqinə telefonunuzdan bu məlumata giriş icazəsi verin"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Foto və media"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play xidmətləri"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> adından cihazlarınız arasında tətbiqləri yayımlamaq üçün icazə istəyir"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> adından telefonunuzun fotoları, mediası və bildirişlərinə giriş üçün icazə istəyir"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"İcazə verin"</string>
diff --git a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
index 37f96c3..baf55d2 100644
--- a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Strimujte aplikacije na telefonu"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pristupa ovim informacijama sa telefona"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluge na više uređaja"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za pristup slikama, medijskom sadržaju i obaveštenjima sa telefona"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za strimovanje aplikacija između uređaja"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Dozvolite da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pristupa ovim informacijama sa telefona"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Slike i mediji"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play usluge"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za strimovanje aplikacija između uređaja"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za pristup slikama, medijskom sadržaju i obaveštenjima sa telefona"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Dozvoli"</string>
diff --git a/packages/CompanionDeviceManager/res/values-be/strings.xml b/packages/CompanionDeviceManager/res/values-be/strings.xml
index 559fa94..cab8068 100644
--- a/packages/CompanionDeviceManager/res/values-be/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-be/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Трансліруйце змесціва праграм з вашага тэлефона"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Дазвольце праграме &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; мець доступ да гэтай інфармацыі з вашага тэлефона"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Сэрвісы для некалькіх прылад"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запытвае дазвол ад імя вашай прылады \"<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>\" на доступ да фота, медыяфайлаў і апавяшчэнняў вашага тэлефона"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Дазвольце праграме &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; мець доступ да гэтай інфармацыі з вашага тэлефона"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Фота і медыяфайлы"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Сэрвісы Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запытвае дазвол ад імя вашай прылады \"<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>\" на перадачу праграм плынню паміж вашымі прыладамі"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"прылада"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Дазволіць"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml
index 5e34bc7..16a7853 100644
--- a/packages/CompanionDeviceManager/res/values-bg/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Поточно предаване на приложенията на телефона ви"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Разрешете на &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да осъществява достъп до тази информация от телефона ви"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуги за различни устройства"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ иска разрешение от името на <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за достъп до снимките, мултимедията и известията на телефона ви"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Разрешете на &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да осъществява достъп до тази информация от телефона ви"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Снимки и мултимедия"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Услуги за Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> иска разрешение от името на <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> да предава поточно приложения между устройствата ви"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Разрешаване"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml
index 381d510..b9b130f 100644
--- a/packages/CompanionDeviceManager/res/values-bn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"আপনার ফোনের অ্যাপ স্ট্রিমিংয়ের মাধ্যমে কাস্ট করুন"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"আপনার ফোন থেকে &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; অ্যাপকে এই তথ্য অ্যাক্সেস করার অনুমতি দিন"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"ক্রস-ডিভাইস পরিষেবা"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"আপনার ফোনের ফটো, মিডিয়া এবং তথ্য অ্যাক্সেস করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-এর হয়ে অনুমতি চাইছে"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"আপনার ফোন থেকে &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;-কে এই তথ্য অ্যাক্সেস করার অনুমতি দিন"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"ফটো ও মিডিয়া"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play পরিষেবা"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"আপনার ডিভাইসগুলির মধ্যে অ্যাপ স্ট্রিম করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-এর হয়ে অনুমতি চাইছে"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইস"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"অনুমতি দিন"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml
index 5c57571..8c941ac 100644
--- a/packages/CompanionDeviceManager/res/values-bs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Prenosite aplikacije s telefona"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pristupa ovim informacijama s telefona"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluga na više uređaja"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> zahtijeva odobrenje da pristupi fotografijama, medijima i odobrenjima na vašem telefonu"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> zahtijeva odobrenje da prenosi aplikacije između vaših uređaja"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Dozvolite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da pristupa ovim informacijama s vašeg telefona"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Fotografije i mediji"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play usluge"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> zahtijeva odobrenje da prenosi aplikacije između vaših uređaja"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> zahtijeva odobrenje da pristupi fotografijama, medijima i odobrenjima na vašem telefonu"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Dozvoli"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ca/strings.xml b/packages/CompanionDeviceManager/res/values-ca/strings.xml
index 80665cc..eee184c 100644
--- a/packages/CompanionDeviceManager/res/values-ca/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Reprodueix en continu aplicacions del telèfon"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Permet que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; accedeixi a aquesta informació del telèfon"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Serveis multidispositiu"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu dispositiu (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) per accedir a les fotos, el contingut multimèdia i les notificacions del telèfon"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Permet que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; accedeixi a aquesta informació del telèfon"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Fotos i contingut multimèdia"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Serveis de Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu dispositiu (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) per reproduir en continu aplicacions entre els dispositius"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositiu"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Permet"</string>
diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml
index ac4dadc..aff0cda 100644
--- a/packages/CompanionDeviceManager/res/values-cs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Streamujte aplikace v telefonu"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Povolte aplikaci &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; přístup k těmto informacím z vašeho telefonu"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Služby pro více zařízení"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> požaduje za vaše zařízení <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> oprávnění k přístupu k fotkám, médiím a oznámením v telefonu"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Povolte aplikaci &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; přístup k těmto informacím z vašeho telefonu"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Fotky a média"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Služby Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> požaduje za vaše zařízení <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> oprávnění ke streamování aplikací mezi zařízeními"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"zařízení"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Povolit"</string>
diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml
index 0e7a5b7..a043978 100644
--- a/packages/CompanionDeviceManager/res/values-da/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-da/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Stream din telefons apps"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Giv &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; adgang til disse oplysninger fra din telefon"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjenester, som kan tilsluttes en anden enhed"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til at få adgang til din telefons billeder, medier og notifikationer"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til at streame apps mellem dine enheder"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Tillad, at &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; får adgang til disse oplysninger fra din telefon"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Billeder og medier"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjenester"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til at streame apps mellem dine enheder"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til at få adgang til din telefons billeder, medier og notifikationer"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"enhed"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Tillad"</string>
diff --git a/packages/CompanionDeviceManager/res/values-de/strings.xml b/packages/CompanionDeviceManager/res/values-de/strings.xml
index 8fed026..a136841 100644
--- a/packages/CompanionDeviceManager/res/values-de/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-de/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Smartphone-Apps streamen"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; Zugriff auf diese Informationen von deinem Smartphone gewähren"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Geräteübergreifende Dienste"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet im Namen deines <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> um die Berechtigung zum Zugriff auf die Fotos, Medien und Benachrichtigungen deines Smartphones"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; Zugriff auf diese Informationen von deinem Smartphone gewähren"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Fotos und Medien"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play-Dienste"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet im Namen deines <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> um die Berechtigung zum Streamen von Apps zwischen deinen Geräten"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"Gerät"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Zulassen"</string>
diff --git a/packages/CompanionDeviceManager/res/values-el/strings.xml b/packages/CompanionDeviceManager/res/values-el/strings.xml
index 9f3b2ac..56d7dcd 100644
--- a/packages/CompanionDeviceManager/res/values-el/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-el/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Μεταδώστε σε ροή τις εφαρμογές του τηλεφώνου σας"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Να επιτρέπεται στο &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; η πρόσβαση σε αυτές τις πληροφορίες από το τηλέφωνό σας."</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Υπηρεσίες πολλών συσκευών"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> άδεια για πρόσβαση στις φωτογραφίες, τα αρχεία μέσων και τις ειδοποιήσεις του τηλεφώνου σας"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> άδεια για ροή εφαρμογών μεταξύ των συσκευών σας"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Επιτρέψτε στην εφαρμογή &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; να έχει πρόσβαση σε αυτές τις πληροφορίες από το τηλέφωνό σας"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Φωτογραφίες και μέσα"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Υπηρεσίες Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> άδεια για ροή εφαρμογών μεταξύ των συσκευών σας"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> άδεια για πρόσβαση στις φωτογραφίες, τα αρχεία μέσων και τις ειδοποιήσεις του τηλεφώνου σας"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"συσκευή"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Να επιτρέπεται"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
index 85a3275..c80620e 100644
--- a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
index 85a3275..c80620e 100644
--- a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
index 85a3275..c80620e 100644
--- a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
index 85a3275..c80620e 100644
--- a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
index e95cc0d..1b8833b 100644
--- a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‎‏‎‏‏‎‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‏‎‎‏‎‎‏‏‏‎Stream your phone’s apps‎‏‎‎‏‎"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‏‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎Allow &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt; to access this information from your phone‎‏‎‎‏‎"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‏‏‏‎‏‏‏‎‎‎‎‎‏‎‏‎‏‎‏‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‎‏‎‏‏‏‏‎‎‏‎‏‎Cross-device services‎‏‎‎‏‎"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‎‏‏‎‎‎‎‎‏‎‎‏‎‏‏‎‏‎‏‎‏‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‏‎‏‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is requesting permission on behalf of your ‎‏‎‎‏‏‎<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>‎‏‎‎‏‏‏‎ to access your phone’s photos, media, and notifications‎‏‎‎‏‎"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‎‎‏‏‏‏‎‎‏‎‎‎‎‎‏‏‎‏‏‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is requesting permission on behalf of your ‎‏‎‎‏‏‎<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>‎‏‎‎‏‏‏‎ to stream apps between your devices‎‏‎‎‏‎"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‎‎‏‎‏‎Allow &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt; to access this information from your phone‎‏‎‎‏‎"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‏‏‎‎‎‎‏‎‏‎‏‎‏‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‏‎‎‎‎‏‎‏‎‏‏‏‎Photos and media‎‏‎‎‏‎"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‎‏‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎Google Play services‎‏‎‎‏‎"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‎‎‎‏‏‏‏‎‎‏‎‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is requesting permission on behalf of your ‎‏‎‎‏‏‎<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>‎‏‎‎‏‏‏‎ to stream apps between your devices‎‏‎‎‏‎"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‎‏‎‎‎‏‎‎‎‏‎‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‎‏‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is requesting permission on behalf of your ‎‏‎‎‏‏‎<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>‎‏‎‎‏‏‏‎ to access your phone’s photos, media, and notifications‎‏‎‎‏‎"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎device‎‏‎‎‏‎"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‎‏‎‏‏‏‏‎‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‎‎Allow‎‏‎‎‏‎"</string>
diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
index 4797315..6bf4f6f 100644
--- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Transmitir las apps de tu teléfono"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Permite que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información de tu teléfono"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicios multidispositivo"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicita tu permiso en nombre de <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acceder a las fotos, el contenido multimedia y las notificaciones de tu teléfono"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Permite que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información de tu teléfono"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Fotos y contenido multimedia"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Servicios de Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicita tu permiso en nombre de <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para transmitir apps entre dispositivos"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-es/strings.xml b/packages/CompanionDeviceManager/res/values-es/strings.xml
index 7233e56..a8c6be3 100644
--- a/packages/CompanionDeviceManager/res/values-es/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Emite las aplicaciones de tu teléfono"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información desde tu teléfono"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicios multidispositivo"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pidiendo permiso en nombre de tu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acceder a las fotos, los archivos multimedia y las notificaciones de tu teléfono"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información desde tu teléfono"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Fotos y elementos multimedia"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Servicios de Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pidiendo permiso en nombre de tu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para emitir aplicaciones en otros dispositivos tuyos"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml
index 8dcf60a..e56b623 100644
--- a/packages/CompanionDeviceManager/res/values-et/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-et/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Telefoni rakenduste voogesitamine"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Lubage rakendusel &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pääseda teie telefonis juurde sellele teabele"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Seadmeülesed teenused"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotlevad teie seadme <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nimel luba pääseda juurde telefoni fotodele, meediale ja märguannetele"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Lubage rakendusel &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pääseda teie telefonis juurde sellele teabele"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Fotod ja meedia"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play teenused"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nimel luba teie seadmete vahel rakendusi voogesitada"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"seade"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Luba"</string>
diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml
index 0db66f4..31ebe97 100644
--- a/packages/CompanionDeviceManager/res/values-eu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Igorri zuzenean telefonoko aplikazioak"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Eman informazioa telefonotik hartzeko baimena &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioari"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Gailu baterako baino gehiagotarako zerbitzuak"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Telefonoko argazkiak, multimedia-edukia eta jakinarazpenak atzitzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> gailuaren izenean"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Eman informazio hori telefonotik hartzeko baimena &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioari"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Argazkiak eta multimedia-edukia"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"Gailu batetik bestera aplikazioak igortzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> gailuaren izenean"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"gailua"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Eman baimena"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml
index 4e500cc..09fd7e4 100644
--- a/packages/CompanionDeviceManager/res/values-fa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"جاری‌سازی برنامه‌های تلفن"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"‏اجازه دادن به &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; برای دسترسی به اطلاعات تلفن"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"سرویس‌های بین‌دستگاهی"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> اجازه می‌خواهد ازطرف <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> به عکس‌ها، رسانه، و اعلان‌های تلفن شما دسترسی پیدا کند"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"‏&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; مجاز می‌شود به این اطلاعات در دستگاهتان دسترسی پیدا کند"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"عکس‌ها و رسانه‌ها"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"‏خدمات Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> اجازه می‌خواهد ازطرف <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> برنامه‌ها را بین دستگاه‌های شما جاری‌سازی کند"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"دستگاه"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"اجازه دادن"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml
index bb4e9a5..6f44de6 100644
--- a/packages/CompanionDeviceManager/res/values-fi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Striimaa puhelimen sovelluksia"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Salli, että &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; saa pääsyn näihin puhelimesi tietoihin"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Laitteidenväliset palvelut"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteeltasi (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) lupaa päästä puhelimesi kuviin, mediaan ja ilmoituksiin"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Salli pääsy tähän tietoon puhelimellasi: &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Kuvat ja media"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Palvelut"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteeltasi (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) lupaa striimata sovelluksia laitteidesi välillä"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"laite"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Salli"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
index c6696d5..a10136bd 100644
--- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Diffusez les applications de votre téléphone"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Autorisez &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à ces informations à partir de votre téléphone"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Services multiappareils"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour accéder aux photos, aux fichiers multimédias et aux notifications de votre téléphone"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Autorisez &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à ces informations à partir de votre téléphone"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Photos et fichiers multimédias"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Services Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour diffuser des applications entre vos appareils"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml
index 6d0e2d3..836d562 100644
--- a/packages/CompanionDeviceManager/res/values-fr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Diffuser en streaming les applis de votre téléphone"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à ces informations depuis votre téléphone"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Services inter-appareils"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour accéder aux photos, contenus multimédias et notifications de votre téléphone"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à ces informations depuis votre téléphone"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Photos et contenus multimédias"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Services Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour caster des applis d\'un appareil à l\'autre"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml
index 8eae0cb..48110c4 100644
--- a/packages/CompanionDeviceManager/res/values-gl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Emite as aplicacións do teu teléfono"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Permitir que a aplicación &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información desde o teu teléfono"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servizos multidispositivo"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nome do teu dispositivo (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) para acceder ás fotos, ao contido multimedia e ás notificacións do teléfono"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información desde o teu teléfono"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Fotos e contido multimedia"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Servizos de Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nome do teu dispositivo (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) para emitir aplicacións entre os teus aparellos"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-gu/strings.xml b/packages/CompanionDeviceManager/res/values-gu/strings.xml
index 1186edd..2f552ad 100644
--- a/packages/CompanionDeviceManager/res/values-gu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gu/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"તમારા ફોનની ઍપ સ્ટ્રીમ કરો"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"તમારા ફોનમાંથી આ માહિતી ઍક્સેસ કરવા માટે, &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ને મંજૂરી આપો"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"ક્રોસ-ડિવાઇસ સેવાઓ"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> તમારા <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> વતી તમારા ફોનના ફોટા, મીડિયા અને નોટિફિકેશન ઍક્સેસ કરવાની પરવાનગીની વિનંતી કરી રહી છે"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"તમારા ફોનમાંથી આ માહિતી ઍક્સેસ કરવા માટે, &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ને મંજૂરી આપો"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"ફોટા અને મીડિયા"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play સેવાઓ"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> તમારા <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> વતી તમારા ડિવાઇસ વચ્ચે ઍપ સ્ટ્રીમ કરવાની પરવાનગીની વિનંતી કરી રહી છે"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"ડિવાઇસ"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"મંજૂરી આપો"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml
index a8c6c6f..e49b653 100644
--- a/packages/CompanionDeviceManager/res/values-hi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"अपने फ़ोन के ऐप्लिकेशन को स्ट्रीम करें"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; को अपने फ़ोन से यह जानकारी ऐक्सेस करने की अनुमति दें"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रॉस-डिवाइस से जुड़ी सेवाएं"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> की ओर से, फ़ोन में मौजूद फ़ोटो, मीडिया, और सूचनाओं को ऐक्सेस करने की अनुमति मांग रही हैं"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; को अपने फ़ोन से यह जानकारी ऐक्सेस करने की अनुमति दें"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"फ़ोटो और मीडिया"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play सेवाएं"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> की ओर से, डिवाइसों के बीच ऐप्लिकेशन को स्ट्रीम करने की अनुमति मांग रहा है"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"डिवाइस"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"अनुमति दें"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml
index 224bf69..0c6d3a2 100644
--- a/packages/CompanionDeviceManager/res/values-hr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Streaming aplikacija vašeg telefona"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Omogućite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da pristupa informacijama s vašeg telefona"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluge na različitim uređajima"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> da pristupi fotografijama, medijskim sadržajima i obavijestima na telefonu"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za emitiranje aplikacija između vaših uređaja"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Omogućite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da pristupa informacijama s vašeg telefona"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Fotografije i mediji"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Usluge za Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za streamanje aplikacija između vaših uređaja"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za pristup fotografijama, medijskim sadržajima i obavijestima na telefonu"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Dopusti"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml
index b06e289..b39854a 100644
--- a/packages/CompanionDeviceManager/res/values-hu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"A telefon alkalmazásainak streamelése"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Engedélyezi a(z) „<xliff:g id="APP_NAME">%1$s</xliff:g>” alkalmazás számára az információhoz való hozzáférést a telefonról"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Többeszközös szolgáltatások"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> engedélyt kér a(z) <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nevében a telefonon tárolt fotókhoz, médiatartalmakhoz és értesítésekhez való hozzáféréshez"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Engedélyezi a(z) „<xliff:g id="APP_NAME">%1$s</xliff:g>” alkalmazás számára az információhoz való hozzáférést a telefonról"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Fotók és médiatartalmak"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play-szolgáltatások"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> engedélyt kér a(z) <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nevében az alkalmazások eszközök közötti streameléséhez"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"eszköz"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Engedélyezés"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml
index 1fe3331..dfd18e4 100644
--- a/packages/CompanionDeviceManager/res/values-hy/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Հեռարձակել հեռախոսի հավելվածները"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Թույլատրեք &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; հավելվածին օգտագործել այս տեղեկությունները ձեր հեռախոսից"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Միջսարքային ծառայություններ"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ ձեր հեռախոսի լուսանկարները, մեդիաֆայլերն ու ծանուցումները տեսնելու համար"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Թույլատրեք &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; հավելվածին օգտագործել այս տեղեկությունները ձեր հեռախոսից"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Լուսանկարներ և մուլտիմեդիա"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play ծառայություններ"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ ձեր սարքերի միջև հավելվածներ հեռարձակելու համար"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"սարք"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Թույլատրել"</string>
diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml
index 2ee559d..86c678e 100644
--- a/packages/CompanionDeviceManager/res/values-in/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-in/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Streaming aplikasi ponsel"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Izinkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; untuk mengakses informasi ini dari ponsel Anda"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Layanan lintas perangkat"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> untuk mengakses foto, media, dan notifikasi ponsel Anda"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Izinkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; mengakses informasi ini dari ponsel Anda"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Foto dan media"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Layanan Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> untuk menstreaming aplikasi di antara perangkat Anda"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"perangkat"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Izinkan"</string>
diff --git a/packages/CompanionDeviceManager/res/values-is/strings.xml b/packages/CompanionDeviceManager/res/values-is/strings.xml
index f694d0f..cf622e6 100644
--- a/packages/CompanionDeviceManager/res/values-is/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-is/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Streymdu forritum símans"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Veita &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aðgang að þessum upplýsingum úr símanum þínum"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Þjónustur á milli tækja"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> sendir beiðni um aðgang að myndum, margmiðlunarefni og tilkynningum símans þíns fyrir hönd <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Veita &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aðgang að þessum upplýsingum úr símanum þínum"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Myndir og efni"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Þjónusta Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> sendir beiðni um heimild fyrir straumspilun forrita á milli tækjanna þinna fyrir hönd <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"tæki"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Leyfa"</string>
diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml
index 3997a6e..baaf53e 100644
--- a/packages/CompanionDeviceManager/res/values-it/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-it/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Trasmetti in streaming le app del tuo telefono"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Consenti a &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; di accedere a queste informazioni dal tuo telefono"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servizi cross-device"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> richiede per conto del tuo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> l\'autorizzazione ad accedere a foto, contenuti multimediali e notifiche del telefono"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Consenti a &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; di accedere a questa informazione dal tuo telefono"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Foto e contenuti multimediali"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> richiede per conto del tuo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> l\'autorizzazione a trasmettere app in streaming tra i dispositivi"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Consenti"</string>
diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml
index 00b732a..b414125 100644
--- a/packages/CompanionDeviceManager/res/values-iw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"שידור אפליקציות מהטלפון"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"‏מתן אישור לאפליקציה &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; לגשת למידע הזה מהטלפון שלך"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"שירותים למספר מכשירים"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור ה‑<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> כדי לגשת לתמונות, למדיה ולהתראות בטלפון שלך"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור מכשיר <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> כדי לשדר אפליקציות בין המכשירים שלך"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"‏מתן אישור לאפליקציה &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; לגשת למידע הזה מהטלפון שלך"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"תמונות ומדיה"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור ה‑<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> כדי לשדר אפליקציות בין המכשירים שלך"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור מכשיר <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> כדי לגשת לתמונות, למדיה ולהתראות בטלפון שלך"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"מכשיר"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"יש אישור"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ja/strings.xml b/packages/CompanionDeviceManager/res/values-ja/strings.xml
index c281063..cf25568 100644
--- a/packages/CompanionDeviceManager/res/values-ja/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ja/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="4470785958457506021">"コンパニオン デバイス マネージャ"</string>
+    <string name="app_label" msgid="4470785958457506021">"コンパニオン デバイス マネージャー"</string>
     <string name="confirmation_title" msgid="3785000297483688997">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; に &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; へのアクセスを許可"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ウォッチ"</string>
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; の管理対象となる<xliff:g id="PROFILE_NAME">%1$s</xliff:g>の選択"</string>
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"スマートフォンのアプリのストリーミング"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"スマートフォンのこの情報へのアクセスを &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; に許可"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"クロスデバイス サービス"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> が <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> に代わってスマートフォンの写真、メディア、通知にアクセスする権限をリクエストしています"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"このスマートフォンからの情報へのアクセスを &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; に許可"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"写真とメディア"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play 開発者サービス"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> が <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> に代わってデバイス間でアプリをストリーミングする権限をリクエストしています"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"デバイス"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"許可"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml
index 7db3d0c..514cefe 100644
--- a/packages/CompanionDeviceManager/res/values-ka/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ka/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"თქვენი ტელეფონის აპების სტრიმინგი"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"ნება დართეთ, რომ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; აპს ჰქონდეს ამ ინფორმაციაზე წვდომა თქვენი ტელეფონიდან"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"მოწყობილობათშორისი სერვისები"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ითხოვს უფლებას თქვენი <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-ის სახელით, რომ წვდომა ჰქონდეს თქვენი ტელეფონის ფოტოებზე, მედიასა და შეტყობინებებზე"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"ნება დართეთ, რომ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; აპს ჰქონდეს ამ ინფორმაციაზე წვდომა თქვენი ტელეფონიდან"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"ფოტოები და მედია"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ითხოვს უფლებას თქვენი <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-ის სახელით, რომ მოწყობილობებს შორის სტრიმინგი შეძლოს"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"მოწყობილობა"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"დაშვება"</string>
diff --git a/packages/CompanionDeviceManager/res/values-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml
index 58a625c..e4027de 100644
--- a/packages/CompanionDeviceManager/res/values-kk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kk/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Телефон қолданбаларын трансляциялайды."</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; қолданбасына телефоныңыздағы осы ақпаратты пайдалануға рұқсат беріңіз."</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Аралық құрылғы қызметтері"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> атынан телефондағы фотосуреттерді, медиафайлдар мен хабарландыруларды пайдалану үшін рұқсат сұрайды."</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; қолданбасына телефоныңыздағы осы ақпаратты пайдалануға рұқсат беріңіз."</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Фотосуреттер мен медиафайлдар"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play қызметтері"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> атынан құрылғылар арасында қолданбалар трансляциялау үшін рұқсат сұрайды."</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"құрылғы"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Рұқсат беру"</string>
diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml
index 7f3b933..a4e5911 100644
--- a/packages/CompanionDeviceManager/res/values-km/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-km/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"ផ្សាយកម្មវិធីរបស់ទូរសព្ទអ្នក"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"អនុញ្ញាតឱ្យ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ចូលប្រើព័ត៌មាននេះពីទូរសព្ទរបស់អ្នក"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"សេវាកម្មឆ្លងកាត់ឧបករណ៍"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងស្នើសុំការអនុញ្ញាតជំនួសឱ្យ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> របស់អ្នក ដើម្បីចូលប្រើរូបថត មេឌៀ និងការជូនដំណឹងរបស់ទូរសព្ទអ្នក"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"អនុញ្ញាតឱ្យ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ចូលមើលព័ត៌មាននេះពីទូរសព្ទរបស់អ្នក"</string>
@@ -35,11 +36,12 @@
     <string name="permission_storage" msgid="6831099350839392343">"រូបថត និងមេឌៀ"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"សេវាកម្ម Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងស្នើសុំការអនុញ្ញាតជំនួសឱ្យ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> របស់អ្នក ដើម្បីបញ្ចាំងកម្មវិធីរវាងឧបករណ៍របស់អ្នក"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"ឧបករណ៍"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"អនុញ្ញាត"</string>
-    <string name="consent_no" msgid="2640796915611404382">"កុំអនុញ្ញាត"</string>
+    <string name="consent_no" msgid="2640796915611404382">"មិនអនុញ្ញាត"</string>
     <string name="consent_back" msgid="2560683030046918882">"ថយក្រោយ"</string>
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"ផ្ដល់​ការអនុញ្ញាតឱ្យ​កម្មវិធីនៅលើ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ដូចនៅលើ &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ឬ?"</string>
     <string name="permission_sync_summary" msgid="4866838188678457084">"&lt;p&gt;សកម្មភាពនេះ​អាចរួមបញ្ចូល​ការចូលប្រើ​ទីតាំង កាមេរ៉ា និងមីក្រូហ្វូន និងការអនុញ្ញាត​ដែលមានលក្ខណៈ​រសើបផ្សេងទៀត​នៅលើ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;។&lt;/p&gt; &lt;p&gt;អ្នកអាចប្ដូរ​ការអនុញ្ញាតទាំងនេះ​បានគ្រប់ពេលវេលា​នៅក្នុងការកំណត់​នៅលើ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;។&lt;/p&gt;"</string>
diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml
index e0f2fd5..72d9318 100644
--- a/packages/CompanionDeviceManager/res/values-kn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"ನಿಮ್ಮ ಫೋನ್‍ನ ಆ್ಯಪ್‌ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಿ"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"ನಿಮ್ಮ ಫೋನ್ ಮೂಲಕ ಈ ಮಾಹಿತಿಯನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ಗೆ ಅನುಮತಿಸಿ"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"ಕ್ರಾಸ್-ಡಿವೈಸ್ ಸೇವೆಗಳು"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"ನಿಮ್ಮ ಫೋನ್‌ನ ಫೋಟೋಗಳು, ಮೀಡಿಯಾ ಮತ್ತು ಅಧಿಸೂಚನೆಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ನಿಮ್ಮ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಳ್ಳುತ್ತಿದೆ"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"ನಿಮ್ಮ ಫೋನ್ ಮೂಲಕ ಈ ಮಾಹಿತಿಯನ್ನು ಪ್ರವೇಶಿಸಲು &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ಗೆ ಅನುಮತಿಸಿ"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"ಫೋಟೋಗಳು ಮತ್ತು ಮಾಧ್ಯಮ"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play ಸೇವೆಗಳು"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"ನಿಮ್ಮ ಸಾಧನಗಳ ನಡುವೆ ಆ್ಯಪ್‌ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ನಿಮ್ಮ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಳ್ಳುತ್ತಿದೆ"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"ಸಾಧನ"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"ಅನುಮತಿಸಿ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml
index 99acb18..ed6fc63 100644
--- a/packages/CompanionDeviceManager/res/values-ko/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"휴대전화의 앱을 스트리밍합니다."</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; 앱이 휴대전화에서 이 정보에 액세스하도록 허용합니다."</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"교차 기기 서비스"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 대신 휴대전화의 사진, 미디어, 알림에 액세스할 수 있는 권한을 요청하고 있습니다."</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; 앱이 휴대전화에서 이 정보에 액세스하도록 허용합니다."</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"사진 및 미디어"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play 서비스"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 대신 기기 간에 앱을 스트리밍할 수 있는 권한을 요청하고 있습니다."</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"기기"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"허용"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml
index 63d6fba..63318cb 100644
--- a/packages/CompanionDeviceManager/res/values-ky/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Телефондогу колдонмолорду алып ойнотуу"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; колдонмосуна телефонуңуздагы ушул маалыматты көрүүгө уруксат бериңиз"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Түзмөктөр аралык кызматтар"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> түзмөгүңүздүн атынан телефондогу сүрөттөрдү, медиа файлдарды жана билдирмелерди колдонууга уруксат сурап жатат"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; колдонмосуна телефонуңуздагы ушул маалыматты көрүүгө уруксат бериңиз"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Сүрөттөр жана медиа"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play кызматтары"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> түзмөгүңүздүн атынан түзмөктөрүңүздүн ортосунда колдонмолорду тышкы экранга чыгарууга уруксат сурап жатат"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"түзмөк"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Ооба"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml
index 910a527..af79fab 100644
--- a/packages/CompanionDeviceManager/res/values-lo/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lo/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"ສະຕຣີມແອັບຂອງໂທລະສັບທ່ານ"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"ອະນຸຍາດ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ໃຫ້ເຂົ້າເຖິງຂໍ້ມູນນີ້ຈາກໂທລະສັບຂອງທ່ານໄດ້"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"ບໍລິການຂ້າມອຸປະກອນ"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມຂອງ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ເພື່ອເຂົ້າເຖິງຮູບພາບ, ມີເດຍ ແລະ ການແຈ້ງເຕືອນຂອງໂທລະສັບທ່ານ"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"ອະນຸຍາດ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ໃຫ້ເຂົ້າເຖິງຂໍ້ມູນນີ້ຈາກໂທລະສັບຂອງທ່ານໄດ້"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"ຮູບພາບ ແລະ ມີເດຍ"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"ບໍລິການ Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມຂອງ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ເພື່ອສະຕຣີມແອັບລະຫວ່າງອຸປະກອນຂອງທ່ານ"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"ອຸປະກອນ"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"ອະນຸຍາດ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml
index 5edd78d..f88eba9 100644
--- a/packages/CompanionDeviceManager/res/values-lt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Telefono programų perdavimas srautu"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Leisti &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pasiekti šią informaciją iš jūsų telefono"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Pasl. keliuose įrenginiuose"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ prašo leidimo jūsų „<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>“ vardu, kad galėtų pasiekti telefono nuotraukas, mediją ir pranešimus"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Leisti &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pasiekti šią informaciją iš jūsų telefono"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Nuotraukos ir medija"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"„Google Play“ paslaugos"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ prašo leidimo jūsų „<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>“ vardu, kad galėtų srautu perduoti programas iš vieno įrenginio į kitą"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"įrenginys"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Leisti"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lv/strings.xml b/packages/CompanionDeviceManager/res/values-lv/strings.xml
index 582cf84..f058e54 100644
--- a/packages/CompanionDeviceManager/res/values-lv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Var straumēt jūsu tālruņa lietotnes"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Atļaut lietotnei &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; piekļūt šai informācijai no jūsu tālruņa"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Vairāku ierīču pakalpojumi"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> pieprasa atļauju piekļūt jūsu tālruņa fotoattēliem, multivides saturam un paziņojumiem šīs ierīces vārdā: <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Atļaut lietotnei &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; piekļūt šai informācijai no jūsu tālruņa"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Fotoattēli un multivides faili"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play pakalpojumi"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> pieprasa atļauju straumēt lietotnes starp jūsu ierīcēm šīs ierīces vārdā: <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"ierīce"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Atļaut"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mk/strings.xml b/packages/CompanionDeviceManager/res/values-mk/strings.xml
index 3393f36..23ced12 100644
--- a/packages/CompanionDeviceManager/res/values-mk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mk/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Стримувајте ги апликациите на телефонот"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Овозможете &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да пристапува до овие податоци на телефонот"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Повеќенаменски услуги"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за да пристапува до фотографиите, аудиовизуелните содржини и известувањата на телефонот"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Овозможете &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да пристапува до овие податоци на телефонот"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Аудиовизуелни содржини"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Услуги на Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за да стримува апликации помеѓу вашите уреди"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"уред"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Дозволи"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ml/strings.xml b/packages/CompanionDeviceManager/res/values-ml/strings.xml
index be36c5c..17f3045 100644
--- a/packages/CompanionDeviceManager/res/values-ml/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ml/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"നിങ്ങളുടെ ഫോണിലെ ആപ്പുകൾ സ്‌ട്രീം ചെയ്യാൻ"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"നിങ്ങളുടെ ഫോണിൽ നിന്ന് ഈ വിവരങ്ങൾ ആക്‌സസ് ചെയ്യാൻ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ആപ്പിനെ അനുവദിക്കുക"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"ക്രോസ്-ഉപകരണ സേവനങ്ങൾ"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"നിങ്ങളുടെ ഫോണിലെ ഫോട്ടോകൾ, മീഡിയ, അറിയിപ്പുകൾ എന്നിവ ആക്സസ് ചെയ്യാൻ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ഉപകരണത്തിനു വേണ്ടി <xliff:g id="APP_NAME">%1$s</xliff:g> അനുമതി അഭ്യർത്ഥിക്കുന്നു."</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"നിങ്ങളുടെ ഫോണിൽ നിന്ന് ഈ വിവരങ്ങൾ ആക്‌സസ് ചെയ്യാൻ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ആപ്പിനെ അനുവദിക്കുക"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"ഫോട്ടോകളും മീഡിയയും"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play സേവനങ്ങൾ"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"നിങ്ങളുടെ ഉപകരണങ്ങളിൽ ഒന്നിൽ നിന്ന് അടുത്തതിലേക്ക് ആപ്പുകൾ സ്ട്രീം ചെയ്യാൻ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ഉപകരണത്തിനു വേണ്ടി <xliff:g id="APP_NAME">%1$s</xliff:g> അനുമതി അഭ്യർത്ഥിക്കുന്നു."</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"ഉപകരണം"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"അനുവദിക്കുക"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mn/strings.xml b/packages/CompanionDeviceManager/res/values-mn/strings.xml
index dc52154..1c74e48 100644
--- a/packages/CompanionDeviceManager/res/values-mn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mn/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Таны утасны аппуудыг дамжуулах"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;-д таны утаснаас энэ мэдээлэлд хандахыг зөвшөөрнө үү"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Төхөөрөмж хоорондын үйлчилгээ"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь таны <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-н өмнөөс утасны зураг, медиа болон мэдэгдэлд хандахын тулд зөвшөөрөл хүсэж байна"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"Таны төхөөрөмжүүд хооронд апп дамжуулахын тулд <xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-н өмнөөс зөвшөөрөл хүсэж байна"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;-д таны утаснаас энэ мэдээлэлд хандахыг зөвшөөрнө үү"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Зураг болон медиа"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play үйлчилгээ"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь таны <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-н өмнөөс төхөөрөмж хооронд апп дамжуулахын тулд зөвшөөрөл хүсэж байна"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"Таны утасны зураг, медиа болон мэдэгдэлд хандахын тулд <xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-н өмнөөс зөвшөөрөл хүсэж байна"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"төхөөрөмж"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Зөвшөөрөх"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml
index e5bdfd5..3f83446 100644
--- a/packages/CompanionDeviceManager/res/values-mr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"फोनवरील ॲप्स स्ट्रीम करा"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ला ही माहिती तुमच्या फोनवरून अ‍ॅक्सेस करण्यासाठी अनुमती द्या"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रॉस-डिव्हाइस सेवा"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"तुमच्या फोनमधील फोटो, मीडिया आणि सूचना ॲक्सेस करण्यासाठी <xliff:g id="APP_NAME">%1$s</xliff:g> हे तुमच्या <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> च्या वतीने परवानगीची विनंती करत आहे"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ला ही माहिती तुमच्या फोनवरून अ‍ॅक्सेस करण्यासाठी अनुमती द्या"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"फोटो आणि मीडिया"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play सेवा"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"तुमच्या डिव्हाइसदरम्यान ॲप्स स्ट्रीम करण्यासाठी <xliff:g id="APP_NAME">%1$s</xliff:g> हे तुमच्या <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> च्या वतीने परवानगीची विनंती करत आहे"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"डिव्हाइस"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"अनुमती द्या"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ms/strings.xml b/packages/CompanionDeviceManager/res/values-ms/strings.xml
index 70d0373..bf1b537 100644
--- a/packages/CompanionDeviceManager/res/values-ms/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ms/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Strim apl telefon anda"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Benarkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; mengakses maklumat ini daripada telefon anda"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Perkhidmatan silang peranti"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang meminta kebenaran bagi pihak <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> anda untuk mengakses foto, media dan pemberitahuan telefon anda"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Benarkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; untuk mengakses maklumat ini daripada telefon anda"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Foto dan media"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Perkhidmatan Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang meminta kebenaran bagi pihak <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> anda untuk menstrim apl antara peranti anda"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"peranti"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Benarkan"</string>
diff --git a/packages/CompanionDeviceManager/res/values-my/strings.xml b/packages/CompanionDeviceManager/res/values-my/strings.xml
index e47e834..61272cc 100644
--- a/packages/CompanionDeviceManager/res/values-my/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-my/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"သင့်ဖုန်းရှိအက်ပ်များကို တိုက်ရိုက်လွှင့်နိုင်သည်"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ကို သင့်ဖုန်းမှ ဤအချက်အလက် သုံးခွင့်ပြုမည်"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"စက်များကြားသုံး ဝန်ဆောင်မှုများ"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင့်ဖုန်း၏ ဓာတ်ပုံ၊ မီဒီယာနှင့် အကြောင်းကြားချက်များသုံးရန် သင်၏ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင်၏စက်များအကြား အက်ပ်များတိုက်ရိုက်လွှင့်ရန် <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; အား သင့်ဖုန်းမှ ဤအချက်အလက် သုံးခွင့်ပြုခြင်း"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"ဓာတ်ပုံနှင့် မီဒီယာများ"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play ဝန်ဆောင်မှုများ"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင်၏စက်များအကြား အက်ပ်များတိုက်ရိုက်လွှင့်ရန် သင်၏ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင့်ဖုန်း၏ ဓာတ်ပုံ၊ မီဒီယာနှင့် အကြောင်းကြားချက်များသုံးရန် <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"စက်"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"ခွင့်ပြုရန်"</string>
diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml
index 58d5f23..5a4b911 100644
--- a/packages/CompanionDeviceManager/res/values-nb/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Strøm appene på telefonen"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Gi &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tilgang til denne informasjonen fra telefonen din"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjenester på flere enheter"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse på vegne av <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> for å få tilgang til bilder, medier og varsler på telefonen din"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Gi &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tilgang til denne informasjonen fra telefonen din"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Bilder og medier"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjenester"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse på vegne av <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> for å strømme apper mellom enhetene dine"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Tillat"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ne/strings.xml b/packages/CompanionDeviceManager/res/values-ne/strings.xml
index a056fcc..9184bf5 100644
--- a/packages/CompanionDeviceManager/res/values-ne/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ne/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"आफ्नो फोनका एपहरू प्रयोग गर्नुहोस्"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; लाई तपाईंको फोनमा भएको यो जानकारी हेर्ने तथा प्रयोग गर्ने अनुमति दिनुहोस्"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रस-डिभाइस सेवाहरू"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईंको डिभाइस <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> को तर्फबाट तपाईंको फोनमा भएका फोटो, मिडिया र सूचनाहरू हेर्ने तथा प्रयोग गर्ने अनुमति माग्दै छ"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; लाई तपाईंको फोनमा भएको यो जानकारी हेर्ने तथा प्रयोग गर्ने अनुमति दिनुहोस्"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"फोटो र मिडिया"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईंको डिभाइस <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> को तर्फबाट तपाईंका कुनै एउटा डिभाइसबाट अर्को डिभाइसमा एप स्ट्रिम गर्ने अनुमति माग्दै छ"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"यन्त्र"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"अनुमति दिनुहोस्"</string>
diff --git a/packages/CompanionDeviceManager/res/values-nl/strings.xml b/packages/CompanionDeviceManager/res/values-nl/strings.xml
index a3b4cef..2039ee0 100644
--- a/packages/CompanionDeviceManager/res/values-nl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nl/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"De apps van je telefoon streamen"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang geven tot deze informatie op je telefoon"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device-services"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toegang tot de foto\'s, media en meldingen van je telefoon"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om apps te streamen tussen je apparaten"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang geven tot deze informatie op je telefoon"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Foto\'s en media"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play-services"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om apps te streamen tussen je apparaten"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toegang tot de foto\'s, media en meldingen van je telefoon"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"apparaat"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Toestaan"</string>
diff --git a/packages/CompanionDeviceManager/res/values-or/strings.xml b/packages/CompanionDeviceManager/res/values-or/strings.xml
index 4fe9d0c..f7b22ca 100644
--- a/packages/CompanionDeviceManager/res/values-or/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-or/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"ଆପଣଙ୍କ ଫୋନର ଆପ୍ସକୁ ଷ୍ଟ୍ରିମ କରନ୍ତୁ"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"ଆପଣଙ୍କ ଫୋନରୁ ଏହି ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"କ୍ରସ-ଡିଭାଇସ ସେବାଗୁଡ଼ିକ"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"ଆପଣଙ୍କ ଫୋନର ଫଟୋ, ମିଡିଆ ଏବଂ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"ଆପଣଙ୍କ ଫୋନରୁ ଏହି ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"ଫଟୋ ଏବଂ ମିଡିଆ"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play ସେବାଗୁଡ଼ିକ"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"ଆପଣଙ୍କ ଡିଭାଇସଗୁଡ଼ିକ ମଧ୍ୟରେ ଆପ୍ସକୁ ଷ୍ଟ୍ରିମ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"ଡିଭାଇସ୍"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml
index 5fdcd36..804574c 100644
--- a/packages/CompanionDeviceManager/res/values-pa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"ਆਪਣੇ ਫ਼ੋਨ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰੋ"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਇਸ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"ਕ੍ਰਾਸ-ਡੀਵਾਈਸ ਸੇਵਾਵਾਂ"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਫ਼ੋਨ ਦੀਆਂ ਫ਼ੋਟੋਆਂ, ਮੀਡੀਆ ਅਤੇ ਸੂਚਨਾਵਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਇਸ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"ਫ਼ੋਟੋਆਂ ਅਤੇ ਮੀਡੀਆ"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play ਸੇਵਾਵਾਂ"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸਾਂ ਵਿਚਕਾਰ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"ਡੀਵਾਈਸ"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"ਆਗਿਆ ਦਿਓ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml
index c890fbc..d7fd7b4 100644
--- a/packages/CompanionDeviceManager/res/values-pl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Odtwarzaj strumieniowo aplikacje z telefonu"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Zezwól aplikacji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na dostęp do tych informacji na Twoim telefonie"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Usługi na innym urządzeniu"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> o uprawnienia dotyczące dostępu do zdjęć, multimediów i powiadomień na telefonie"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Zezwól aplikacji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na dostęp do tych informacji na Twoim telefonie"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Zdjęcia i multimedia"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Usługi Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> o uprawnienia dotyczące strumieniowego odtwarzania aplikacji między urządzeniami"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"urządzenie"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Zezwól"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
index 87986f1..82ae48f 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Faça streaming dos apps do seu smartphone"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Permitir que o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse estas informações do smartphone"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone."</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Autorizar que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse estas informações do smartphone"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Fotos e mídia"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone."</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
index 0584694..87eba3d 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Faça stream das apps do telemóvel"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Permita que a app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aceda a estas informações do seu telemóvel"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para aceder às fotos, conteúdo multimédia e notificações do seu telemóvel"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer stream de apps entre os seus dispositivos"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Permita que a app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aceda a estas informações do seu telemóvel"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Fotos e multimédia"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Serviços do Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer stream de apps entre os seus dispositivos"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para aceder às fotos, ao conteúdo multimédia e às notificações do seu telemóvel"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml
index 87986f1..82ae48f 100644
--- a/packages/CompanionDeviceManager/res/values-pt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Faça streaming dos apps do seu smartphone"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Permitir que o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse estas informações do smartphone"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone."</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Autorizar que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse estas informações do smartphone"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Fotos e mídia"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone."</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ro/strings.xml b/packages/CompanionDeviceManager/res/values-ro/strings.xml
index 449dc86..619468e 100644
--- a/packages/CompanionDeviceManager/res/values-ro/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ro/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Să redea în stream aplicațiile telefonului"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Permiteți ca &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; să acceseze aceste informații de pe telefon"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicii pe mai multe dispozitive"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de a accesa fotografiile, conținutul media și notificările de pe telefon"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de a reda în stream aplicații între dispozitivele dvs."</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Permiteți ca &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; să acceseze aceste informații de pe telefon"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Fotografii și media"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Servicii Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de a reda în stream aplicații între dispozitivele dvs."</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de a accesa fotografiile, conținutul media și notificările de pe telefon"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispozitiv"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Permiteți"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml
index b7f0547..dcc9850 100644
--- a/packages/CompanionDeviceManager/res/values-ru/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Трансляция приложений с телефона."</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Разрешите приложению &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; получать эту информацию с вашего телефона"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Сервисы стриминга приложений"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запрашивает разрешение от имени вашего устройства <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>, чтобы получить доступ к фотографиям, медиаконтенту и уведомлениям на телефоне."</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Разрешите приложению &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; получать эту информацию с вашего телефона"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Фотографии и медиафайлы"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Сервисы Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запрашивает доступ от имени вашего устройства <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>, чтобы транслировать приложения между вашими устройствами."</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Разрешить"</string>
diff --git a/packages/CompanionDeviceManager/res/values-si/strings.xml b/packages/CompanionDeviceManager/res/values-si/strings.xml
index 48674b7..bf5361e 100644
--- a/packages/CompanionDeviceManager/res/values-si/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-si/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"ඔබගේ දුරකථනයේ යෙදුම් ප්‍රවාහ කරන්න"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; හට ඔබගේ දුරකථනයෙන් මෙම තොරතුරුවලට ප්‍රවේශ වීමට ඉඩ දෙන්න"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"හරස්-උපාංග සේවා"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබගේ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> වෙනුවෙන් ඔබගේ දුරකථනයෙහි ඡායාරූප, මාධ්‍ය සහ දැනුම්දීම් වෙත ප්‍රවේශ වීමට අවසරය ඉල්ලමින් සිටී"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබගේ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> වෙනුවෙන් ඔබගේ උපාංග අතර යෙදුම් ප්‍රවාහ කිරීමට අවසරය ඉල්ලමින් සිටියි"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; හට ඔබගේ දුරකථනයෙන් මෙම තොරතුරුවලට ප්‍රවේශ වීමට ඉඩ දෙන්න"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"ඡායාරූප සහ මාධ්‍ය"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play සේවා"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබගේ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> වෙනුවෙන් ඔබගේ උපාංග අතර යෙදුම් ප්‍රවාහ කිරීමට අවසරය ඉල්ලමින් සිටී"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබගේ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> වෙනුවෙන් ඔබගේ දුරකථනයෙහි ඡායාරූප, මාධ්‍ය සහ දැනුම්දීම් වෙත ප්‍රවේශ වීමට අවසරය ඉල්ලමින් සිටියි"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"උපාංගය"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"ඉඩ දෙන්න"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sk/strings.xml b/packages/CompanionDeviceManager/res/values-sk/strings.xml
index 5c2ce5c..89ddd79 100644
--- a/packages/CompanionDeviceManager/res/values-sk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sk/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Streamovanie aplikácií v telefóne"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Povoľte aplikácii &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; prístup k týmto informáciám z vášho telefónu"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Služby pre viacero zariadení"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje povolenie na prístup k fotkám, médiám a upozorneniam vášho telefónu v mene tohto zariadenia (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>)"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje povolenie na streamovanie aplikácií medzi vašimi zariadeniami v mene tohto zariadenia (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>)"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Povoľte aplikácii &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; prístup k týmto informáciám z vášho telefónu"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Fotky a médiá"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Služby Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje povolenie na streamovanie aplikácií medzi vašimi zariadeniami v mene tohto zariadenia (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>)"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje povolenie na prístup k fotkám, médiám a upozorneniam vášho telefónu v mene tohto zariadenia (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>)"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"zariadenie"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Povoliť"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml
index 3b31abc..2c4e8ba 100644
--- a/packages/CompanionDeviceManager/res/values-sl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Pretočno predvajanje aplikacij telefona"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Dovolite, da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; dostopa do teh podatkov v vašem telefonu"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Storitve za zunanje naprave"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>« zahteva dovoljenje za dostop do fotografij, predstavnosti in obvestil v telefonu."</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Dovolite, da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; dostopa do teh podatkov v vašem telefonu"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Fotografije in predstavnost"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Storitve Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>« zahteva dovoljenje za pretočno predvajanje aplikacij v vaših napravah."</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"naprava"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Dovoli"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml
index a63eaaa..ae35c02 100644
--- a/packages/CompanionDeviceManager/res/values-sq/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Transmeto aplikacionet e telefonit tënd"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Lejo që &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; të ketë qasje në këtë informacion nga telefoni yt"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Shërbimet mes pajisjeve"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"\"<xliff:g id="APP_NAME">%1$s</xliff:g>\" po kërkon leje në emër të <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> për të marrë qasje te fotografitë, media dhe njoftimet e telefonit tënd"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Lejo që &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; të ketë qasje në këtë informacion nga telefoni yt"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Fotografitë dhe media"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Shërbimet e Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> po kërkon leje në emër të <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> për të transmetuar aplikacione ndërmjet pajisjeve të tua"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"pajisja"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Lejo"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sr/strings.xml b/packages/CompanionDeviceManager/res/values-sr/strings.xml
index 9d39188..0d05e1a 100644
--- a/packages/CompanionDeviceManager/res/values-sr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sr/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Стримујте апликације на телефону"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Дозволите да &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; приступа овим информацијама са телефона"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуге на више уређаја"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за приступ сликама, медијском садржају и обавештењима са телефона"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за стримовање апликација између уређаја"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Дозволите да &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; приступа овим информацијама са телефона"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Слике и медији"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play услуге"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за стримовање апликација између уређаја"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за приступ сликама, медијском садржају и обавештењима са телефона"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"уређај"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Дозволи"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sv/strings.xml b/packages/CompanionDeviceManager/res/values-sv/strings.xml
index 31dd2d8..9282017 100644
--- a/packages/CompanionDeviceManager/res/values-sv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Streama telefonens appar"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Ge &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; åtkomstbehörighet till denna information på telefonen"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjänster för flera enheter"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> begär behörighet att ge <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> åtkomst till foton, mediefiler och aviseringar på telefonen"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Ge &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; åtkomstbehörighet till denna information på telefonen"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Foton och media"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjänster"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> begär behörighet att låta <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> streama appar mellan enheter"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Tillåt"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sw/strings.xml b/packages/CompanionDeviceManager/res/values-sw/strings.xml
index e906dc8..4e281a8 100644
--- a/packages/CompanionDeviceManager/res/values-sw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Tiririsha programu za simu yako"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Ruhusu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ifikie maelezo haya kutoka kwenye simu yako"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Huduma za kifaa kilichounganishwa kwingine"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> inaomba ruhusa kwa niaba ya <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yako ili kufikia picha, maudhui na arifa za simu yako"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Ruhusu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ifikie maelezo haya kutoka kwenye simu yako"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Picha na maudhui"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Huduma za Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> inaomba ruhusa kwa niaba ya <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yako ili kutiririsha programu kati ya vifaa vyako"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"kifaa"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Ruhusu"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml
index 1cba5e8..a7eeae7 100644
--- a/packages/CompanionDeviceManager/res/values-ta/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"உங்கள் மொபைலின் ஆப்ஸை ஸ்ட்ரீம் செய்யலாம்"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"மொபைலில் உள்ள இந்தத் தகவல்களை அணுக, &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ஆப்ஸை அனுமதிக்கவும்"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"பன்முக சாதன சேவைகள்"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"உங்கள் மொபைலில் உள்ள படங்கள், மீடியா, அறிவிப்புகள் ஆகியவற்றை அணுக உங்கள் <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> அனுமதி கோருகிறது"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"உங்கள் மொபைலிலிருந்து இந்தத் தகவலை அணுக &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ஆப்ஸை அனுமதியுங்கள்"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"படங்கள் மற்றும் மீடியா"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play சேவைகள்"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"உங்கள் சாதனங்களுக்கு இடையே ஆப்ஸை ஸ்ட்ரீம் செய்ய உங்கள் <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> அனுமதி கோருகிறது"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"சாதனம்"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"அனுமதி"</string>
diff --git a/packages/CompanionDeviceManager/res/values-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml
index 96e7608..37bfea5 100644
--- a/packages/CompanionDeviceManager/res/values-te/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-te/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"మీ ఫోన్ యాప్‌లను స్ట్రీమ్ చేయండి"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"మీ ఫోన్ నుండి ఈ సమాచారాన్ని యాక్సెస్ చేయడానికి &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; యాప్‌ను అనుమతించండి"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> మీ ఫోన్ ఫోటోలు, మీడియా, నోటిఫికేషన్‌లను యాక్సెస్ చేయడానికి మీ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> తరపున అనుమతిని రిక్వెస్ట్ చేస్తోంది"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"మీ ఫోన్ నుండి ఈ సమాచారాన్ని యాక్సెస్ చేయడానికి &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; యాప్‌ను అనుమతించండి"</string>
@@ -35,10 +36,11 @@
     <string name="permission_storage" msgid="6831099350839392343">"ఫోటోలు, మీడియా"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play సర్వీసులు"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"మీ పరికరాల మధ్య యాప్‌లను స్ట్రీమ్ చేయడానికి <xliff:g id="APP_NAME">%1$s</xliff:g> మీ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> తరపున అనుమతిని రిక్వెస్ట్ చేస్తోంది"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"పరికరం"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
-    <string name="consent_yes" msgid="8344487259618762872">"అనుమతించు"</string>
+    <string name="consent_yes" msgid="8344487259618762872">"అనుమతించండి"</string>
     <string name="consent_no" msgid="2640796915611404382">"అనుమతించవద్దు"</string>
     <string name="consent_back" msgid="2560683030046918882">"వెనుకకు"</string>
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;లోని యాప్‌లకు &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;లో ఉన్న అనుమతులను ఇవ్వాలా?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-th/strings.xml b/packages/CompanionDeviceManager/res/values-th/strings.xml
index d5ba74a..9be0209 100644
--- a/packages/CompanionDeviceManager/res/values-th/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-th/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"สตรีมแอปของโทรศัพท์คุณ"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"อนุญาตให้ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; เข้าถึงข้อมูลนี้จากโทรศัพท์ของคุณ"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"บริการหลายอุปกรณ์"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังขอสิทธิ์ในนามของ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> เพื่อเข้าถึงรูปภาพ สื่อ และการแจ้งเตือนในโทรศัพท์ของคุณ"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"อนุญาตให้ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; เข้าถึงข้อมูลนี้จากโทรศัพท์ของคุณ"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"รูปภาพและสื่อ"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"บริการ Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังขอสิทธิ์ในนามของ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> เพื่อสตรีมแอประหว่างอุปกรณ์ต่างๆ ของคุณ"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"อุปกรณ์"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"อนุญาต"</string>
diff --git a/packages/CompanionDeviceManager/res/values-tl/strings.xml b/packages/CompanionDeviceManager/res/values-tl/strings.xml
index 6376863..e86bc41 100644
--- a/packages/CompanionDeviceManager/res/values-tl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tl/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"I-stream ang mga app ng iyong telepono"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Payagan ang &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na i-access ang impormasyong ito sa iyong telepono"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Mga cross-device na serbisyo"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay humihiling ng pahintulot sa ngalan ng iyong <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para i-access ang mga larawan, media, at notification ng telepono mo"</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay humihiling ng pahintulot sa ngalan ng iyong <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para mag-stream ng mga app sa pagitan ng mga device mo"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Payagan ang &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na i-access ang impormasyon sa iyong telepono"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Mga larawan at media"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Mga serbisyo ng Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay humihiling ng pahintulot sa ngalan ng iyong <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para mag-stream ng mga app sa pagitan ng mga device mo"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay humihiling ng pahintulot sa ngalan ng iyong <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para i-access ang mga larawan, media, at notification ng telepono mo"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Payagan"</string>
diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml
index bba792258..008a02f 100644
--- a/packages/CompanionDeviceManager/res/values-tr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Telefonunuzun uygulamalarını yayınlama"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; uygulamasının, telefonunuzdaki bu bilgilere erişmesine izin verin"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cihazlar arası hizmetler"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g>, telefonunuzdaki fotoğraf, medya ve bildirimlere erişmek için <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> cihazınız adına izin istiyor"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; uygulamasının, telefonunuzdaki bu bilgilere erişmesine izin verin"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Fotoğraflar ve medya"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play hizmetleri"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g>, cihazlarınız arasında uygulama akışı gerçekleştirmek için <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> cihazınız adına izin istiyor"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"İzin ver"</string>
diff --git a/packages/CompanionDeviceManager/res/values-uk/strings.xml b/packages/CompanionDeviceManager/res/values-uk/strings.xml
index 718fad3..062820e 100644
--- a/packages/CompanionDeviceManager/res/values-uk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uk/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Транслювати додатки телефона"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Надайте додатку &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; доступ до цієї інформації з телефона"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Сервіси для кількох пристроїв"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> від імені вашого пристрою <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> запитує дозвіл на доступ до фотографій, медіафайлів і сповіщень вашого телефона"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Надайте пристрою &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; доступ до цієї інформації з телефона"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Фотографії та медіафайли"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Сервіси Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> від імені вашого пристрою <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> запитує дозвіл на трансляцію додатків між вашими пристроями"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"пристрій"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Дозволити"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml
index ef93add..8b6a14a 100644
--- a/packages/CompanionDeviceManager/res/values-ur/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"اپنے فون کی ایپس کی سلسلہ بندی کریں"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"‏‎&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;‎ کو اپنے فون سے ان معلومات تک رسائی حاصل کرنے کی اجازت دیں"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"کراس ڈیوائس سروسز"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ آپ کے <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> کی جانب سے آپ کے فون کی تصاویر، میڈیا اور اطلاعات تک رسائی کی اجازت طلب کر رہی ہے"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"‏اپنے فون سے اس معلومات تک رسائی حاصل Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; کرنے کی اجازت دیں"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"تصاویر اور میڈیا"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"‏Google Play سروسز"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ آپ کے <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> کی جانب سے آپ کے آلات کے درمیان ایپس کی سلسلہ بندی کرنے کی اجازت کی درخواست کر رہی ہے"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"آلہ"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"اجازت دیں"</string>
diff --git a/packages/CompanionDeviceManager/res/values-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml
index 1813857..5c1262c 100644
--- a/packages/CompanionDeviceManager/res/values-uz/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Telefondagi ilovalarni translatsiya qilish"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ilovasiga telefondagi ushbu maʼlumot uchun ruxsat bering"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Qurilmalararo xizmatlar"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Telefoningizdagi rasm, media va bildirishnomalarga kirish uchun <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nomidan ruxsat soʻramoqda"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ilovasiga telefondagi ushbu maʼlumot uchun ruxsat bering"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Suratlar va media"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play xizmatlari"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"Qurilamalararo ilovalar strimingi uchun <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nomidan ruxsat soʻramoqda"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"qurilma"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Ruxsat"</string>
diff --git a/packages/CompanionDeviceManager/res/values-vi/strings.xml b/packages/CompanionDeviceManager/res/values-vi/strings.xml
index 045547b..b29e08c 100644
--- a/packages/CompanionDeviceManager/res/values-vi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-vi/strings.xml
@@ -25,7 +25,7 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Truyền các ứng dụng trên điện thoại của bạn"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Cho phép &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; truy cập vào thông tin này trên điện thoại của bạn"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Dịch vụ trên nhiều thiết bị"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> để truy cập vào ảnh, nội dung nghe nhìn và thông báo trên điện thoại của bạn."</string>
+    <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> để truyền trực tuyến ứng dụng giữa các thiết bị của bạn"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Cho phép &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; truy cập vào thông tin này trên điện thoại của bạn"</string>
@@ -35,7 +35,7 @@
     <string name="permission_storage" msgid="6831099350839392343">"Ảnh và nội dung nghe nhìn"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Dịch vụ Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> để truyền trực tuyến ứng dụng giữa các thiết bị của bạn"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> để truy cập vào ảnh, nội dung nghe nhìn và thông báo trên điện thoại của bạn."</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"thiết bị"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Cho phép"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
index 06a8b3e..7b95bad 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"流式传输手机上的应用"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"允许“<xliff:g id="APP_NAME">%1$s</xliff:g>”&lt;strong&gt;&lt;/strong&gt;访问您手机中的这项信息"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"跨设备服务"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>请求访问您手机上的照片、媒体内容和通知"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"允许 &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; 访问您手机中的这项信息"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"照片和媒体内容"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服务"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>请求在您的设备之间流式传输应用内容"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"设备"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"允许"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
index 6956aff..cb32f8b 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"串流播放手機應用程式內容"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取您手機中的這項資料"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"跨裝置服務"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 要求必要權限,以便存取手機上的相片、媒體和通知"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取您手機中的這項資料"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"相片和媒體"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服務"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 要求必要權限,以便在裝置之間串流應用程式內容"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"允許"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
index 8d4623a..bafeaaf 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"串流傳輸手機應用程式內容"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取手機中的這項資訊"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"跨裝置服務"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表你的「<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>」要求必要權限,以便存取手機上的相片、媒體和通知"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取你手機中的這項資訊"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"相片和媒體"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服務"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表你的「<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>」要求必要權限,以便在裝置之間串流傳輸應用程式內容"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"允許"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zu/strings.xml b/packages/CompanionDeviceManager/res/values-zu/strings.xml
index c669736..e148d0a 100644
--- a/packages/CompanionDeviceManager/res/values-zu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zu/strings.xml
@@ -25,7 +25,8 @@
     <string name="permission_apps_summary" msgid="798718816711515431">"Sakaza ama-app wefoni yakho"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Vumela i-&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ifinyelele lolu lwazi kusukela efonini yakho"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Amasevisi amadivayisi amaningi"</string>
-    <string name="helper_summary_app_streaming" msgid="7380294597268573523">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> icela imvume esikhundleni se-<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yakho ukuze ifinyelele izithombe zefoni yakho, imidiya nezaziso"</string>
+    <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+    <skip />
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"Vumela &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ukufinyelela lolu lwazi kusuka efonini yakho"</string>
@@ -35,7 +36,8 @@
     <string name="permission_storage" msgid="6831099350839392343">"Izithombe nemidiya"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Amasevisi we-Google Play"</string>
-    <string name="helper_summary_computer" msgid="1676407599909474428">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> icela imvume esikhundleni se-<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yakho ukuze isakaze-bukhoma ama-app phakathi kwamadivayisi akho"</string>
+    <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+    <skip />
     <string name="profile_name_generic" msgid="6851028682723034988">"idivayisi"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
     <string name="consent_yes" msgid="8344487259618762872">"Vumela"</string>
diff --git a/packages/CompanionDeviceManager/res/values/strings.xml b/packages/CompanionDeviceManager/res/values/strings.xml
index cea9a68..83dbbf3 100644
--- a/packages/CompanionDeviceManager/res/values/strings.xml
+++ b/packages/CompanionDeviceManager/res/values/strings.xml
@@ -48,7 +48,7 @@
     <string name="helper_title_app_streaming">Cross-device services</string>
 
     <!-- Description of the helper dialog for APP_STREAMING profile. [CHAR LIMIT=NONE] -->
-    <string name="helper_summary_app_streaming"><xliff:g id="app_name" example="GMS">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="device_type" example="Chromebook">%2$s</xliff:g> to access your phone\u2019s photos, media, and notifications</string>
+    <string name="helper_summary_app_streaming"><xliff:g id="app_name" example="GMS">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="device_type" example="Chromebook">%2$s</xliff:g> to stream apps between your devices</string>
 
     <!-- ================= DEVICE_PROFILE_AUTOMOTIVE_PROJECTION ================= -->
 
@@ -82,7 +82,7 @@
     <string name="helper_title_computer">Google Play services</string>
 
     <!-- Description of the helper dialog for COMPUTER profile. [CHAR LIMIT=NONE] -->
-    <string name="helper_summary_computer"> <xliff:g id="app_name" example="GMS">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="device_type" example="Chromebook">%2$s</xliff:g> to stream apps between your devices</string>
+    <string name="helper_summary_computer"><xliff:g id="app_name" example="GMS">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="device_type" example="Chromebook">%2$s</xliff:g> to access your phone\u2019s photos, media, and notifications</string>
 
     <!-- ================= null profile ================= -->
 
diff --git a/packages/DynamicSystemInstallationService/res/values-or/strings.xml b/packages/DynamicSystemInstallationService/res/values-or/strings.xml
index 05b9016..b5ec292 100644
--- a/packages/DynamicSystemInstallationService/res/values-or/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-or/strings.xml
@@ -7,7 +7,7 @@
     <string name="notification_install_failed" msgid="4066039210317521404">"ଇନଷ୍ଟଲ୍ କରିବା ବିଫଳ ହୋଇଛି"</string>
     <string name="notification_image_validation_failed" msgid="2720357826403917016">"ଇମେଜ୍ ବୈଧକରଣ ବିଫଳ ହୋଇଛି। ଇନଷ୍ଟଲେସନ୍ ରଦ୍ଦ କରନ୍ତୁ।"</string>
     <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"ବର୍ତ୍ତମାନ ଏକ ଡାଇନାମିକ୍ ସିଷ୍ଟମ୍ ଚାଲୁଛି। ମୂଳ Android ସଂସ୍କରଣ ବ୍ୟବହାର କରିବାକୁ ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ।"</string>
-    <string name="notification_action_cancel" msgid="5929299408545961077">"ବାତିଲ୍ କରନ୍ତୁ"</string>
+    <string name="notification_action_cancel" msgid="5929299408545961077">"ବାତିଲ କରନ୍ତୁ"</string>
     <string name="notification_action_discard" msgid="1817481003134947493">"ଖାରଜ କରନ୍ତୁ"</string>
     <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ"</string>
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ"</string>
diff --git a/packages/InputDevices/res/values-zu/strings.xml b/packages/InputDevices/res/values-zu/strings.xml
index 2c53626..88d55f2 100644
--- a/packages/InputDevices/res/values-zu/strings.xml
+++ b/packages/InputDevices/res/values-zu/strings.xml
@@ -3,51 +3,51 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="8016145283189546017">"Amadivayisi wokufaka"</string>
     <string name="keyboard_layouts_label" msgid="6688773268302087545">"Ikhibhodi ye-Android"</string>
-    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"I-English (UK)"</string>
-    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"I-English (US)"</string>
-    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"I-English (US), isitayela sakwamanye amazwe"</string>
-    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"I-English (US), isitayela se-Colemak"</string>
-    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"I-English (US), isitayela se-Dvorak"</string>
-    <string name="keyboard_layout_english_us_workman_label" msgid="2944541595262173111">"I-English (US), isitayela sokusebenza"</string>
-    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Isi-German"</string>
-    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Isi-French"</string>
-    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Isi-French (Canada)"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"English (UK)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"English (US)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"English (US), isitayela sakwamanye amazwe"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"English (US), isitayela se-Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"English (US), isitayela se-Dvorak"</string>
+    <string name="keyboard_layout_english_us_workman_label" msgid="2944541595262173111">"English (US), isitayela sokusebenza"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"German"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"French"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"French (Canada)"</string>
     <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Isi-Russian"</string>
     <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Isi-Russian, isitayela se-Mac"</string>
-    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Isi-Spanish"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Spanish"</string>
     <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Isi-Swiss French"</string>
     <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Isi-Swiss German"</string>
     <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Isi-Belgian"</string>
     <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Isi-Bulgarian"</string>
     <string name="keyboard_layout_bulgarian_phonetic" msgid="7568914730360106653">"Isi-Bulgarian, Ifonetiki"</string>
-    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Isi-Italian"</string>
-    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Isi-Danish"</string>
-    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Isi-Norwegian"</string>
-    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Isi-Swedish"</string>
-    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Isi-Finnish"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italian"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Danish"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norwegian"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Swedish"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finnish"</string>
     <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Isi-Croatian"</string>
-    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Isi-Czech"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Czech"</string>
     <string name="keyboard_layout_czech_qwerty" msgid="3331402534128515501">"Isitayela se-Czech QWERTY"</string>
     <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Isi-Estonian"</string>
-    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Isi-Hungarian"</string>
-    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Isi-Icelandic"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Hungarian"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Icelandic"</string>
     <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Isi-Brazilian"</string>
-    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Isi-Portuguese"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portuguese"</string>
     <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Isi-Slovak"</string>
-    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Isi-Slovenian"</string>
-    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Isi-Turkish"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Slovenian"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turkish"</string>
     <string name="keyboard_layout_turkish_f" msgid="9130320856010776018">"I-Turkish-F"</string>
     <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Isi-Ukrainian"</string>
-    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"Isi-Arabic"</string>
-    <string name="keyboard_layout_greek" msgid="7289253560162386040">"Isi-Greek"</string>
-    <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"Isi-Hebrew"</string>
-    <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"Isi-Lithuanian"</string>
-    <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"Isi-Spanish (Latin)"</string>
-    <string name="keyboard_layout_latvian" msgid="4405417142306250595">"Isi-Latvian"</string>
-    <string name="keyboard_layout_persian" msgid="3920643161015888527">"Isi-Persian"</string>
-    <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"Isi-Azebhayijani"</string>
-    <string name="keyboard_layout_polish" msgid="1121588624094925325">"Isi-Polish"</string>
-    <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Isi-Belarusian"</string>
+    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"Arabic"</string>
+    <string name="keyboard_layout_greek" msgid="7289253560162386040">"Greek"</string>
+    <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"Hebrew"</string>
+    <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"Lithuanian"</string>
+    <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"Spanish (Latin)"</string>
+    <string name="keyboard_layout_latvian" msgid="4405417142306250595">"Latvian"</string>
+    <string name="keyboard_layout_persian" msgid="3920643161015888527">"Persian"</string>
+    <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"Azerbaijani"</string>
+    <string name="keyboard_layout_polish" msgid="1121588624094925325">"Polish"</string>
+    <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Belarusian"</string>
     <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"isi-Mongolian"</string>
-    <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Okwesi-Georgian"</string>
+    <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgian"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-eu/strings.xml b/packages/PackageInstaller/res/values-eu/strings.xml
index fac338b..fe6edce 100644
--- a/packages/PackageInstaller/res/values-eu/strings.xml
+++ b/packages/PackageInstaller/res/values-eu/strings.xml
@@ -85,8 +85,8 @@
     <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak telebista honetan. Hori aldatzeko, joan Ezarpenak atalera."</string>
     <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak telefono honetan. Hori aldatzeko, joan Ezarpenak atalera."</string>
     <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Baliteke telefonoak eta datu pertsonalek aplikazio ezezagunen erasoak jasatea. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik telefonoari agian gertatuko zaizkion kalteen edo datu-galeren erantzulea."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tabletak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik tabletak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Telebistak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik telebistak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Baliteke tabletak eta datu pertsonalek aplikazio ezezagunen erasoak jasatea. Aplikazio hau instalatzen baduzu, onartu egingo duzu hura erabiltzeagatik tabletari agian gertatuko zaizkion kalteen edo datu-galeren erantzulea zeu izango zarela."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Baliteke telebistak eta datu pertsonalek aplikazio ezezagunen erasoak jasatea. Aplikazio hau instalatzen baduzu, onartu egingo duzu hura erabiltzeagatik telebistari agian gertatuko zaizkion kalteen edo datu-galeren erantzulea zeu izango zarela."</string>
     <string name="anonymous_source_continue" msgid="4375745439457209366">"Egin aurrera"</string>
     <string name="external_sources_settings" msgid="4046964413071713807">"Ezarpenak"</string>
     <string name="wear_app_channel" msgid="1960809674709107850">"Wear aplikazioak instalatzea/desinstalatzea"</string>
diff --git a/packages/PackageInstaller/res/values-or/strings.xml b/packages/PackageInstaller/res/values-or/strings.xml
index 4bc5bec..75d5d2d 100644
--- a/packages/PackageInstaller/res/values-or/strings.xml
+++ b/packages/PackageInstaller/res/values-or/strings.xml
@@ -20,7 +20,7 @@
     <string name="install" msgid="711829760615509273">"ଇନଷ୍ଟଲ୍‍ କରନ୍ତୁ"</string>
     <string name="update" msgid="3932142540719227615">"ଅପଡେଟ୍ କରନ୍ତୁ"</string>
     <string name="done" msgid="6632441120016885253">"ହୋଇଗଲା"</string>
-    <string name="cancel" msgid="1018267193425558088">"ବାତିଲ୍ କରନ୍ତୁ"</string>
+    <string name="cancel" msgid="1018267193425558088">"ବାତିଲ କରନ୍ତୁ"</string>
     <string name="installing" msgid="4921993079741206516">"ଇନଷ୍ଟଲ୍‌ କରାଯାଉଛି…"</string>
     <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ଇନଷ୍ଟଲ୍‌ କରାଯାଉଛି…"</string>
     <string name="install_done" msgid="5987363587661783896">"ଆପ ଇନଷ୍ଟଲ ହୋଇଗଲା।"</string>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java
index 36294ac..c9230b4 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java
@@ -69,7 +69,7 @@
                     getContext().getPackageManager().getApplicationInfo(pkg, 0).storageUuid,
                     pkg, user);
             return stats.getDataBytes();
-        } catch (PackageManager.NameNotFoundException | IOException e) {
+        } catch (PackageManager.NameNotFoundException | IOException | SecurityException e) {
             Log.e(LOG_TAG, "Cannot determine amount of app data for " + pkg, e);
         }
 
diff --git a/packages/PrintSpooler/res/values-or/strings.xml b/packages/PrintSpooler/res/values-or/strings.xml
index fa10909..6f215d3 100644
--- a/packages/PrintSpooler/res/values-or/strings.xml
+++ b/packages/PrintSpooler/res/values-or/strings.xml
@@ -83,7 +83,7 @@
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ବାତିଲ୍‍ କରାଯାଉଛି"</string>
     <string name="failed_notification_title_template" msgid="2256217208186530973">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ପ୍ରିଣ୍ଟର୍‍ ତ୍ରୁଟି"</string>
     <string name="blocked_notification_title_template" msgid="1175435827331588646">"ପ୍ରିଣ୍ଟର୍‍ ଦ୍ୱାରା ରୋକାଯାଇଥିବା <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
-    <string name="cancel" msgid="4373674107267141885">"ବାତିଲ୍ କରନ୍ତୁ"</string>
+    <string name="cancel" msgid="4373674107267141885">"ବାତିଲ କରନ୍ତୁ"</string>
     <string name="restart" msgid="2472034227037808749">"ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"ପ୍ରିଣ୍ଟର୍‍କୁ କୌଣସି ସଂଯୋଗ ନାହିଁ"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"ଅଜଣା"</string>
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index 87e61b5..a83c090 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -13,12 +13,15 @@
 
     static_libs: [
         "androidx.annotation_annotation",
-        "androidx.legacy_legacy-support-v4",
-        "androidx.recyclerview_recyclerview",
-        "androidx.preference_preference",
         "androidx.appcompat_appcompat",
+        "androidx.coordinatorlayout_coordinatorlayout",
+        "androidx.core_core",
+        "androidx.fragment_fragment",
         "androidx.lifecycle_lifecycle-runtime",
-        "androidx.mediarouter_mediarouter-nodeps",
+        "androidx.loader_loader",
+        "androidx.localbroadcastmanager_localbroadcastmanager",
+        "androidx.preference_preference",
+        "androidx.recyclerview_recyclerview",
         "com.google.android.material_material",
         "iconloader",
 
@@ -74,13 +77,15 @@
     name: "SettingsLibDefaults",
     static_libs: [
         "androidx.annotation_annotation",
-        "androidx.lifecycle_lifecycle-common",
-        "androidx.legacy_legacy-support-v4",
-        "androidx.lifecycle_lifecycle-runtime",
-        "androidx.recyclerview_recyclerview",
-        "androidx.preference_preference",
         "androidx.appcompat_appcompat",
-        "androidx.legacy_legacy-preference-v14",
+        "androidx.coordinatorlayout_coordinatorlayout",
+        "androidx.core_core",
+        "androidx.fragment_fragment",
+        "androidx.lifecycle_lifecycle-runtime",
+        "androidx.loader_loader",
+        "androidx.localbroadcastmanager_localbroadcastmanager",
+        "androidx.preference_preference",
+        "androidx.recyclerview_recyclerview",
         "SettingsLib",
     ],
 }
diff --git a/packages/SettingsLib/LayoutPreference/res/layout/settings_entity_header.xml b/packages/SettingsLib/LayoutPreference/res/layout/settings_entity_header.xml
index 50f69d1..c629d96 100644
--- a/packages/SettingsLib/LayoutPreference/res/layout/settings_entity_header.xml
+++ b/packages/SettingsLib/LayoutPreference/res/layout/settings_entity_header.xml
@@ -71,6 +71,8 @@
         <TextView
             android:id="@+id/entity_header_second_summary"
             style="@style/TextAppearance.EntityHeaderSummary"
+            android:singleLine="false"
+            android:maxLines="4"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"/>
 
diff --git a/packages/SettingsLib/common.mk b/packages/SettingsLib/common.mk
index 8c309ff..d959656 100644
--- a/packages/SettingsLib/common.mk
+++ b/packages/SettingsLib/common.mk
@@ -19,15 +19,17 @@
 # NOTE: keep this file and ./Android.bp in sync.
 
 LOCAL_STATIC_JAVA_LIBRARIES += \
-    androidx.annotation_annotation \
-    androidx.lifecycle_lifecycle-common
+    androidx.annotation_annotation
 
 LOCAL_STATIC_ANDROID_LIBRARIES += \
-    androidx.legacy_legacy-support-v4 \
-    androidx.lifecycle_lifecycle-runtime \
-    androidx.recyclerview_recyclerview \
-    androidx.preference_preference \
     androidx.appcompat_appcompat \
-    androidx.legacy_legacy-preference-v14 \
+    androidx.coordinatorlayout_coordinatorlayout \
+    androidx.core_core \
+    androidx.fragment_fragment \
+    androidx.lifecycle_lifecycle-runtime \
+    androidx.loader_loader \
+    androidx.localbroadcastmanager_localbroadcastmanager \
+    androidx.preference_preference \
+    androidx.recyclerview_recyclerview \
     SettingsLib
 
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 1ccc1b3..6eef053 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -667,7 +667,7 @@
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"ነባሪ"</string>
     <string name="turn_screen_on_title" msgid="3266937298097573424">"ማያ ገጽን ያብሩ"</string>
     <string name="allow_turn_screen_on" msgid="6194845766392742639">"ማያ ገጹን ማብራት ይፍቀዱ"</string>
-    <string name="allow_turn_screen_on_description" msgid="43834403291575164">"አንድ መተግበሪያ ማያ ገጹን እንዲያበራ ይፍቀዱለት። ከተሰጠ፣ መተግበሪያው ያለእርስዎ ግልጽ ሐሳብ በማንኛውም ጊዜ ማያ ገጹን ሊያበራ ይችላል።"</string>
+    <string name="allow_turn_screen_on_description" msgid="43834403291575164">"አንድ መተግበሪያ ማያ ገጹን እንዲያበራ ይፍቀዱለት። ከተሰጠ፣ መተግበሪያው ያለእርስዎ ግልፅ ሐሳብ በማንኛውም ጊዜ ማያ ገጹን ሊያበራ ይችላል።"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"<xliff:g id="APP_NAME">%1$s</xliff:g>ን ማሰራጨት ይቁም?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>ን ካሰራጩ ወይም ውፅዓትን ከቀየሩ የአሁኑ ስርጭትዎ ይቆማል"</string>
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ያሰራጩ"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 861d84d7..8e702db 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -576,7 +576,7 @@
     <string name="user_setup_dialog_message" msgid="269931619868102841">"مطمئن شوید شخص در دسترس است تا دستگاه را بگیرد و فضایش را تنظیم کند"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"اکنون نمایه را تنظیم می‌کنید؟"</string>
     <string name="user_setup_button_setup_now" msgid="1708269547187760639">"اکنون تنظیم شود"</string>
-    <string name="user_setup_button_setup_later" msgid="8712980133555493516">"اکنون نه"</string>
+    <string name="user_setup_button_setup_later" msgid="8712980133555493516">"حالا نه"</string>
     <string name="user_add_user_type_title" msgid="551279664052914497">"افزودن"</string>
     <string name="user_new_user_name" msgid="60979820612818840">"کاربر جدید"</string>
     <string name="user_new_profile_name" msgid="2405500423304678841">"نمایه جدید"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 7186248..03c72bc 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -665,7 +665,7 @@
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Fyysinen näppäimistö"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Valitse näppäimistöasettelu"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Oletus"</string>
-    <string name="turn_screen_on_title" msgid="3266937298097573424">"Käynnistä näyttö"</string>
+    <string name="turn_screen_on_title" msgid="3266937298097573424">"Näytön käynnistys"</string>
     <string name="allow_turn_screen_on" msgid="6194845766392742639">"Salli näytön käynnistäminen"</string>
     <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Salli sovelluksen käynnistää näyttö. Jos sovellus saa luvan, se voi käynnistää näytön itsenäisesti milloin tahansa."</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Lopetetaanko <xliff:g id="APP_NAME">%1$s</xliff:g>-sovelluksen lähettäminen?"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 78c7ab4..75abf99 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -100,13 +100,13 @@
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Холбогдсон (медиа байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Холбогдсон (мессежийн хандалт байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Холбогдсон (утас эсвэл медиа байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Холбогдсон, батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Холбогдсон (утас байхгүй), батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"Холбогдсон (медиа байхгүй), батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"Холбогдсон (утас эсвэл медиа байхгүй), батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
-    <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"Идэвхтэй, батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Холбогдсон, батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Холбогдсон (утас байхгүй), батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"Холбогдсон (медиа байхгүй), батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"Холбогдсон (утас эсвэл медиа байхгүй), батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
+    <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"Идэвхтэй, батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_active_battery_level_untethered" msgid="2706188607604205362">"Идэвхтэй, Зүүн: Батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Баруун: Батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
-    <string name="bluetooth_battery_level" msgid="2893696778200201555">"Батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_battery_level" msgid="2893696778200201555">"Батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"Зүүн: Батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Баруун: Батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Идэвхтэй"</string>
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Идэвхтэй, зөвхөн зүүн тал"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 083e55a..3c7e5b3 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -183,8 +183,8 @@
     <string name="running_process_item_user_label" msgid="3988506293099805796">"အသုံးပြုသူ- <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
     <string name="launch_defaults_some" msgid="3631650616557252926">"မူရင်းအချို့ သတ်မှတ်ပြီး"</string>
     <string name="launch_defaults_none" msgid="8049374306261262709">"မူရင်း သတ်မှတ်မထားပါ။"</string>
-    <string name="tts_settings" msgid="8130616705989351312">"စာသားမှစကားပြောပြောင်း ဆက်တင်များ"</string>
-    <string name="tts_settings_title" msgid="7602210956640483039">"စာသားမှ စကားပြောသို့ အထွက်"</string>
+    <string name="tts_settings" msgid="8130616705989351312">"စာ-မှ-စကားပြောင်းခြင်း ဆက်တင်များ"</string>
+    <string name="tts_settings_title" msgid="7602210956640483039">"စာ-မှ-စကားသို့ အထွက်"</string>
     <string name="tts_default_rate_title" msgid="3964187817364304022">"စကားပြောနှုန်း"</string>
     <string name="tts_default_rate_summary" msgid="3781937042151716987">"စာတမ်းအားပြောဆိုသော အမြန်နှုန်း"</string>
     <string name="tts_default_pitch_title" msgid="6988592215554485479">"အသံအနိမ့်အမြင့်"</string>
@@ -198,7 +198,7 @@
     <string name="tts_install_data_title" msgid="1829942496472751703">"အသံဒေတာများကို ထည့်သွင်းခြင်း"</string>
     <string name="tts_install_data_summary" msgid="3608874324992243851">"စကားသံပေါင်းစပ်မှုအတွက်လိုအပ်သောအသံဒေတာအား ထည့်သွင်းမည်"</string>
     <string name="tts_engine_security_warning" msgid="3372432853837988146">"ဤစကားသံပေါင်းစပ်စနစ်အားအသုံးပြုရာရာတွင် သင့်ကိုယ်ရေးအချက်အလက်များဖြစ်သော စကားဝှက်များနှင့် ကရက်ဒစ်ကတ်နံပါတ်စသည်တို့အပါအဝင် သင်ပြောဆိုသောစာသားများအားလုံးကို ရယူသွားမည်ဖြစ်သည်။ ဤစနစ်သည် <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> မှ လာပါသည်။ ဤစကားသံပေါင်းစပ်စနစ်ကို အသုံးပြုမလား။"</string>
-    <string name="tts_engine_network_required" msgid="8722087649733906851">"ဤဘာသာစကားသည် စာသားမှ အသံထွက်ရန် အလုပ်လုပ်သော ကွန်ရက်ချိတ်ဆက်မှု လိုအပ်သည်။"</string>
+    <string name="tts_engine_network_required" msgid="8722087649733906851">"ဤဘာသာစကားသည် စာ-မှ-စကား ပြောင်းရန် အလုပ်လုပ်သော ကွန်ရက်ချိတ်ဆက်မှု လိုအပ်သည်။"</string>
     <string name="tts_default_sample_string" msgid="6388016028292967973">"ဤသည်မှာ အသံတုလုပ်ခြင်း ၏ နမူနာတစ်ခုဖြစ်သည်။"</string>
     <string name="tts_status_title" msgid="8190784181389278640">"လက်ရှိဘာသာစကားအခြေအနေ"</string>
     <string name="tts_status_ok" msgid="8583076006537547379">"<xliff:g id="LOCALE">%1$s</xliff:g> သည်အပြည့်အ၀ အထောက်အကူပြုသည်။"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index f2aa3b6..fbe89e3 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -148,7 +148,7 @@
     <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"LE_AUDIO ପାଇଁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"ପେୟାର୍‌"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"ପେୟାର୍‌"</string>
-    <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"ବାତିଲ୍‌ କରନ୍ତୁ"</string>
+    <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"ବାତିଲ କରନ୍ତୁ"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"ପେୟାରିଂ ଫଳରେ ସଂଯୁକ୍ତ ଥିବା ବେଳେ ଆପଣଙ୍କ ସମ୍ପର୍କଗୁଡ଼ିକୁ ଏବଂ କଲ୍‌ର ଇତିବୃତିକୁ ଆକସେସ୍‌ ମଞ୍ଜୁର ହୁଏ।"</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ସହ ପେୟାର୍‌ କରିହେଲା ନାହିଁ।"</string>
     <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"ଏକ ଭୁଲ୍‌ PIN କିମ୍ବା ପାସକୀ କାରଣରୁ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ସହ ପେୟାର୍‌ କରିପାରିଲା ନାହିଁ।"</string>
@@ -305,7 +305,7 @@
     <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"ବ୍ୟକ୍ତିଗତ DNS"</string>
     <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"ବ୍ୟକ୍ତିଗତ DNS ମୋଡ୍‌ ବାଛନ୍ତୁ"</string>
     <string name="private_dns_mode_off" msgid="7065962499349997041">"ବନ୍ଦ"</string>
-    <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"ସ୍ଵଚାଳିତ"</string>
+    <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"ଅଟୋମେଟିକ"</string>
     <string name="private_dns_mode_provider" msgid="3619040641762557028">"ବ୍ୟକ୍ତିଗତ DNS ପ୍ରଦାତା ହୋଷ୍ଟନାମ"</string>
     <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"DNS ପ୍ରଦାନକାରୀଙ୍କ ହୋଷ୍ଟନାମ ଲେଖନ୍ତୁ"</string>
     <string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"କନେକ୍ଟ କରିହେଲା ନାହିଁ"</string>
@@ -524,7 +524,7 @@
     <string name="wifi_tether_connected_summary" msgid="5282919920463340158">"{count,plural, =0{0ଟି ଡିଭାଇସ ସଂଯୁକ୍ତ ହୋଇଛି}=1{1ଟି ଡିଭାଇସ ସଂଯୁକ୍ତ ହୋଇଛି}other{#ଟି ଡିଭାଇସ ସଂଯୁକ୍ତ ହୋଇଛି}}"</string>
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"ଅଧିକ ସମୟ।"</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"କମ୍ ସମୟ।"</string>
-    <string name="cancel" msgid="5665114069455378395">"ବାତିଲ୍"</string>
+    <string name="cancel" msgid="5665114069455378395">"ବାତିଲ"</string>
     <string name="okay" msgid="949938843324579502">"ଠିକ୍‌ ଅଛି"</string>
     <string name="done" msgid="381184316122520313">"ହୋଇଗଲା"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"ଆଲାରାମ୍ ଏବଂ ରିମାଇଣ୍ଡରଗୁଡ଼ିକ"</string>
@@ -624,7 +624,7 @@
     <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ଡିଭାଇସ୍ ଡିଫଲ୍ଟ"</string>
     <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"ଅକ୍ଷମ କରାଯାଇଛି"</string>
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ସକ୍ଷମ କରାଯାଇଛି"</string>
-    <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ଏହି ପରିବର୍ତ୍ତନ ଲାଗୁ କରିବା ପାଇଁ ଆପଣଙ୍କ ଡିଭାଇସକୁ ନିଶ୍ଚିତ ରୂପେ ରିବୁଟ୍ କରାଯିବା ଆବଶ୍ୟକ। ବର୍ତ୍ତମାନ ରିବୁଟ୍ କରନ୍ତୁ କିମ୍ବା ବାତିଲ୍ କରନ୍ତୁ।"</string>
+    <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ଏହି ପରିବର୍ତ୍ତନ ଲାଗୁ କରିବା ପାଇଁ ଆପଣଙ୍କ ଡିଭାଇସକୁ ନିଶ୍ଚିତ ରୂପେ ରିବୁଟ୍ କରାଯିବା ଆବଶ୍ୟକ। ବର୍ତ୍ତମାନ ରିବୁଟ୍ କରନ୍ତୁ କିମ୍ବା ବାତିଲ କରନ୍ତୁ।"</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"ତାରଯୁକ୍ତ ହେଡଫୋନ୍"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"ଚାଲୁ ଅଛି"</string>
     <string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"ବନ୍ଦ ଅଛି"</string>
diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml
index a5b9f79..513fb6e 100644
--- a/packages/SettingsLib/res/values-te/arrays.xml
+++ b/packages/SettingsLib/res/values-te/arrays.xml
@@ -50,8 +50,8 @@
   </string-array>
   <string-array name="hdcp_checking_titles">
     <item msgid="2377230797542526134">"ఎప్పటికీ తనిఖీ చేయవద్దు"</item>
-    <item msgid="3919638466823112484">"DRM కంటెంట్‌కు మాత్రమే తనిఖీ చేయండి"</item>
-    <item msgid="9048424957228926377">"ఎల్లప్పుడూ తనిఖీ చేయండి"</item>
+    <item msgid="3919638466823112484">"DRM కంటెంట్‌కు మాత్రమే చెక్ చేయండి"</item>
+    <item msgid="9048424957228926377">"ఎల్లప్పుడూ చెక్ చేయండి"</item>
   </string-array>
   <string-array name="hdcp_checking_summaries">
     <item msgid="4045840870658484038">"ఎప్పటికీ HDCP తనిఖీని ఉపయోగించవద్దు"</item>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index f89775f..3f82d47 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -204,7 +204,7 @@
     <string name="tts_status_ok" msgid="8583076006537547379">"<xliff:g id="LOCALE">%1$s</xliff:g>కి పూర్తి మద్దతు ఉంది"</string>
     <string name="tts_status_requires_network" msgid="8327617638884678896">"<xliff:g id="LOCALE">%1$s</xliff:g>కి నెట్‌వర్క్ కనెక్షన్ అవసరం"</string>
     <string name="tts_status_not_supported" msgid="2702997696245523743">"<xliff:g id="LOCALE">%1$s</xliff:g>కు మద్దతు లేదు"</string>
-    <string name="tts_status_checking" msgid="8026559918948285013">"తనిఖీ చేస్తోంది..."</string>
+    <string name="tts_status_checking" msgid="8026559918948285013">"చెక్ చేస్తోంది..."</string>
     <string name="tts_engine_settings_title" msgid="7849477533103566291">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> కోసం సెట్టింగ్‌లు"</string>
     <string name="tts_engine_settings_button" msgid="477155276199968948">"ఇంజిన్ సెట్టింగ్‌లను ప్రారంభించండి"</string>
     <string name="tts_engine_preference_section_title" msgid="3861562305498624904">"ప్రాధాన్య ఇంజిన్"</string>
@@ -336,7 +336,7 @@
     <string name="dev_settings_warning_title" msgid="8251234890169074553">"అభివృద్ధి సెట్టింగ్‌లను అనుమతించాలా?"</string>
     <string name="dev_settings_warning_message" msgid="37741686486073668">"ఈ సెట్టింగ్‌లు అభివృద్ధి వినియోగం కోసం మాత్రమే ఉద్దేశించబడినవి. వీటి వలన మీ పరికరం మరియు దీనిలోని యాప్‌లు విచ్ఛిన్నం కావచ్చు లేదా తప్పుగా ప్రవర్తించవచ్చు."</string>
     <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"USB ద్వారా యాప్‌లను వెరిఫై చేయి"</string>
-    <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"హానికరమైన ప్రవర్తన కోసం ADB/ADT ద్వారా ఇన్‌స్టాల్ చేయబడిన యాప్‌లను తనిఖీ చేయి."</string>
+    <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"హానికరమైన ప్రవర్తన కోసం ADB/ADT ద్వారా ఇన్‌స్టాల్ చేయబడిన యాప్‌లను చెక్ చేయండి."</string>
     <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"పేర్లు (MAC అడ్రస్‌లు మాత్రమే) లేని బ్లూటూత్ పరికరాలు డిస్‌ప్లే కాబడతాయి"</string>
     <string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"రిమోట్ పరికరాల్లో ఆమోదించలేని స్థాయిలో అధిక వాల్యూమ్ ఉండటం లేదా వాల్యూమ్ కంట్రోల్ లేకపోవడం వంటి సమస్యలు ఉంటే బ్లూటూత్ సంపూర్ణ వాల్యూమ్ ఫీచర్‌ను డిజేబుల్ చేస్తుంది."</string>
     <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"బ్లూటూత్ Gabeldorsche ఫీచర్ స్ట్యాక్‌ను ఎనేబుల్ చేస్తుంది."</string>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index a5f4133..f1745ec 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -246,9 +246,9 @@
     <!-- Bluetooth settings. The user-visible string that is used whenever referring to the PAN profile (accessing Internet through remote device). [CHAR LIMIT=40] -->
     <string name="bluetooth_profile_pan">Internet access</string>
     <!-- Bluetooth settings. The user-visible string that is used whenever referring to the PBAP profile. [CHAR LIMIT=40] -->
-    <string name="bluetooth_profile_pbap">Contact sharing</string>
+    <string name="bluetooth_profile_pbap">Contacts and call history sharing</string>
     <!-- Bluetooth settings. The user-visible summary string that is used whenever referring to the PBAP profile (sharing contacts). [CHAR LIMIT=60] -->
-    <string name="bluetooth_profile_pbap_summary">Use for contact sharing</string>
+    <string name="bluetooth_profile_pbap_summary">Use for contacts and call history sharing</string>
     <!-- Bluetooth settings. The user-visible string that is used whenever referring to the PAN profile (sharing this device's Internet connection). [CHAR LIMIT=40] -->
     <string name="bluetooth_profile_pan_nap">Internet connection sharing</string>
     <!-- Bluetooth settings. The user-visible string that is used whenever referring to the map profile. -->
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
index bf9debf..bf69757 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
@@ -87,9 +87,11 @@
             if (DEBUG) {
                 Log.d(TAG, "Bluetooth service connected");
             }
-            mService = (BluetoothLeBroadcast) proxy;
-            mIsProfileReady = true;
-            registerServiceCallBack(mExecutor, mBroadcastCallback);
+            if(!mIsProfileReady) {
+                mService = (BluetoothLeBroadcast) proxy;
+                mIsProfileReady = true;
+                registerServiceCallBack(mExecutor, mBroadcastCallback);
+            }
         }
 
         @Override
@@ -97,8 +99,10 @@
             if (DEBUG) {
                 Log.d(TAG, "Bluetooth service disconnected");
             }
-            mIsProfileReady = false;
-            unregisterServiceCallBack(mBroadcastCallback);
+            if(mIsProfileReady) {
+                mIsProfileReady = false;
+                unregisterServiceCallBack(mBroadcastCallback);
+            }
         }
     };
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
index d6d7304..281501e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
@@ -22,6 +22,7 @@
 import android.bluetooth.BluetoothDevice;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
+import android.media.AudioManager;
 import android.media.RoutingSessionInfo;
 import android.os.Build;
 import android.text.TextUtils;
@@ -83,6 +84,7 @@
     private InfoMediaManager mInfoMediaManager;
     private String mPackageName;
     private MediaDevice mOnTransferBluetoothDevice;
+    private AudioManager mAudioManager;
 
     @VisibleForTesting
     List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();
@@ -126,6 +128,7 @@
         mPackageName = packageName;
         mLocalBluetoothManager =
                 LocalBluetoothManager.getInstance(context, /* onInitCallback= */ null);
+        mAudioManager = context.getSystemService(AudioManager.class);
         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
         if (mLocalBluetoothManager == null) {
             Log.e(TAG, "Bluetooth is not supported on this device");
@@ -148,6 +151,7 @@
         mInfoMediaManager = infoMediaManager;
         mPackageName = packageName;
         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+        mAudioManager = context.getSystemService(AudioManager.class);
     }
 
     /**
@@ -527,13 +531,16 @@
             synchronized (mMediaDevicesLock) {
                 mMediaDevices.clear();
                 mMediaDevices.addAll(devices);
-                // Add disconnected bluetooth devices only when phone output device is available.
+                // Add muting expected bluetooth devices only when phone output device is available.
                 for (MediaDevice device : devices) {
                     final int type = device.getDeviceType();
                     if (type == MediaDevice.MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE
                             || type == MediaDevice.MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE
                             || type == MediaDevice.MediaDeviceType.TYPE_PHONE_DEVICE) {
-                        mMediaDevices.addAll(buildDisconnectedBluetoothDevice());
+                        MediaDevice mutingExpectedDevice = getMutingExpectedDevice();
+                        if (mutingExpectedDevice != null) {
+                            mMediaDevices.add(mutingExpectedDevice);
+                        }
                         break;
                     }
                 }
@@ -552,6 +559,34 @@
             }
         }
 
+        private MediaDevice getMutingExpectedDevice() {
+            if (mBluetoothAdapter == null
+                    || mAudioManager.getMutingExpectedDevice() == null) {
+                Log.w(TAG, "BluetoothAdapter is null or muting expected device not exist");
+                return null;
+            }
+            final List<BluetoothDevice> bluetoothDevices =
+                    mBluetoothAdapter.getMostRecentlyConnectedDevices();
+            final CachedBluetoothDeviceManager cachedDeviceManager =
+                    mLocalBluetoothManager.getCachedDeviceManager();
+            for (BluetoothDevice device : bluetoothDevices) {
+                final CachedBluetoothDevice cachedDevice =
+                        cachedDeviceManager.findDevice(device);
+                if (isBondedMediaDevice(cachedDevice) && isMutingExpectedDevice(cachedDevice)) {
+                    return new BluetoothMediaDevice(mContext,
+                            cachedDevice,
+                            null, null, mPackageName);
+                }
+            }
+            return null;
+        }
+
+        private boolean isMutingExpectedDevice(CachedBluetoothDevice cachedDevice) {
+            return mAudioManager.getMutingExpectedDevice() != null
+                    && cachedDevice.getAddress().equals(
+                    mAudioManager.getMutingExpectedDevice().getAddress());
+        }
+
         private List<MediaDevice> buildDisconnectedBluetoothDevice() {
             if (mBluetoothAdapter == null) {
                 Log.w(TAG, "buildDisconnectedBluetoothDevice() BluetoothAdapter is null");
@@ -595,6 +630,13 @@
             return new ArrayList<>(mDisconnectedMediaDevices);
         }
 
+        private boolean isBondedMediaDevice(CachedBluetoothDevice cachedDevice) {
+            return cachedDevice != null
+                    && cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED
+                    && !cachedDevice.isConnected()
+                    && isMediaDevice(cachedDevice);
+        }
+
         private boolean isMediaDevice(CachedBluetoothDevice device) {
             for (LocalBluetoothProfile profile : device.getConnectableProfiles()) {
                 if (profile instanceof A2dpProfile || profile instanceof HearingAidProfile ||
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java
index 1f2297b..fc2bf0a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java
@@ -21,10 +21,10 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyLong;
+import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java
index 95f7ef4..508dffc 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java
@@ -18,7 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java
index 69484ed..f760032 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java
@@ -22,7 +22,7 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.Activity;
@@ -147,7 +147,7 @@
         dialog.show();
         dialog.cancel();
 
-        verifyZeroInteractions(successCallback);
+        verifyNoInteractions(successCallback);
         verify(cancelCallback, times(1))
                 .run();
     }
@@ -163,7 +163,7 @@
         dialog.show();
         dialog.getButton(Dialog.BUTTON_NEGATIVE).performClick();
 
-        verifyZeroInteractions(successCallback);
+        verifyNoInteractions(successCallback);
         verify(cancelCallback, times(1))
                 .run();
     }
@@ -184,7 +184,7 @@
 
         verify(successCallback, times(1))
                 .accept("test", oldUserIcon);
-        verifyZeroInteractions(cancelCallback);
+        verifyNoInteractions(cancelCallback);
     }
 
     @Test
@@ -202,7 +202,7 @@
 
         verify(successCallback, times(1))
                 .accept("test", null);
-        verifyZeroInteractions(cancelCallback);
+        verifyNoInteractions(cancelCallback);
     }
 
     @Test
@@ -223,7 +223,7 @@
 
         verify(successCallback, times(1))
                 .accept(expectedNewName, mCurrentIcon);
-        verifyZeroInteractions(cancelCallback);
+        verifyNoInteractions(cancelCallback);
     }
 
     @Test
@@ -242,7 +242,7 @@
 
         verify(successCallback, times(1))
                 .accept("test", newPhoto);
-        verifyZeroInteractions(cancelCallback);
+        verifyNoInteractions(cancelCallback);
     }
 
     @Test
@@ -261,7 +261,7 @@
 
         verify(successCallback, times(1))
                 .accept("test", newPhoto);
-        verifyZeroInteractions(cancelCallback);
+        verifyNoInteractions(cancelCallback);
     }
 
     @Test
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/UpdatableListPreferenceDialogFragmentTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/UpdatableListPreferenceDialogFragmentTest.java
index 0b3495d..ca0aa0d 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/UpdatableListPreferenceDialogFragmentTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/UpdatableListPreferenceDialogFragmentTest.java
@@ -56,7 +56,7 @@
 
         mUpdatableListPrefDlgFragment = spy(UpdatableListPreferenceDialogFragment
                 .newInstance(KEY, MetricsProto.MetricsEvent.DIALOG_SWITCH_A2DP_DEVICES));
-        mEntries = spy(new ArrayList<>());
+        mEntries = new ArrayList<>();
         mUpdatableListPrefDlgFragment.setEntries(mEntries);
         mUpdatableListPrefDlgFragment
                 .setMetricsCategory(mUpdatableListPrefDlgFragment.getArguments());
diff --git a/packages/SettingsProvider/res/values-nb/strings.xml b/packages/SettingsProvider/res/values-nb/strings.xml
index 3bdaf83..8da90c0 100644
--- a/packages/SettingsProvider/res/values-nb/strings.xml
+++ b/packages/SettingsProvider/res/values-nb/strings.xml
@@ -20,6 +20,6 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4567566098528588863">"Lagring av innstillinger"</string>
-    <string name="wifi_softap_config_change" msgid="5688373762357941645">"Innstillingene for Wi-Fi-sone er endret"</string>
+    <string name="wifi_softap_config_change" msgid="5688373762357941645">"Innstillingene for wifi-sone er endret"</string>
     <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Trykk for å se detaljer"</string>
 </resources>
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
index 3ad3f34..298bbbd 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
@@ -92,7 +92,7 @@
         Settings.Global.Wearable.AMBIENT_ENABLED,
         Settings.Global.Wearable.AMBIENT_TILT_TO_WAKE,
         Settings.Global.Wearable.AMBIENT_TOUCH_TO_WAKE,
-        Settings.Global.Wearable.TOUCH_AND_HOLD_WATCH_FACE,
+        Settings.Global.Wearable.GESTURE_TOUCH_AND_HOLD_WATCH_FACE_ENABLED,
         Settings.Global.Wearable.BATTERY_SAVER_MODE,
         Settings.Global.Wearable.WEAR_ACTIVITY_AUTO_RESUME_TIMEOUT_MS,
         Settings.Global.Wearable.WEAR_ACTIVITY_AUTO_RESUME_TIMEOUT_SET_BY_USER
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 94256fc..133b52d 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -118,6 +118,10 @@
         Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD,
         Settings.Secure.FACE_UNLOCK_APP_ENABLED,
         Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
+        Settings.Secure.FINGERPRINT_SIDE_FPS_KG_POWER_WINDOW,
+        Settings.Secure.FINGERPRINT_SIDE_FPS_BP_POWER_WINDOW,
+        Settings.Secure.FINGERPRINT_SIDE_FPS_ENROLL_TAP_WINDOW,
+        Settings.Secure.FINGERPRINT_SIDE_FPS_AUTH_DOWNTIME,
         Settings.Secure.ACTIVE_UNLOCK_ON_WAKE,
         Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT,
         Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
index d1ba27e..796b4c4 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
@@ -51,6 +51,7 @@
                                 || (val == BatteryManager.BATTERY_PLUGGED_AC)
                                 || (val == BatteryManager.BATTERY_PLUGGED_USB)
                                 || (val == BatteryManager.BATTERY_PLUGGED_WIRELESS)
+                                || (val == BatteryManager.BATTERY_PLUGGED_DOCK)
                                 || (val
                                         == (BatteryManager.BATTERY_PLUGGED_AC
                                                 | BatteryManager.BATTERY_PLUGGED_USB))
@@ -58,12 +59,29 @@
                                         == (BatteryManager.BATTERY_PLUGGED_AC
                                                 | BatteryManager.BATTERY_PLUGGED_WIRELESS))
                                 || (val
+                                        == (BatteryManager.BATTERY_PLUGGED_AC
+                                                | BatteryManager.BATTERY_PLUGGED_DOCK))
+                                || (val
                                         == (BatteryManager.BATTERY_PLUGGED_USB
                                                 | BatteryManager.BATTERY_PLUGGED_WIRELESS))
                                 || (val
+                                        == (BatteryManager.BATTERY_PLUGGED_USB
+                                                | BatteryManager.BATTERY_PLUGGED_DOCK))
+                                || (val
+                                        == (BatteryManager.BATTERY_PLUGGED_WIRELESS
+                                                | BatteryManager.BATTERY_PLUGGED_DOCK))
+                                || (val
+                                        == (BatteryManager.BATTERY_PLUGGED_AC
+                                                | BatteryManager.BATTERY_PLUGGED_USB
+                                                | BatteryManager.BATTERY_PLUGGED_WIRELESS))
+                                || (val
                                         == (BatteryManager.BATTERY_PLUGGED_AC
                                                 | BatteryManager.BATTERY_PLUGGED_USB
-                                                | BatteryManager.BATTERY_PLUGGED_WIRELESS));
+                                                | BatteryManager.BATTERY_PLUGGED_DOCK))
+                                || (val
+                                        == (BatteryManager.BATTERY_PLUGGED_USB
+                                                | BatteryManager.BATTERY_PLUGGED_WIRELESS
+                                                | BatteryManager.BATTERY_PLUGGED_DOCK));
                     } catch (NumberFormatException e) {
                         return false;
                     }
@@ -313,7 +331,8 @@
         VALIDATORS.put(Global.USER_PREFERRED_RESOLUTION_WIDTH, ANY_INTEGER_VALIDATOR);
         VALIDATORS.put(Global.Wearable.WET_MODE_ON, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Global.Wearable.COOLDOWN_MODE_ON, BOOLEAN_VALIDATOR);
-        VALIDATORS.put(Global.Wearable.TOUCH_AND_HOLD_WATCH_FACE, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(
+                Global.Wearable.GESTURE_TOUCH_AND_HOLD_WATCH_FACE_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Global.Wearable.SCREEN_UNLOCK_SOUND_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Global.Wearable.CHARGING_SOUNDS_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Global.Wearable.BEDTIME_MODE, BOOLEAN_VALIDATOR);
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 7b0196a..bb01f4f 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -172,6 +172,11 @@
                 Secure.AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN, NON_NEGATIVE_INTEGER_VALIDATOR);
         VALIDATORS.put(Secure.FACE_UNLOCK_KEYGUARD_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Secure.FINGERPRINT_SIDE_FPS_KG_POWER_WINDOW, NON_NEGATIVE_INTEGER_VALIDATOR);
+        VALIDATORS.put(Secure.FINGERPRINT_SIDE_FPS_BP_POWER_WINDOW, NON_NEGATIVE_INTEGER_VALIDATOR);
+        VALIDATORS.put(Secure.FINGERPRINT_SIDE_FPS_ENROLL_TAP_WINDOW,
+                NON_NEGATIVE_INTEGER_VALIDATOR);
+        VALIDATORS.put(Secure.FINGERPRINT_SIDE_FPS_AUTH_DOWNTIME, NON_NEGATIVE_INTEGER_VALIDATOR);
         VALIDATORS.put(Secure.SHOW_MEDIA_WHEN_BYPASSING, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.FACE_UNLOCK_APP_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, BOOLEAN_VALIDATOR);
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 2d384c2..b31e36c 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -596,6 +596,9 @@
     <!-- Permission required for CTS test - ClipboardManagerTest -->
     <uses-permission android:name="android.permission.SET_CLIP_SOURCE" />
 
+    <!-- Permission required for CTS test - CtsInputMethodTestCases -->
+    <uses-permission android:name="android.permission.TEST_INPUT_METHOD" />
+
     <!-- Permission required for CTS test - FontManagerTest -->
     <uses-permission android:name="android.permission.UPDATE_FONTS" />
 
diff --git a/packages/Shell/res/values-pa/strings.xml b/packages/Shell/res/values-pa/strings.xml
index daeac3c..57ad5e2 100644
--- a/packages/Shell/res/values-pa/strings.xml
+++ b/packages/Shell/res/values-pa/strings.xml
@@ -39,7 +39,7 @@
     <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਸਫਲਤਾਪੂਰਵਕ ਲਿਆ ਗਿਆ।"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਨਹੀਂ ਲਿਆ ਜਾ ਸਕਿਆ।"</string>
     <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"ਬੱਗ ਰਿਪੋਰਟ <xliff:g id="ID">#%d</xliff:g> ਵੇਰਵੇ"</string>
-    <string name="bugreport_info_name" msgid="4414036021935139527">"ਫ਼ਾਈਲ ਨਾਮ"</string>
+    <string name="bugreport_info_name" msgid="4414036021935139527">"ਫ਼ਾਈਲ ਦਾ ਨਾਮ"</string>
     <string name="bugreport_info_title" msgid="2306030793918239804">"ਬੱਗ ਸਿਰਲੇਖ"</string>
     <string name="bugreport_info_description" msgid="5072835127481627722">"ਬੱਗ ਸਾਰਾਂਸ਼"</string>
     <string name="save" msgid="4781509040564835759">"ਰੱਖਿਅਤ ਕਰੋ"</string>
diff --git a/packages/SimAppDialog/res/values-fa/strings.xml b/packages/SimAppDialog/res/values-fa/strings.xml
index 7eb87dd..74e81a4 100644
--- a/packages/SimAppDialog/res/values-fa/strings.xml
+++ b/packages/SimAppDialog/res/values-fa/strings.xml
@@ -21,6 +21,6 @@
     <string name="install_carrier_app_title" msgid="334729104862562585">"سرویس دستگاه همراه را فعال کنید"</string>
     <string name="install_carrier_app_description" msgid="4014303558674923797">"برای اینکه سیم‌کارت جدیدتان به‌درستی کار کند، باید برنامه <xliff:g id="ID_1">%1$s</xliff:g> را نصب کنید"</string>
     <string name="install_carrier_app_description_default" msgid="7356830245205847840">"برای اینکه سیم‌کارت جدیدتان به‌درستی کار کند، باید برنامه شرکت مخابراتی را نصب کنید"</string>
-    <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"الآن نه"</string>
+    <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"حالا نه"</string>
     <string name="install_carrier_app_download_action" msgid="7859229305958538064">"بارگیری برنامه"</string>
 </resources>
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index bae7064..046706d 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -110,6 +110,7 @@
         "androidx.arch.core_core-runtime",
         "androidx.lifecycle_lifecycle-common-java8",
         "androidx.lifecycle_lifecycle-extensions",
+        "androidx.lifecycle_lifecycle-runtime-ktx",
         "androidx.dynamicanimation_dynamicanimation",
         "androidx-constraintlayout_constraintlayout",
         "androidx.exifinterface_exifinterface",
@@ -219,6 +220,7 @@
         "androidx.arch.core_core-runtime",
         "androidx.lifecycle_lifecycle-common-java8",
         "androidx.lifecycle_lifecycle-extensions",
+        "androidx.lifecycle_lifecycle-runtime-ktx",
         "androidx.dynamicanimation_dynamicanimation",
         "androidx-constraintlayout_constraintlayout",
         "androidx.exifinterface_exifinterface",
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 1c13b16..6edf13a 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -618,6 +618,17 @@
             android:excludeFromRecents="true"
             android:visibleToInstantApps="true"/>
 
+        <activity
+            android:name=".media.MediaProjectionAppSelectorActivity"
+            android:theme="@style/Theme.SystemUI.MediaProjectionAppSelector"
+            android:finishOnCloseSystemDialogs="true"
+            android:excludeFromRecents="true"
+            android:documentLaunchMode="never"
+            android:relinquishTaskIdentity="true"
+            android:configChanges=
+                "screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden"
+            android:visibleToInstantApps="true"/>
+
         <!-- started from TvNotificationPanel -->
         <activity
             android:name=".statusbar.tv.notifications.TvNotificationPanelActivity"
diff --git a/packages/SystemUI/TEST_MAPPING b/packages/SystemUI/TEST_MAPPING
index f9a9ef6..154a6fc 100644
--- a/packages/SystemUI/TEST_MAPPING
+++ b/packages/SystemUI/TEST_MAPPING
@@ -102,7 +102,7 @@
   //
   // If you don't use @Staging or @Postsubmit, your new test will immediately
   // block presubmit, which is probably not what you want!
-  "platinum-postsubmit": [
+  "sysui-platinum-postsubmit": [
     {
       "name": "PlatformScenarioTests",
       "options": [
@@ -121,7 +121,7 @@
       ]
     }
   ],
-  "staged-platinum-postsubmit": [
+  "sysui-staged-platinum-postsubmit": [
     {
       "name": "PlatformScenarioTests",
       "options": [
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
index fbe3356..8ddd430 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
@@ -523,9 +523,10 @@
             state: LaunchAnimator.State,
             linearProgress: Float,
         ) {
-            if (transactionApplierView.viewRootImpl == null) {
-                // If the view root we synchronize with was detached, don't apply any transaction
-                // (as [SyncRtSurfaceTransactionApplier.scheduleApply] would otherwise throw).
+            if (transactionApplierView.viewRootImpl == null || !window.leash.isValid) {
+                // Don't apply any transaction if the view root we synchronize with was detached or
+                // if the SurfaceControl associated with [window] is not valid, as
+                // [SyncRtSurfaceTransactionApplier.scheduleApply] would otherwise throw.
                 return
             }
 
@@ -605,9 +606,10 @@
             state: LaunchAnimator.State,
             linearProgress: Float
         ) {
-            if (transactionApplierView.viewRootImpl == null) {
-                // If the view root we synchronize with was detached, don't apply any transaction
-                // (as [SyncRtSurfaceTransactionApplier.scheduleApply] would otherwise throw).
+            if (transactionApplierView.viewRootImpl == null || !navigationBar.leash.isValid) {
+                // Don't apply any transaction if the view root we synchronize with was detached or
+                // if the SurfaceControl associated with [navigationBar] is not valid, as
+                // [SyncRtSurfaceTransactionApplier.scheduleApply] would otherwise throw.
                 return
             }
 
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
index cb16d7c..2f36ab9 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
@@ -150,15 +150,16 @@
     fun showFromDialog(
         dialog: Dialog,
         animateFrom: Dialog,
+        cuj: DialogCuj? = null,
         animateBackgroundBoundsChange: Boolean = false
     ) {
         val view =
             openedDialogs.firstOrNull { it.dialog == animateFrom }?.dialogContentWithBackground
                 ?: throw IllegalStateException(
                     "The animateFrom dialog was not animated using " +
-                        "DialogLaunchAnimator.showFrom(View|Dialog)"
-                )
-        showFromView(dialog, view, animateBackgroundBoundsChange = animateBackgroundBoundsChange)
+                        "DialogLaunchAnimator.showFrom(View|Dialog)")
+        showFromView(
+            dialog, view, animateBackgroundBoundsChange = animateBackgroundBoundsChange, cuj = cuj)
     }
 
     /**
@@ -514,11 +515,20 @@
         dialogContentWithBackground.setTransitionVisibility(View.INVISIBLE)
 
         // Make sure the dialog is visible instantly and does not do any window animation.
-        window.attributes.windowAnimations = R.style.Animation_LaunchAnimation
+        val attributes = window.attributes
+        attributes.windowAnimations = R.style.Animation_LaunchAnimation
 
         // Ensure that the animation is not clipped by the display cut-out when animating this
         // dialog into an app.
-        window.attributes.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
+        attributes.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
+
+        // Ensure that the animation is not clipped by the navigation/task bars when animating this
+        // dialog into an app.
+        val wasFittingNavigationBars =
+            attributes.fitInsetsTypes and WindowInsets.Type.navigationBars() != 0
+        attributes.fitInsetsTypes =
+            attributes.fitInsetsTypes and WindowInsets.Type.navigationBars().inv()
+
         window.attributes = window.attributes
 
         // We apply the insets ourselves to make sure that the paddings are set on the correct
@@ -526,7 +536,13 @@
         window.setDecorFitsSystemWindows(false)
         val viewWithInsets = (dialogContentWithBackground.parent as ViewGroup)
         viewWithInsets.setOnApplyWindowInsetsListener { view, windowInsets ->
-            val insets = windowInsets.getInsets(WindowInsets.Type.displayCutout())
+            val type = if (wasFittingNavigationBars) {
+                WindowInsets.Type.displayCutout() or WindowInsets.Type.navigationBars()
+            } else {
+                WindowInsets.Type.displayCutout()
+            }
+
+            val insets = windowInsets.getInsets(type)
             view.setPadding(insets.left, insets.top, insets.right, insets.bottom)
             WindowInsets.CONSUMED
         }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
index 47f448d..eb000ad 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
@@ -49,17 +49,16 @@
  * Note: Avoid instantiating this directly and call [ActivityLaunchAnimator.Controller.fromView]
  * whenever possible instead.
  */
-open class GhostedViewLaunchAnimatorController(
+open class GhostedViewLaunchAnimatorController @JvmOverloads constructor(
     /** The view that will be ghosted and from which the background will be extracted. */
     private val ghostedView: View,
 
     /** The [InteractionJankMonitor.CujType] associated to this animation. */
     private val cujType: Int? = null,
-    private var interactionJankMonitor: InteractionJankMonitor? = null
+    private var interactionJankMonitor: InteractionJankMonitor =
+        InteractionJankMonitor.getInstance(),
 ) : ActivityLaunchAnimator.Controller {
 
-    constructor(view: View, type: Int) : this(view, type, null)
-
     /** The container to which we will add the ghost view and expanding background. */
     override var launchContainer = ghostedView.rootView as ViewGroup
     private val launchContainerOverlay: ViewGroupOverlay
@@ -203,7 +202,7 @@
         val matrix = ghostView?.animationMatrix ?: Matrix.IDENTITY_MATRIX
         matrix.getValues(initialGhostViewMatrixValues)
 
-        cujType?.let { interactionJankMonitor?.begin(ghostedView, it) }
+        cujType?.let { interactionJankMonitor.begin(ghostedView, it) }
     }
 
     override fun onLaunchAnimationProgress(
@@ -289,7 +288,7 @@
             return
         }
 
-        cujType?.let { interactionJankMonitor?.end(it) }
+        cujType?.let { interactionJankMonitor.end(it) }
 
         backgroundDrawable?.wrapped?.alpha = startBackgroundAlpha
 
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
index 4b0c62b..cc7d23e 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
@@ -106,7 +106,7 @@
             ephemeral: Boolean
         ): Boolean {
             if (
-                !isVisible(
+                !occupiesSpace(
                     rootView.visibility,
                     rootView.left,
                     rootView.top,
@@ -177,7 +177,7 @@
             fadeInInterpolator: Interpolator = DEFAULT_FADE_IN_INTERPOLATOR
         ): Boolean {
             if (
-                isVisible(
+                occupiesSpace(
                     rootView.visibility,
                     rootView.left,
                     rootView.top,
@@ -295,7 +295,7 @@
 
                     (view.getTag(R.id.tag_animator) as? ObjectAnimator)?.cancel()
 
-                    if (!isVisible(view.visibility, left, top, right, bottom)) {
+                    if (!occupiesSpace(view.visibility, left, top, right, bottom)) {
                         setBound(view, Bound.LEFT, left)
                         setBound(view, Bound.TOP, top)
                         setBound(view, Bound.RIGHT, right)
@@ -362,7 +362,7 @@
             duration: Long = DEFAULT_DURATION
         ): Boolean {
             if (
-                !isVisible(
+                !occupiesSpace(
                     rootView.visibility,
                     rootView.left,
                     rootView.top,
@@ -530,17 +530,17 @@
         }
 
         /**
-         * Returns whether the given [visibility] and bounds are consistent with a view being
-         * currently visible on screen.
+         * Returns whether the given [visibility] and bounds are consistent with a view being a
+         * contributing part of the hierarchy.
          */
-        private fun isVisible(
+        private fun occupiesSpace(
             visibility: Int,
             left: Int,
             top: Int,
             right: Int,
             bottom: Int
         ): Boolean {
-            return visibility == View.VISIBLE && left != right && top != bottom
+            return visibility != View.GONE && left != right && top != bottom
         }
 
         /**
diff --git a/packages/SystemUI/checks/Android.bp b/packages/SystemUI/checks/Android.bp
index 8457312..61fc48f 100644
--- a/packages/SystemUI/checks/Android.bp
+++ b/packages/SystemUI/checks/Android.bp
@@ -32,6 +32,7 @@
         "auto_service_annotations",
         "lint_api",
     ],
+    kotlincflags: ["-Xjvm-default=all"],
 }
 
 java_test_host {
diff --git a/packages/SystemUI/compose/gallery/AndroidManifest.xml b/packages/SystemUI/compose/gallery/AndroidManifest.xml
index 562e1cc..4fcce0b 100644
--- a/packages/SystemUI/compose/gallery/AndroidManifest.xml
+++ b/packages/SystemUI/compose/gallery/AndroidManifest.xml
@@ -17,5 +17,6 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.systemui.compose.gallery">
-
+    <!-- To emulate a display size and density. -->
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 </manifest>
diff --git a/packages/SystemUI/compose/gallery/app/AndroidManifest.xml b/packages/SystemUI/compose/gallery/app/AndroidManifest.xml
index 8113263..e7d496c 100644
--- a/packages/SystemUI/compose/gallery/app/AndroidManifest.xml
+++ b/packages/SystemUI/compose/gallery/app/AndroidManifest.xml
@@ -16,7 +16,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.systemui.compose.gallery">
+    package="com.android.systemui.compose.gallery.app">
     <application
         android:allowBackup="true"
         android:icon="@mipmap/ic_launcher"
@@ -25,7 +25,7 @@
         android:supportsRtl="true"
         android:theme="@style/Theme.SystemUIGallery">
         <activity
-            android:name=".GalleryActivity"
+            android:name="com.android.systemui.compose.gallery.GalleryActivity"
             android:exported="true"
             android:label="@string/app_name">
             <intent-filter>
diff --git a/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/ConfigurationControls.kt b/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/ConfigurationControls.kt
index 65ea88a..06bdad8 100644
--- a/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/ConfigurationControls.kt
+++ b/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/ConfigurationControls.kt
@@ -1,5 +1,10 @@
 package com.android.systemui.compose.gallery
 
+import android.graphics.Point
+import android.os.UserHandle
+import android.view.Display
+import android.view.WindowManagerGlobal
+import androidx.compose.foundation.layout.RowScope
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.lazy.LazyRow
@@ -9,14 +14,25 @@
 import androidx.compose.material.icons.filled.FormatSize
 import androidx.compose.material.icons.filled.FormatTextdirectionLToR
 import androidx.compose.material.icons.filled.FormatTextdirectionRToL
+import androidx.compose.material.icons.filled.Smartphone
+import androidx.compose.material.icons.filled.Tablet
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
 import androidx.compose.material3.Icon
 import androidx.compose.material3.Text
 import androidx.compose.material3.TextButton
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.dp
+import kotlin.math.max
+import kotlin.math.min
 
 enum class FontScale(val scale: Float) {
     Small(0.85f),
@@ -35,6 +51,39 @@
     onChangeLayoutDirection: () -> Unit,
     onChangeFontScale: () -> Unit,
 ) {
+    // The display we are emulating, if any.
+    var emulatedDisplayName by rememberSaveable { mutableStateOf<String?>(null) }
+    val emulatedDisplay =
+        emulatedDisplayName?.let { name -> EmulatedDisplays.firstOrNull { it.name == name } }
+
+    LaunchedEffect(emulatedDisplay) {
+        val wm = WindowManagerGlobal.getWindowManagerService()
+
+        val defaultDisplayId = Display.DEFAULT_DISPLAY
+        if (emulatedDisplay == null) {
+            wm.clearForcedDisplayDensityForUser(defaultDisplayId, UserHandle.myUserId())
+            wm.clearForcedDisplaySize(defaultDisplayId)
+        } else {
+            val density = emulatedDisplay.densityDpi
+
+            // Emulate the display and make sure that we use the maximum available space possible.
+            val initialSize = Point()
+            wm.getInitialDisplaySize(defaultDisplayId, initialSize)
+            val width = emulatedDisplay.width
+            val height = emulatedDisplay.height
+            val minOfSize = min(width, height)
+            val maxOfSize = max(width, height)
+            if (initialSize.x < initialSize.y) {
+                wm.setForcedDisplaySize(defaultDisplayId, minOfSize, maxOfSize)
+            } else {
+                wm.setForcedDisplaySize(defaultDisplayId, maxOfSize, minOfSize)
+            }
+            wm.setForcedDisplayDensityForUser(defaultDisplayId, density, UserHandle.myUserId())
+        }
+    }
+
+    // TODO(b/231131244): Fork FlowRow from Accompanist and use that instead to make sure that users
+    // don't miss any available configuration.
     LazyRow {
         // Dark/light theme.
         item {
@@ -82,5 +131,70 @@
                 }
             }
         }
+
+        // Display emulation.
+        EmulatedDisplays.forEach { display ->
+            item {
+                DisplayButton(
+                    display,
+                    emulatedDisplay == display,
+                    { emulatedDisplayName = it?.name },
+                )
+            }
+        }
     }
 }
+
+@Composable
+private fun DisplayButton(
+    display: EmulatedDisplay,
+    selected: Boolean,
+    onChangeEmulatedDisplay: (EmulatedDisplay?) -> Unit,
+) {
+    val onClick = {
+        if (selected) {
+            onChangeEmulatedDisplay(null)
+        } else {
+            onChangeEmulatedDisplay(display)
+        }
+    }
+
+    val content: @Composable RowScope.() -> Unit = {
+        Icon(display.icon, null)
+        Spacer(Modifier.width(8.dp))
+        Text(display.name)
+    }
+
+    if (selected) {
+        Button(onClick, contentPadding = ButtonDefaults.TextButtonContentPadding, content = content)
+    } else {
+        TextButton(onClick, content = content)
+    }
+}
+
+/** The displays that can be emulated from this Gallery app. */
+private val EmulatedDisplays =
+    listOf(
+        EmulatedDisplay(
+            "Phone",
+            Icons.Default.Smartphone,
+            width = 1440,
+            height = 3120,
+            densityDpi = 560,
+        ),
+        EmulatedDisplay(
+            "Tablet",
+            Icons.Default.Tablet,
+            width = 2560,
+            height = 1600,
+            densityDpi = 320,
+        ),
+    )
+
+private data class EmulatedDisplay(
+    val name: String,
+    val icon: ImageVector,
+    val width: Int,
+    val height: Int,
+    val densityDpi: Int,
+)
diff --git a/packages/SystemUI/compose/testing/src/com/android/systemui/testing/compose/ComposeScreenshotTestRule.kt b/packages/SystemUI/compose/testing/src/com/android/systemui/testing/compose/ComposeScreenshotTestRule.kt
index 7a0b1f1..e611e8b 100644
--- a/packages/SystemUI/compose/testing/src/com/android/systemui/testing/compose/ComposeScreenshotTestRule.kt
+++ b/packages/SystemUI/compose/testing/src/com/android/systemui/testing/compose/ComposeScreenshotTestRule.kt
@@ -24,22 +24,37 @@
 import androidx.compose.ui.test.onRoot
 import com.android.systemui.compose.theme.SystemUITheme
 import com.android.systemui.testing.screenshot.ScreenshotActivity
-import com.android.systemui.testing.screenshot.ScreenshotTestRule
-import com.android.systemui.testing.screenshot.ScreenshotTestSpec
+import com.android.systemui.testing.screenshot.SystemUIGoldenImagePathManager
+import com.android.systemui.testing.screenshot.UnitTestBitmapMatcher
+import com.android.systemui.testing.screenshot.drawIntoBitmap
 import org.junit.rules.RuleChain
 import org.junit.rules.TestRule
 import org.junit.runner.Description
 import org.junit.runners.model.Statement
+import platform.test.screenshot.DeviceEmulationRule
+import platform.test.screenshot.DeviceEmulationSpec
+import platform.test.screenshot.MaterialYouColorsRule
+import platform.test.screenshot.ScreenshotTestRule
+import platform.test.screenshot.getEmulatedDevicePathConfig
 
 /** A rule for Compose screenshot diff tests. */
-class ComposeScreenshotTestRule(testSpec: ScreenshotTestSpec) : TestRule {
+class ComposeScreenshotTestRule(emulationSpec: DeviceEmulationSpec) : TestRule {
+    private val colorsRule = MaterialYouColorsRule()
+    private val deviceEmulationRule = DeviceEmulationRule(emulationSpec)
+    private val screenshotRule =
+        ScreenshotTestRule(
+            SystemUIGoldenImagePathManager(getEmulatedDevicePathConfig(emulationSpec))
+        )
     private val composeRule = createAndroidComposeRule<ScreenshotActivity>()
-    private val screenshotRule = ScreenshotTestRule(testSpec)
-
-    private val delegate = RuleChain.outerRule(screenshotRule).around(composeRule)
+    private val delegateRule =
+        RuleChain.outerRule(colorsRule)
+            .around(deviceEmulationRule)
+            .around(screenshotRule)
+            .around(composeRule)
+    private val matcher = UnitTestBitmapMatcher
 
     override fun apply(base: Statement, description: Description): Statement {
-        return delegate.apply(base, description)
+        return delegateRule.apply(base, description)
     }
 
     /**
@@ -69,6 +84,6 @@
         composeRule.waitForIdle()
 
         val view = (composeRule.onRoot().fetchSemanticsNode().root as ViewRootForTest).view
-        screenshotRule.screenshotTest(goldenIdentifier, view)
+        screenshotRule.assertBitmapAgainstGolden(view.drawIntoBitmap(), goldenIdentifier, matcher)
     }
 }
diff --git a/packages/SystemUI/docs/camera.md b/packages/SystemUI/docs/camera.md
index cabc65c..a1c8458 100644
--- a/packages/SystemUI/docs/camera.md
+++ b/packages/SystemUI/docs/camera.md
@@ -1,34 +1,23 @@
 # How double-click power launches the camera
-
-_as of august 2020_
-
+_Last update: July 2022_
 
 ## Sequence of events
-
-
-
-1. [PhoneWindowManager.java](/services/core/java/com/android/server/policy/PhoneWindowManager.java) is responsible for all power button presses (see `interceptPowerKeyDown`). 
-2. Even though PWMgr has a lot of logic to detect all manner of power button multipresses and gestures, it also checks with GestureLauncherService, which is also [offered the chance](/services/core/java/com/android/server/policy/PhoneWindowManager.java#943) to [intercept](/services/core/java/com/android/server/GestureLauncherService.java#358) the power key.
-3. GLS is responsible for the camera timeout, and if it detects one, it [forwards it to the StatusBarManagerService](/services/core/java/com/android/server/GestureLauncherService.java#475) (which hands it off to SystemUI).
-4. Inside SystemUI, [onCameraLaunchDetected](/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java#3927) looks at the keyguard state and determines 
+1. [PhoneWindowManager.java](/services/core/java/com/android/server/policy/PhoneWindowManager.java) is responsible for all power button presses (see `interceptPowerKeyDown`) 
+2. Even though `PhoneWindowManager` has a lot of logic to detect all manner of power button multi-presses and gestures, it also checks with `GestureLauncherService`, which is also [offered the chance](/services/core/java/com/android/server/policy/PhoneWindowManager.java#943) to [intercept](/services/core/java/com/android/server/GestureLauncherService.java) the power key
+3. `GestureLauncherService` is responsible for the camera timeout, and if it detects one, it [forwards it to the StatusBarManagerService](/services/core/java/com/android/server/GestureLauncherService.java) (which hands it off to SystemUI)
+4. Inside SystemUI, `onCameraLaunchDetected` in [CentralSurfacesCommandQueueCallbacks.java](/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java) looks at the keyguard state and determines
     1. whether the camera is even allowed 
     2. whether the screen is on; if not, we need to delay until that happens
     3. whether the device is locked (defined as "keyguard is showing").
-5. If the device is unlocked (no keyguard), the camera is launched immediately. [Callsite in onCameraLaunchGestureDetected](/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java#4047).
-6. If the keyguard is up, however, [KeyguardBottomAreaView.launchCamera](/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java#477) takes over to handle the "secure camera" (a different intent, usually directing to the same app, but giving that app the cue to not allow access to the photo roll, etc).
-7. If the intent [would have to launch a resolver](/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java#480) (the user has multiple cameras installed and hasn’t chosen one to always launch for the `SECURE_CAMERA_INTENT`),
-    1. In order to show the resolver, the lockscreen "bouncer" (authentication method) [is first presented](/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java#523).
-8. Otherwise (just one secure camera), [it is launched](/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java#501) (with some window animation gymnastics).
+5. If the device is unlocked (no keyguard), the camera is launched immediately
+6. If the keyguard is up, however, [NotificationPanelViewController.launchCamera](/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java) takes over to handle the "secure camera" (a different intent, usually directing to the same app, but giving that app the cue to not allow access to the photo roll, etc).
+7. If the intent would have to launch a resolver (because the user has multiple camera apps installed and has not chosen one to always launch for the `SECURE_CAMERA_INTENT`, then - in order to show the resolver, the lockscreen "bouncer" (authentication method) is first presented
+8. Otherwise (just one secure camera), it is launched
 
-
-## Which intent launches?
-
-
-
-*   If the keyguard is not showing (device is unlocked)
-    *   `CameraIntents.getInsecureCameraIntent()`, defined to be `MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA`. 
-    *   [Callsite](/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java#3950) in StatusBar.java.
-*   If the keyguard is showing (device locked)
-    *   [KeyguardBottomAreaView.getCameraIntent()](/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java#366) is consulted, which allows the "keyguard right button" (which we don’t actually show) to control the camera intent. The [default implementation](/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java#831) returns one of `CameraIntents.getInsecureCameraIntent()` or `CameraIntents.getSecureCameraIntent()`, which are `MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA` and `MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE`, respectively. 
-    *   [Callsite](/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java#523) in KeyguardBottomAreaView.java.
-*   Note that starting in Android 12, as required by some OEMs, if the special string resource `config_cameraGesturePackage` is nonempty, this will be treated as a package name to be added to the insecure camera intent, constraining the invocation to that single app and typically preventing implicit intent resolution. This package must be on the device or the camera gesture will no longer work properly.
\ No newline at end of file
+## Which intent launches the camera app?
+[CameraGestureHelper](/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt) encapsulate this logic. Roughly:
+* If the keyguard is not showing (device is unlocked)
+    *   `CameraIntents.getInsecureCameraIntent()`, defined to be `MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA`.
+* If the keyguard is showing (device is locked)
+    *   one of `CameraIntents.getInsecureCameraIntent()` or `CameraIntents.getSecureCameraIntent()`, which are `MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA` and `MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE`, respectively
+* Note that starting in Android 12, as required by some OEMs, if the special string resource `config_cameraGesturePackage` is nonempty, this will be treated as a package name to be added to the insecure camera intent, constraining the invocation to that single app and typically preventing implicit intent resolution. This package must be on the device or the camera gesture will no longer work properly
diff --git a/packages/SystemUI/docs/user-file-manager.md b/packages/SystemUI/docs/user-file-manager.md
new file mode 100644
index 0000000..52fa206
--- /dev/null
+++ b/packages/SystemUI/docs/user-file-manager.md
@@ -0,0 +1,33 @@
+# UserFileManager
+
+This class is used to generate file paths and SharedPreferences that is compatible for specific OS
+users in SystemUI. Due to constraints in SystemUI, we can only read/write files as the system user.
+Therefore, for secondary users, we want to store secondary user specific files into the system user
+directory.
+
+
+## Usages
+
+Inject UserFileManager into your class.
+
+### fun getFile(fileName: String, userId: Int): File
+Add a file name and user id. You can retrieve the current user id from UserTracker. This will
+return a java.io File object that contains the file path to write/read to.
+
+i.e. `fileManager.getFile("example.xml", userTracker.userId)`
+
+### fun getSharedPreferences(fileName: String, mode: Int, userId: Int): SharedPreferences
+Add a file name, user id, and PreferencesMode. You can retrieve the current user id from
+UserTracker. This returns SharedPreferences object that is tied to the specific user. Note that if
+the SharedPreferences file does not exist, one will be created automatically. See
+[SharedPreferences documentation](https://developer.android.com/reference/android/content/Context#getSharedPreferences(java.lang.String,%20int))
+for more details.
+
+i.e. `fileManager.getSharedPreferences("prefs.xml", userTracker.userId, 0)`
+
+## Handling User Removal
+
+This class will listen for Intent.ACTION_USER_REMOVED and remove directories that no longer
+corresponding to active users. Additionally, upon start up, the class will run the same query for
+deletion to ensure that there is no stale data.
+
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
index cafdc86..1008481 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
@@ -61,7 +61,7 @@
 
     /** Initializes various rendering parameters. If never called, provides reasonable defaults. */
     fun initialize(resources: Resources, dozeFraction: Float, foldFraction: Float) {
-        events.onColorPaletteChanged(resources)
+        events.onColorPaletteChanged(resources, RegionDarkness.DEFAULT, RegionDarkness.DEFAULT)
         animations.doze(dozeFraction)
         animations.fold(foldFraction)
         events.onTimeTick()
@@ -89,7 +89,11 @@
     fun onFontSettingChanged() { }
 
     /** Call whenever the color palette should update */
-    fun onColorPaletteChanged(resources: Resources) { }
+    fun onColorPaletteChanged(
+            resources: Resources,
+            smallClockIsDark: RegionDarkness,
+            largeClockIsDark: RegionDarkness
+    ) { }
 }
 
 /** Methods which trigger various clock animations */
@@ -112,3 +116,12 @@
     val clockId: ClockId,
     val name: String
 )
+
+/**
+ * Enum for whether clock region is dark or light.
+ */
+enum class RegionDarkness(val isDark: Boolean) {
+    DEFAULT(false),
+    DARK(true),
+    LIGHT(false)
+}
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index 6ffd661..84ebe77 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -8,9 +8,9 @@
 -keep class com.android.systemui.statusbar.car.CarStatusBar
 -keep class com.android.systemui.statusbar.phone.CentralSurfaces
 -keep class com.android.systemui.statusbar.tv.TvStatusBar
--keep class com.android.systemui.car.CarSystemUIFactory
--keep class com.android.systemui.SystemUIFactory
--keep class com.android.systemui.tv.TvSystemUIFactory
+-keep class ** extends com.android.systemui.SystemUIInitializer {
+    *;
+}
 -keep class * extends com.android.systemui.CoreStartable
 -keep class * implements com.android.systemui.CoreStartable$Injector
 
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_bouncer_user_switcher.xml b/packages/SystemUI/res-keyguard/layout/keyguard_bouncer_user_switcher.xml
index 36035fc..01e3de2 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_bouncer_user_switcher.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_bouncer_user_switcher.xml
@@ -45,6 +45,7 @@
           style="@style/Bouncer.UserSwitcher.Spinner.Header"
           android:clickable="false"
           android:id="@+id/user_switcher_header"
+          android:textDirection="locale"
           android:layout_width="@dimen/bouncer_user_switcher_width"
           android:layout_height="wrap_content" />
     </LinearLayout>>
diff --git a/packages/SystemUI/res/drawable/dream_overlay_camera_off.xml b/packages/SystemUI/res/drawable/dream_overlay_camera_off.xml
new file mode 100644
index 0000000..159655e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/dream_overlay_camera_off.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 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
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="56dp"
+    android:height="24dp"
+    android:viewportWidth="56"
+    android:viewportHeight="24">
+  <path
+      android:pathData="M12,0L44,0A12,12 0,0 1,56 12L56,12A12,12 0,0 1,44 24L12,24A12,12 0,0 1,0 12L0,12A12,12 0,0 1,12 0z"
+      android:fillColor="#5F6368"/>
+  <path
+      android:pathData="M21.872,5.873L20.926,6.813L21.492,7.38C21.392,7.566 21.332,7.773 21.332,8V16C21.332,16.733 21.932,17.333 22.666,17.333H30.666C30.892,17.333 31.099,17.273 31.286,17.173L33.186,19.073L34.126,18.133L31.999,16L21.872,5.873ZM31.999,10.986V8C31.999,7.266 31.399,6.666 30.666,6.666H24.552L25.886,8H30.666V12.78L31.999,14.113V13.013L34.666,15.666V8.333L31.999,10.986ZM22.666,8.553V16H30.112L22.666,8.553Z"
+      android:fillColor="#ffffff"
+      android:fillType="evenOdd"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/dream_overlay_mic_and_camera_off.xml b/packages/SystemUI/res/drawable/dream_overlay_mic_and_camera_off.xml
new file mode 100644
index 0000000..087dde7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/dream_overlay_mic_and_camera_off.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 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
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="56dp"
+    android:height="24dp"
+    android:viewportWidth="56"
+    android:viewportHeight="24">
+  <path
+      android:pathData="M12,0L44,0A12,12 0,0 1,56 12L56,12A12,12 0,0 1,44 24L12,24A12,12 0,0 1,0 12L0,12A12,12 0,0 1,12 0z"
+      android:fillColor="#5F6368"/>
+  <path
+      android:pathData="M15.332,7.333C15.332,6.966 15.632,6.666 15.999,6.666C16.366,6.666 16.666,6.966 16.666,7.333V10.78L17.879,11.993C17.952,11.786 17.999,11.566 17.999,11.333V7.333C17.999,6.226 17.106,5.333 15.999,5.333C14.892,5.333 13.999,6.226 13.999,7.333V8.113L15.332,9.446V7.333ZM9.872,5.873L8.926,6.813L16.692,14.58C16.472,14.633 16.239,14.666 15.999,14.666C14.159,14.666 12.666,13.173 12.666,11.333H11.332C11.332,13.686 13.072,15.62 15.332,15.946V18H16.666V15.946C17.046,15.893 17.412,15.786 17.759,15.64L21.186,19.066L22.126,18.126L9.872,5.873ZM19.332,11.333H20.666C20.666,12.313 20.359,13.213 19.846,13.96L18.872,12.986C19.159,12.5 19.332,11.94 19.332,11.333Z"
+      android:fillColor="#ffffff"
+      android:fillType="evenOdd"/>
+  <path
+      android:pathData="M33.872,5.873L32.926,6.813L33.492,7.38C33.392,7.566 33.332,7.773 33.332,8V16C33.332,16.733 33.932,17.333 34.666,17.333H42.666C42.892,17.333 43.099,17.273 43.286,17.173L45.186,19.073L46.126,18.133L43.999,16L33.872,5.873ZM43.999,10.986V8C43.999,7.266 43.399,6.666 42.666,6.666H36.552L37.886,8H42.666V12.78L43.999,14.113V13.013L46.666,15.666V8.333L43.999,10.986ZM34.666,8.553V16H42.112L34.666,8.553Z"
+      android:fillColor="#ffffff"
+      android:fillType="evenOdd"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/dream_overlay_mic_off.xml b/packages/SystemUI/res/drawable/dream_overlay_mic_off.xml
new file mode 100644
index 0000000..693250d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/dream_overlay_mic_off.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 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
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="56dp"
+    android:height="24dp"
+    android:viewportWidth="56"
+    android:viewportHeight="24">
+  <path
+      android:pathData="M12,0L44,0A12,12 0,0 1,56 12L56,12A12,12 0,0 1,44 24L12,24A12,12 0,0 1,0 12L0,12A12,12 0,0 1,12 0z"
+      android:fillColor="#5F6368"/>
+  <path
+      android:pathData="M27.807,7.133C27.807,6.767 28.107,6.467 28.473,6.467C28.84,6.467 29.14,6.767 29.14,7.133V10.58L30.353,11.793C30.427,11.587 30.473,11.367 30.473,11.133V7.133C30.473,6.027 29.58,5.133 28.473,5.133C27.367,5.133 26.473,6.027 26.473,7.133V7.913L27.807,9.247V7.133ZM22.347,5.673L21.4,6.613L29.167,14.38C28.947,14.433 28.713,14.467 28.473,14.467C26.633,14.467 25.14,12.973 25.14,11.133H23.807C23.807,13.487 25.547,15.42 27.807,15.747V17.8H29.14V15.747C29.52,15.693 29.887,15.587 30.233,15.44L33.66,18.867L34.6,17.927L22.347,5.673ZM31.807,11.133H33.14C33.14,12.113 32.833,13.013 32.32,13.76L31.347,12.787C31.633,12.3 31.807,11.74 31.807,11.133Z"
+      android:fillColor="#ffffff"
+      android:fillType="evenOdd"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_media_pause_container.xml b/packages/SystemUI/res/drawable/ic_media_pause_container.xml
index b92e635..ea9eb8c 100644
--- a/packages/SystemUI/res/drawable/ic_media_pause_container.xml
+++ b/packages/SystemUI/res/drawable/ic_media_pause_container.xml
@@ -22,11 +22,6 @@
                 android:viewportHeight="48"

                 android:viewportWidth="48">

             <group android:name="_R_G">

-                <group android:name="_R_G_L_1_G"

-                       android:translateX="24"

-                       android:translateY="24"

-                       android:scaleX="0.5"

-                       android:scaleY="0.5"/>

                 <group android:name="_R_G_L_0_G"

                        android:translateX="24"

                        android:translateY="24"

@@ -46,7 +41,7 @@
         <aapt:attr name="android:animation">

             <set android:ordering="together">

                 <objectAnimator android:propertyName="pathData"

-                                android:duration="500"

+                                android:duration="250"

                                 android:startOffset="0"

                                 android:valueFrom="M48 -16 C48,-16 48,16 48,16 C48,33.67 33.67,48 16,48 C16,48 -16,48 -16,48 C-33.67,48 -48,33.67 -48,16 C-48,16 -48,-16 -48,-16 C-48,-33.67 -33.67,-48 -16,-48 C-16,-48 16,-48 16,-48 C33.67,-48 48,-33.67 48,-16c "

                                 android:valueTo="M48 0.25 C48,0.25 48,0 48,0 C47.75,26 31.25,48 0,48 C0,48 0,48 0,48 C-30,48 -48,25.75 -48,-0.25 C-48,-0.25 -48,-0.25 -48,-0.25 C-47.75,-23.5 -32.25,-47.75 0.5,-48 C0.5,-48 0.5,-48 0.5,-48 C28,-47.75 47.75,-29.75 48,0.25c "

@@ -62,7 +57,7 @@
         <aapt:attr name="android:animation">

             <set android:ordering="together">

                 <objectAnimator android:propertyName="translateX"

-                                android:duration="517"

+                                android:duration="267"

                                 android:startOffset="0"

                                 android:valueFrom="0"

                                 android:valueTo="1"

@@ -70,4 +65,4 @@
             </set>

         </aapt:attr>

     </target>

-</animated-vector>
\ No newline at end of file
+</animated-vector>

diff --git a/packages/SystemUI/res/drawable/ic_media_play_container.xml b/packages/SystemUI/res/drawable/ic_media_play_container.xml
index 2fc9fc8..4cb011a 100644
--- a/packages/SystemUI/res/drawable/ic_media_play_container.xml
+++ b/packages/SystemUI/res/drawable/ic_media_play_container.xml
@@ -41,7 +41,7 @@
         <aapt:attr name="android:animation">

             <set android:ordering="together">

                 <objectAnimator android:propertyName="pathData"

-                                android:duration="500"

+                                android:duration="250"

                                 android:startOffset="0"

                                 android:valueFrom="M48 0.25 C48,0.25 48,0 48,0 C47.75,26 31.25,48 0,48 C0,48 0,48 0,48 C-30,48 -48,25.75 -48,-0.25 C-48,-0.25 -48,-0.25 -48,-0.25 C-47.75,-23.5 -32.25,-47.75 0.5,-48 C0.5,-48 0.5,-48 0.5,-48 C28,-47.75 47.75,-29.75 48,0.25c "

                                 android:valueTo="M48 -16 C48,-16 48,16 48,16 C48,33.67 33.67,48 16,48 C16,48 -16,48 -16,48 C-33.67,48 -48,33.67 -48,16 C-48,16 -48,-16 -48,-16 C-48,-33.67 -33.67,-48 -16,-48 C-16,-48 16,-48 16,-48 C33.67,-48 48,-33.67 48,-16c "

@@ -57,7 +57,7 @@
         <aapt:attr name="android:animation">

             <set android:ordering="together">

                 <objectAnimator android:propertyName="translateX"

-                                android:duration="517"

+                                android:duration="267"

                                 android:startOffset="0"

                                 android:valueFrom="0"

                                 android:valueTo="1"

@@ -65,4 +65,4 @@
             </set>

         </aapt:attr>

     </target>

-</animated-vector>
\ No newline at end of file
+</animated-vector>

diff --git a/packages/SystemUI/res/drawable/qs_airplane_icon_off.xml b/packages/SystemUI/res/drawable/qs_airplane_icon_off.xml
new file mode 100644
index 0000000..f239a8d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_airplane_icon_off.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 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.
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="183"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M-1.5 -3.02 C-1.5,-3.02 -1.5,-8.5 -1.5,-8.5 C-1.5,-9.33 -0.83,-10 0,-10 C0.83,-10 1.5,-9.33 1.5,-8.5 C1.5,-8.5 1.5,-3 1.5,-3 C1.5,-3 10,2 10,2 C10,2 10,4 10,4 C10,4 1.51,1.49 1.51,1.49 C1.51,1.49 -1.5,-3.02 -1.5,-3.02c  M1.5 1.5 C1.5,1.5 -1.5,-3 -1.5,-3 C-1.5,-3 -10,2 -10,2 C-10,2 -10,4 -10,4 C-10,4 -1.5,1.5 -1.5,1.5 C-1.5,1.5 -1.5,7 -1.5,7 C-1.5,7 -4,8.5 -4,8.5 C-4,8.5 -4,10 -4,10 C-4,10 0,9 0,9 C0,9 4,10 4,10 C4,10 4,8.5 4,8.5 C4,8.5 1.5,7 1.5,7 C1.5,7 1.5,1.5 1.5,1.5c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_airplane_icon_on.xml b/packages/SystemUI/res/drawable/qs_airplane_icon_on.xml
new file mode 100644
index 0000000..d46fafa
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_airplane_icon_on.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 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.
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_1_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="667"
+                    android:pathData="M 12.125,34.75C 12.104,30.958 12.021,15.792 12,12"
+                    android:propertyName="translateXY"
+                    android:propertyXName="translateX"
+                    android:propertyYName="translateY"
+                    android:startOffset="0">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="517"
+                    android:pathData="M 12,12C 12.021,8.312 12.104,-6.436999999999999 12.125,-10.125"
+                    android:propertyName="translateXY"
+                    android:propertyXName="translateX"
+                    android:propertyYName="translateY"
+                    android:startOffset="0">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="683"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_1_G"
+                    android:translateX="12.125"
+                    android:translateY="34.75">
+                    <path
+                        android:name="_R_G_L_1_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M10 4 C10,4 10,2 10,2 C10,2 1.5,-3 1.5,-3 C1.5,-3 1.5,-8.5 1.5,-8.5 C1.5,-9.33 0.83,-10 0,-10 C-0.83,-10 -1.5,-9.33 -1.5,-8.5 C-1.5,-8.5 -1.5,-3 -1.5,-3 C-1.5,-3 -10,2 -10,2 C-10,2 -10,4 -10,4 C-10,4 -1.5,1.5 -1.5,1.5 C-1.5,1.5 -1.5,7 -1.5,7 C-1.5,7 -4,8.5 -4,8.5 C-4,8.5 -4,10 -4,10 C-4,10 0,9 0,9 C0,9 4,10 4,10 C4,10 4,8.5 4,8.5 C4,8.5 1.5,7 1.5,7 C1.5,7 1.5,1.5 1.5,1.5 C1.5,1.5 10,4 10,4c " />
+                </group>
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M-1.5 -3.02 C-1.5,-3.02 -1.5,-8.5 -1.5,-8.5 C-1.5,-9.33 -0.83,-10 0,-10 C0.83,-10 1.5,-9.33 1.5,-8.5 C1.5,-8.5 1.5,-3 1.5,-3 C1.5,-3 10,2 10,2 C10,2 10,4 10,4 C10,4 1.51,1.49 1.51,1.49 C1.51,1.49 -1.5,-3.02 -1.5,-3.02c  M1.5 1.5 C1.5,1.5 -1.5,-3 -1.5,-3 C-1.5,-3 -10,2 -10,2 C-10,2 -10,4 -10,4 C-10,4 -1.5,1.5 -1.5,1.5 C-1.5,1.5 -1.5,7 -1.5,7 C-1.5,7 -4,8.5 -4,8.5 C-4,8.5 -4,10 -4,10 C-4,10 0,9 0,9 C0,9 4,10 4,10 C4,10 4,8.5 4,8.5 C4,8.5 1.5,7 1.5,7 C1.5,7 1.5,1.5 1.5,1.5c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_battery_saver_icon_off.xml b/packages/SystemUI/res/drawable/qs_battery_saver_icon_off.xml
new file mode 100644
index 0000000..7b9f23d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_battery_saver_icon_off.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 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.
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="183"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:pathData=" M3.67 -8 C3.67,-8 2,-8 2,-8 C2,-8 2,-10 2,-10 C2,-10 -2,-10 -2,-10 C-2,-10 -2,-8 -2,-8 C-2,-8 -3.67,-8 -3.67,-8 C-4.4,-8 -5,-7.4 -5,-6.67 C-5,-6.67 -5,8.66 -5,8.66 C-5,9.4 -4.4,10 -3.67,10 C-3.67,10 3.66,10 3.66,10 C4.4,10 5,9.4 5,8.67 C5,8.67 5,-6.67 5,-6.67 C5,-7.4 4.4,-8 3.67,-8c "
+                        android:strokeAlpha="1"
+                        android:strokeColor="#ffffff"
+                        android:strokeLineCap="round"
+                        android:strokeLineJoin="round"
+                        android:strokeWidth="2" />
+                    <path
+                        android:name="_R_G_L_0_G_D_1_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M2 -10 C2,-10 2,-7 2,-7 C2,-7 -2,-7 -2,-7 C-2,-7 -2,-10 -2,-10 C-2,-10 2,-10 2,-10c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_2_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M3 2 C3,2 1,2 1,2 C1,2 1,4 1,4 C1,4 -1,4 -1,4 C-1,4 -1,2 -1,2 C-1,2 -3,2 -3,2 C-3,2 -3,0 -3,0 C-3,0 -1,0 -1,0 C-1,0 -1,-2 -1,-2 C-1,-2 1,-2 1,-2 C1,-2 1,0 1,0 C1,0 3,0 3,0 C3,0 3,2 3,2c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_battery_saver_icon_on.xml b/packages/SystemUI/res/drawable/qs_battery_saver_icon_on.xml
new file mode 100644
index 0000000..5e4af39
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_battery_saver_icon_on.xml
@@ -0,0 +1,636 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 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.
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_4_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="317"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="1"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="317"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_4_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:pathData="M 0,0.875C 0,-0.9690000000000001 0,-8.344000000000001 0,-10.188"
+                    android:propertyName="translateXY"
+                    android:propertyXName="translateX"
+                    android:propertyYName="translateY"
+                    android:startOffset="0">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c1,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_4_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="112"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c1,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_3_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="250"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="217"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="333"
+                    android:valueFrom="1"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="550"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_3_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="83"
+                    android:pathData="M -0.875,9C -0.854,6.156000000000001 -0.896,11.844 -0.875,9"
+                    android:propertyName="translateXY"
+                    android:propertyXName="translateX"
+                    android:propertyYName="translateY"
+                    android:startOffset="0">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="550"
+                    android:pathData="M -0.875,9C -0.854,6.156000000000001 -0.771,-5.218 -0.75,-8.062"
+                    android:propertyName="translateXY"
+                    android:propertyXName="translateX"
+                    android:propertyYName="translateY"
+                    android:startOffset="83">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_3_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="67"
+                    android:valueTo="67"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="550"
+                    android:propertyName="rotation"
+                    android:startOffset="83"
+                    android:valueFrom="67"
+                    android:valueTo="192"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_2_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="417"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="267"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="500"
+                    android:valueFrom="1"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="767"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_2_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="250"
+                    android:pathData="M 2.125,9.375C 2.146,6.468999999999999 2.104,12.281 2.125,9.375"
+                    android:propertyName="translateXY"
+                    android:propertyXName="translateX"
+                    android:propertyYName="translateY"
+                    android:startOffset="0">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="600"
+                    android:pathData="M 2.125,9.375C 2.146,6.468999999999999 2.229,-5.155999999999999 2.25,-8.062"
+                    android:propertyName="translateXY"
+                    android:propertyXName="translateX"
+                    android:propertyYName="translateY"
+                    android:startOffset="250">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_2_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="28"
+                    android:valueTo="28"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="600"
+                    android:propertyName="rotation"
+                    android:startOffset="250"
+                    android:valueFrom="28"
+                    android:valueTo="153"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_1_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="533"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="533"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="617"
+                    android:valueFrom="1"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="867"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_1_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="350"
+                    android:pathData="M -2,10C -2,6.99 -2,13.01 -2,10"
+                    android:propertyName="translateXY"
+                    android:propertyXName="translateX"
+                    android:propertyYName="translateY"
+                    android:startOffset="0">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="600"
+                    android:pathData="M -2,10C -2,6.99 -2,-5.052 -2,-8.062"
+                    android:propertyName="translateXY"
+                    android:propertyXName="translateX"
+                    android:propertyYName="translateY"
+                    android:startOffset="350">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_1_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="350"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="28"
+                    android:valueTo="28"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="600"
+                    android:propertyName="rotation"
+                    android:startOffset="350"
+                    android:valueFrom="28"
+                    android:valueTo="153"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="883"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="883"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="667"
+                    android:pathData="M 0,11.5C 0,9.729 0,13.271 0,11.5"
+                    android:propertyName="translateXY"
+                    android:propertyXName="translateX"
+                    android:propertyYName="translateY"
+                    android:startOffset="0">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="667"
+                    android:pathData="M 0,11.5C 0,9.729 0,2.646 0,0.875"
+                    android:propertyName="translateXY"
+                    android:propertyXName="translateX"
+                    android:propertyYName="translateY"
+                    android:startOffset="667">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="667"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="-48"
+                    android:valueTo="-48"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="667"
+                    android:propertyName="rotation"
+                    android:startOffset="667"
+                    android:valueFrom="-48"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="1350"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_5_G"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_5_G_D_0_P_0"
+                        android:pathData=" M3.67 -8 C3.67,-8 2,-8 2,-8 C2,-8 2,-10 2,-10 C2,-10 -2,-10 -2,-10 C-2,-10 -2,-8 -2,-8 C-2,-8 -3.67,-8 -3.67,-8 C-4.4,-8 -5,-7.4 -5,-6.67 C-5,-6.67 -5,8.66 -5,8.66 C-5,9.4 -4.4,10 -3.67,10 C-3.67,10 3.66,10 3.66,10 C4.4,10 5,9.4 5,8.67 C5,8.67 5,-6.67 5,-6.67 C5,-7.4 4.4,-8 3.67,-8c "
+                        android:strokeAlpha="1"
+                        android:strokeColor="#ffffff"
+                        android:strokeLineCap="round"
+                        android:strokeLineJoin="round"
+                        android:strokeWidth="2" />
+                    <path
+                        android:name="_R_G_L_5_G_D_1_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M2 -10 C2,-10 2,-7 2,-7 C2,-7 -2,-7 -2,-7 C-2,-7 -2,-10 -2,-10 C-2,-10 2,-10 2,-10c " />
+                </group>
+                <group
+                    android:name="_R_G_L_4_G_N_6_T_0"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <group
+                        android:name="_R_G_L_4_G_T_1"
+                        android:rotation="0"
+                        android:translateX="0"
+                        android:translateY="0.875">
+                        <group
+                            android:name="_R_G_L_4_G"
+                            android:translateY="-0.875">
+                            <path
+                                android:name="_R_G_L_4_G_D_0_P_0"
+                                android:fillAlpha="1"
+                                android:fillColor="#ffffff"
+                                android:fillType="nonZero"
+                                android:pathData=" M3 2 C3,2 1,2 1,2 C1,2 1,4 1,4 C1,4 -1,4 -1,4 C-1,4 -1,2 -1,2 C-1,2 -3,2 -3,2 C-3,2 -3,0 -3,0 C-3,0 -1,0 -1,0 C-1,0 -1,-2 -1,-2 C-1,-2 1,-2 1,-2 C1,-2 1,0 1,0 C1,0 3,0 3,0 C3,0 3,2 3,2c " />
+                        </group>
+                    </group>
+                </group>
+                <group
+                    android:name="_R_G_L_3_G_N_6_T_0"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <group
+                        android:name="_R_G_L_3_G_T_1"
+                        android:rotation="67"
+                        android:scaleX="0.7"
+                        android:scaleY="0.7"
+                        android:translateX="-0.875"
+                        android:translateY="9">
+                        <group
+                            android:name="_R_G_L_3_G"
+                            android:translateY="-0.875">
+                            <path
+                                android:name="_R_G_L_3_G_D_0_P_0"
+                                android:fillAlpha="0"
+                                android:fillColor="#ffffff"
+                                android:fillType="nonZero"
+                                android:pathData=" M3 2 C3,2 1,2 1,2 C1,2 1,4 1,4 C1,4 -1,4 -1,4 C-1,4 -1,2 -1,2 C-1,2 -3,2 -3,2 C-3,2 -3,0 -3,0 C-3,0 -1,0 -1,0 C-1,0 -1,-2 -1,-2 C-1,-2 1,-2 1,-2 C1,-2 1,0 1,0 C1,0 3,0 3,0 C3,0 3,2 3,2c " />
+                        </group>
+                    </group>
+                </group>
+                <group
+                    android:name="_R_G_L_2_G_N_6_T_0"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <group
+                        android:name="_R_G_L_2_G_T_1"
+                        android:rotation="28"
+                        android:scaleX="0.85"
+                        android:scaleY="0.85"
+                        android:translateX="2.125"
+                        android:translateY="9.375">
+                        <group
+                            android:name="_R_G_L_2_G"
+                            android:translateY="-0.875">
+                            <path
+                                android:name="_R_G_L_2_G_D_0_P_0"
+                                android:fillAlpha="0"
+                                android:fillColor="#ffffff"
+                                android:fillType="nonZero"
+                                android:pathData=" M3 2 C3,2 1,2 1,2 C1,2 1,4 1,4 C1,4 -1,4 -1,4 C-1,4 -1,2 -1,2 C-1,2 -3,2 -3,2 C-3,2 -3,0 -3,0 C-3,0 -1,0 -1,0 C-1,0 -1,-2 -1,-2 C-1,-2 1,-2 1,-2 C1,-2 1,0 1,0 C1,0 3,0 3,0 C3,0 3,2 3,2c " />
+                        </group>
+                    </group>
+                </group>
+                <group
+                    android:name="_R_G_L_1_G_N_6_T_0"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <group
+                        android:name="_R_G_L_1_G_T_1"
+                        android:rotation="28"
+                        android:scaleX="0.55"
+                        android:scaleY="0.55"
+                        android:translateX="-2"
+                        android:translateY="10">
+                        <group
+                            android:name="_R_G_L_1_G"
+                            android:translateY="-0.875">
+                            <path
+                                android:name="_R_G_L_1_G_D_0_P_0"
+                                android:fillAlpha="0"
+                                android:fillColor="#ffffff"
+                                android:fillType="nonZero"
+                                android:pathData=" M3 2 C3,2 1,2 1,2 C1,2 1,4 1,4 C1,4 -1,4 -1,4 C-1,4 -1,2 -1,2 C-1,2 -3,2 -3,2 C-3,2 -3,0 -3,0 C-3,0 -1,0 -1,0 C-1,0 -1,-2 -1,-2 C-1,-2 1,-2 1,-2 C1,-2 1,0 1,0 C1,0 3,0 3,0 C3,0 3,2 3,2c " />
+                        </group>
+                    </group>
+                </group>
+                <group
+                    android:name="_R_G_L_0_G_N_6_T_0"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <group
+                        android:name="_R_G_L_0_G_T_1"
+                        android:rotation="-48"
+                        android:translateX="0"
+                        android:translateY="11.5">
+                        <group
+                            android:name="_R_G_L_0_G"
+                            android:translateY="-0.875">
+                            <path
+                                android:name="_R_G_L_0_G_D_0_P_0"
+                                android:fillAlpha="0"
+                                android:fillColor="#ffffff"
+                                android:fillType="nonZero"
+                                android:pathData=" M3 2 C3,2 1,2 1,2 C1,2 1,4 1,4 C1,4 -1,4 -1,4 C-1,4 -1,2 -1,2 C-1,2 -3,2 -3,2 C-3,2 -3,0 -3,0 C-3,0 -1,0 -1,0 C-1,0 -1,-2 -1,-2 C-1,-2 1,-2 1,-2 C1,-2 1,0 1,0 C1,0 3,0 3,0 C3,0 3,2 3,2c " />
+                        </group>
+                    </group>
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_camera_access_icon_off.xml b/packages/SystemUI/res/drawable/qs_camera_access_icon_off.xml
new file mode 100644
index 0000000..8f9ecbe
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_camera_access_icon_off.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 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
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M5 1.3 C5,1.3 8.35,4.63 8.35,4.63 C8.35,4.63 8.35,-4.58 8.35,-4.58 C8.35,-4.58 5,-1.25 5,-1.25 C5,-1.25 5,-5 5,-5 C5,-5.92 4.25,-6.67 3.33,-6.67 C3.33,-6.67 -6.84,-6.68 -6.84,-6.68 C-6.54,-6.37 -6.07,-5.56 -5.49,-5 C-5.49,-5 3.33,-5 3.33,-5 C3.33,-5 3.33,-1.91 3.33,-1.91 C3.33,-1.91 3.32,3.73 3.32,3.73 C3.32,3.73 5,5.23 5,5.23 C5,5.23 5,2.14 5,2.14 C5,2.14 5,1.3 5,1.3c M3.34 5 C3.34,5 -6.67,5 -6.67,5 C-6.67,5 -6.67,-5.01 -6.67,-5.01 C-6.67,-5.01 -5.5,-5 -5.5,-5 C-5.98,-5.57 -6.46,-6.23 -6.83,-6.68 C-7.84,-6.64 -8.34,-5.77 -8.34,-5.01 C-8.34,-5.01 -8.34,5 -8.34,5 C-8.34,5.91 -7.58,6.66 -6.67,6.66 C-6.67,6.66 3.34,6.66 3.34,6.66 C4.13,6.66 4.88,6.1 5,5.23 C4.73,4.96 3.73,4.13 3.34,3.73 C3.34,3.73 3.34,5 3.34,5c "
+                    android:valueTo="M5 1.3 C5,1.3 8.35,4.63 8.35,4.63 C8.35,4.63 8.35,-4.58 8.35,-4.58 C8.35,-4.58 5,-1.25 5,-1.25 C5,-1.25 5,-5 5,-5 C5,-5.92 4.25,-6.67 3.33,-6.67 C3.33,-6.67 -4.28,-6.67 -4.28,-6.67 C-3.98,-6.36 -3.13,-5.56 -2.55,-4.99 C-2.55,-4.99 3.33,-5 3.33,-5 C3.33,-5 3.33,-1.91 3.33,-1.91 C3.33,-1.91 3.33,0.9 3.33,0.9 C3.33,0.9 5.01,2.59 5.01,2.59 C5.01,2.59 5,2.14 5,2.14 C5,2.14 5,1.3 5,1.3c M3.34 5 C3.34,5 -6.67,5 -6.67,5 C-6.67,5 -6.67,-5.01 -6.67,-5.01 C-6.67,-5.01 -5.5,-5 -5.5,-5 C-6.02,-5.5 -6.69,-6.17 -7.12,-6.61 C-7.82,-6.41 -8.34,-5.77 -8.34,-5.01 C-8.34,-5.01 -8.34,5 -8.34,5 C-8.34,5.91 -7.58,6.66 -6.67,6.66 C-6.67,6.66 3.34,6.66 3.34,6.66 C4.13,6.66 4.79,6.11 4.97,5.37 C4.7,5.1 3.73,4.13 3.34,3.73 C3.34,3.73 3.34,5 3.34,5c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_1_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_1_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M-10.96 -7.79 C-10.96,-7.79 -10.96,-7.79 -10.96,-7.79 C-10.96,-7.79 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 -10.96,-7.79 -10.96,-7.79c "
+                    android:valueTo="M7.44 10.61 C7.44,10.61 -10.96,-7.79 -10.96,-7.79 C-10.96,-7.79 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 8.84,9.21 8.84,9.21 C8.84,9.21 7.44,10.61 7.44,10.61c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="183"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M5 1.3 C5,1.3 8.35,4.63 8.35,4.63 C8.35,4.63 8.35,-4.58 8.35,-4.58 C8.35,-4.58 5,-1.25 5,-1.25 C5,-1.25 5,-5 5,-5 C5,-5.92 4.25,-6.67 3.33,-6.67 C3.33,-6.67 -6.84,-6.68 -6.84,-6.68 C-6.54,-6.37 -6.07,-5.56 -5.49,-5 C-5.49,-5 3.33,-5 3.33,-5 C3.33,-5 3.33,-1.91 3.33,-1.91 C3.33,-1.91 3.32,3.73 3.32,3.73 C3.32,3.73 5,5.23 5,5.23 C5,5.23 5,2.14 5,2.14 C5,2.14 5,1.3 5,1.3c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_1_P_0"
+                        android:fillAlpha="0"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M-10.96 -7.79 C-10.96,-7.79 -10.96,-7.79 -10.96,-7.79 C-10.96,-7.79 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 -10.96,-7.79 -10.96,-7.79c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_camera_access_icon_on.xml b/packages/SystemUI/res/drawable/qs_camera_access_icon_on.xml
new file mode 100644
index 0000000..beb8b72
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_camera_access_icon_on.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 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
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M7.44 10.61 C7.44,10.61 -10.96,-7.79 -10.96,-7.79 C-10.96,-7.79 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 8.84,9.21 8.84,9.21 C8.84,9.21 7.44,10.61 7.44,10.61c "
+                    android:valueTo="M7.44 10.62 C7.44,10.62 7.45,10.62 7.45,10.62 C7.45,10.62 8.85,9.22 8.85,9.22 C8.85,9.22 8.84,9.22 8.84,9.22 C8.84,9.22 7.44,10.62 7.44,10.62c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.55,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_1_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="333"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M5 1.3 C5,1.3 8.35,4.63 8.35,4.63 C8.35,4.63 8.35,-4.58 8.35,-4.58 C8.35,-4.58 5,-1.25 5,-1.25 C5,-1.25 5,-5 5,-5 C5,-5.92 4.25,-6.67 3.33,-6.67 C3.33,-6.67 -4.28,-6.67 -4.28,-6.67 C-3.98,-6.36 -3.13,-5.56 -2.55,-4.99 C-2.55,-4.99 3.33,-5 3.33,-5 C3.33,-5 3.33,-1.91 3.33,-1.91 C3.33,-1.91 3.33,0.9 3.33,0.9 C3.33,0.9 5.01,2.59 5.01,2.59 C5.01,2.59 5,2.14 5,2.14 C5,2.14 5,1.3 5,1.3c M3.34 5 C3.34,5 -6.67,5 -6.67,5 C-6.67,5 -6.67,-5.01 -6.67,-5.01 C-6.67,-5.01 -5.5,-5 -5.5,-5 C-6.02,-5.5 -6.69,-6.17 -7.12,-6.61 C-7.82,-6.41 -8.34,-5.77 -8.34,-5.01 C-8.34,-5.01 -8.34,5 -8.34,5 C-8.34,5.91 -7.58,6.66 -6.67,6.66 C-6.67,6.66 3.34,6.66 3.34,6.66 C4.13,6.66 4.79,6.11 4.97,5.37 C4.7,5.1 3.73,4.13 3.34,3.73 C3.34,3.73 3.34,5 3.34,5c "
+                    android:valueTo="M5 1.3 C5,1.3 8.35,4.63 8.35,4.63 C8.35,4.63 8.35,-4.58 8.35,-4.58 C8.35,-4.58 5,-1.25 5,-1.25 C5,-1.25 5,-5 5,-5 C5,-5.92 4.25,-6.67 3.33,-6.67 C3.33,-6.67 -6.84,-6.68 -6.84,-6.68 C-6.54,-6.37 -6.07,-5.56 -5.49,-5 C-5.49,-5 3.33,-5 3.33,-5 C3.33,-5 3.33,-1.91 3.33,-1.91 C3.33,-1.91 3.32,3.73 3.32,3.73 C3.32,3.73 5,5.23 5,5.23 C5,5.23 5,2.14 5,2.14 C5,2.14 5,1.3 5,1.3c M3.34 5 C3.34,5 -6.67,5 -6.67,5 C-6.67,5 -6.67,-5.01 -6.67,-5.01 C-6.67,-5.01 -5.5,-5 -5.5,-5 C-5.98,-5.57 -6.46,-6.23 -6.83,-6.68 C-7.84,-6.64 -8.34,-5.77 -8.34,-5.01 C-8.34,-5.01 -8.34,5 -8.34,5 C-8.34,5.91 -7.58,6.66 -6.67,6.66 C-6.67,6.66 3.34,6.66 3.34,6.66 C4.13,6.66 4.88,6.1 5,5.23 C4.73,4.96 3.73,4.13 3.34,3.73 C3.34,3.73 3.34,5 3.34,5c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="350"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M7.44 10.61 C7.44,10.61 -10.96,-7.79 -10.96,-7.79 C-10.96,-7.79 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 8.84,9.21 8.84,9.21 C8.84,9.21 7.44,10.61 7.44,10.61c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_1_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M5 1.3 C5,1.3 8.35,4.63 8.35,4.63 C8.35,4.63 8.35,-4.58 8.35,-4.58 C8.35,-4.58 5,-1.25 5,-1.25 C5,-1.25 5,-5 5,-5 C5,-5.92 4.25,-6.67 3.33,-6.67 C3.33,-6.67 -4.28,-6.67 -4.28,-6.67 C-3.98,-6.36 -3.13,-5.56 -2.55,-4.99 C-2.55,-4.99 3.33,-5 3.33,-5 C3.33,-5 3.33,-1.91 3.33,-1.91 C3.33,-1.91 3.33,0.9 3.33,0.9 C3.33,0.9 5.01,2.59 5.01,2.59 C5.01,2.59 5,2.14 5,2.14 C5,2.14 5,1.3 5,1.3c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_dnd_icon_off.xml b/packages/SystemUI/res/drawable/qs_dnd_icon_off.xml
new file mode 100644
index 0000000..e42381a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_dnd_icon_off.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 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
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="183"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:rotation="-225"
+                    android:scaleX="0.85"
+                    android:scaleY="0.85"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M-2.83 -4.24 C-2.83,-4.24 4.24,2.83 4.24,2.83 C4.24,2.83 2.83,4.24 2.83,4.24 C2.83,4.24 -4.24,-2.83 -4.24,-2.83 C-4.24,-2.83 -2.83,-4.24 -2.83,-4.24c  M7.07 7.09 C4.65,9.51 1.78,10.02 0,10.02 C-5.52,10.02 -10,5.54 -10,0.02 C-10,-1.76 -9.49,-4.52 -7.07,-7.07 C-7.07,-7.07 -5.66,-5.67 -5.66,-5.67 C-7.73,-3.44 -8,-1.2 -8,0.02 C-8,4.43 -4.41,8.02 0,8.02 C1.22,8.02 3.42,7.71 5.67,5.64 C5.67,5.64 7.07,7.09 7.07,7.09c  M-7.06 -7.1 C-4.62,-9.54 -1.81,-9.94 -0.03,-9.94 C5.49,-9.94 9.97,-5.46 9.97,0.06 C9.97,1.84 9.49,4.63 7.07,7.05 C7.07,7.05 5.66,5.64 5.66,5.64 C7.67,3.51 7.97,1.28 7.97,0.06 C7.97,-4.35 4.38,-7.94 -0.03,-7.94 C-1.25,-7.94 -3.43,-7.88 -5.65,-5.66 C-5.65,-5.66 -7.06,-7.1 -7.06,-7.1c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_dnd_icon_on.xml b/packages/SystemUI/res/drawable/qs_dnd_icon_on.xml
new file mode 100644
index 0000000..a63cb23
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_dnd_icon_on.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 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
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_0_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="500"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="-225"
+                    android:valueTo="-45"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="517"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:rotation="-225"
+                    android:scaleX="0.85"
+                    android:scaleY="0.85"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M-2.83 -4.24 C-2.83,-4.24 4.24,2.83 4.24,2.83 C4.24,2.83 2.83,4.24 2.83,4.24 C2.83,4.24 -4.24,-2.83 -4.24,-2.83 C-4.24,-2.83 -2.83,-4.24 -2.83,-4.24c  M7.07 7.09 C4.65,9.51 1.78,10.02 0,10.02 C-5.52,10.02 -10,5.54 -10,0.02 C-10,-1.76 -9.49,-4.52 -7.07,-7.07 C-7.07,-7.07 -5.66,-5.67 -5.66,-5.67 C-7.73,-3.44 -8,-1.2 -8,0.02 C-8,4.43 -4.41,8.02 0,8.02 C1.22,8.02 3.42,7.71 5.67,5.64 C5.67,5.64 7.07,7.09 7.07,7.09c  M-7.06 -7.1 C-4.62,-9.54 -1.81,-9.94 -0.03,-9.94 C5.49,-9.94 9.97,-5.46 9.97,0.06 C9.97,1.84 9.49,4.63 7.07,7.05 C7.07,7.05 5.66,5.64 5.66,5.64 C7.67,3.51 7.97,1.28 7.97,0.06 C7.97,-4.35 4.38,-7.94 -0.03,-7.94 C-1.25,-7.94 -3.43,-7.88 -5.65,-5.66 C-5.65,-5.66 -7.06,-7.1 -7.06,-7.1c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_location_icon_off.xml b/packages/SystemUI/res/drawable/qs_location_icon_off.xml
new file mode 100644
index 0000000..97eb91c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_location_icon_off.xml
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 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.
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_0_G_D_1_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="175"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M3.98 4.01 C3.98,4.01 2.56,2.54 2.56,2.54 C3.34,1.49 4.41,0.01 4.68,-0.84 C4.9,-1.45 5,-2.2 5,-3 C5,-4.38 4.51,-5.56 3.54,-6.54 C2.56,-7.51 1.38,-8 0,-8 C-0.7,-8 -1.36,-7.89 -1.99,-7.61 C-2.61,-7.34 -4.01,-6.61 -4.61,-4.61 C-4.61,-4.61 -6.24,-6.22 -6.24,-6.22 C-5.27,-8.11 -3.65,-9.09 -2.79,-9.46 C-1.94,-9.84 -1,-10 0,-10 C1.93,-10 3.6,-9.32 4.97,-7.96 C6.33,-6.59 7,-4.93 7,-3 C7,-1.85 6.86,-0.99 6.49,0.02 C6.12,1.04 4.57,3.23 3.98,4.01c "
+                    android:valueTo="M4.62 3.11 C4.62,3.11 3.2,1.65 3.2,1.65 C3.77,0.85 4.43,-0.12 4.68,-0.84 C4.9,-1.45 5,-2.2 5,-3 C5,-4.38 4.51,-5.56 3.54,-6.54 C2.56,-7.51 1.38,-8 0,-8 C-0.7,-8 -1.36,-7.89 -1.99,-7.61 C-2.61,-7.34 -3.55,-6.78 -4.16,-5.65 C-4.16,-5.65 -5.67,-7.13 -5.67,-7.13 C-4.81,-8.35 -3.65,-9.09 -2.79,-9.46 C-1.94,-9.84 -1,-10 0,-10 C1.93,-10 3.6,-9.32 4.97,-7.96 C6.33,-6.59 7,-4.93 7,-3 C7,-1.85 6.85,-0.89 6.49,0.02 C6.13,0.94 5.16,2.35 4.62,3.11c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="75"
+                    android:propertyName="pathData"
+                    android:startOffset="175"
+                    android:valueFrom="M4.62 3.11 C4.62,3.11 3.2,1.65 3.2,1.65 C3.77,0.85 4.43,-0.12 4.68,-0.84 C4.9,-1.45 5,-2.2 5,-3 C5,-4.38 4.51,-5.56 3.54,-6.54 C2.56,-7.51 1.38,-8 0,-8 C-0.7,-8 -1.36,-7.89 -1.99,-7.61 C-2.61,-7.34 -3.55,-6.78 -4.16,-5.65 C-4.16,-5.65 -5.67,-7.13 -5.67,-7.13 C-4.81,-8.35 -3.65,-9.09 -2.79,-9.46 C-1.94,-9.84 -1,-10 0,-10 C1.93,-10 3.6,-9.32 4.97,-7.96 C6.33,-6.59 7,-4.93 7,-3 C7,-1.85 6.85,-0.89 6.49,0.02 C6.13,0.94 5.16,2.35 4.62,3.11c "
+                    android:valueTo="M5.18 2.33 C5.18,2.33 3.75,0.88 3.75,0.88 C4.13,0.29 4.45,-0.23 4.68,-0.84 C4.9,-1.45 5,-2.2 5,-3 C5,-4.38 4.51,-5.56 3.54,-6.54 C2.56,-7.51 1.38,-8 0,-8 C-0.7,-8 -1.36,-7.89 -1.99,-7.61 C-2.61,-7.34 -3.16,-6.94 -3.61,-6.46 C-3.61,-6.46 -5.07,-7.86 -5.07,-7.86 C-4.42,-8.54 -3.65,-9.09 -2.79,-9.46 C-1.94,-9.84 -1,-10 0,-10 C1.93,-10 3.6,-9.32 4.97,-7.96 C6.33,-6.59 7,-4.93 7,-3 C7,-1.85 6.84,-0.81 6.49,0.02 C6.14,0.86 5.68,1.58 5.18,2.33c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_1_P_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="125"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M-0.96 -0.67 C0.37,-0.16 1.79,-0.77 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-2.08,-4.88 -2.84,-3.58 -2.35,-2.11 C-2.16,-1.55 -1.58,-0.91 -0.96,-0.67c "
+                    android:valueTo="M-0.29 -0.52 C0.81,-0.39 1.86,-0.95 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.93,-4.94 -2.6,-3.89 -2.49,-2.82 C-2.18,-2.46 -0.67,-0.84 -0.29,-0.52c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="50"
+                    android:propertyName="pathData"
+                    android:startOffset="125"
+                    android:valueFrom="M-0.29 -0.52 C0.81,-0.39 1.86,-0.95 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.93,-4.94 -2.6,-3.89 -2.49,-2.82 C-2.18,-2.46 -0.67,-0.84 -0.29,-0.52c "
+                    android:valueTo="M0.87 -0.65 C1.56,-0.93 2.02,-1.3 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.63,-5.06 -2.14,-4.44 -2.33,-3.91 C-2.11,-3.68 0.66,-0.85 0.87,-0.65c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="75"
+                    android:propertyName="pathData"
+                    android:startOffset="175"
+                    android:valueFrom="M0.87 -0.65 C1.56,-0.93 2.02,-1.3 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.63,-5.06 -2.14,-4.44 -2.33,-3.91 C-2.11,-3.68 0.66,-0.85 0.87,-0.65c "
+                    android:valueTo="M1.8 -1.24 C2.03,-1.47 2.21,-1.76 2.33,-2.05 C2.44,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.25,-5.21 -1.57,-5.02 -1.77,-4.78 C-1.77,-4.78 1.8,-1.24 1.8,-1.24c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_2_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="125"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M-9.89 -7.81 C-9.89,-7.81 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 -8.49,-9.21 -8.49,-9.21 C-8.49,-9.21 -9.89,-7.81 -9.89,-7.81c "
+                    android:valueTo="M-9.89 -7.81 C-9.89,-7.81 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 -8.49,-9.21 -8.49,-9.21 C-8.49,-9.21 -9.89,-7.81 -9.89,-7.81c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="125"
+                    android:propertyName="pathData"
+                    android:startOffset="125"
+                    android:valueFrom="M-9.89 -7.81 C-9.89,-7.81 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 -8.49,-9.21 -8.49,-9.21 C-8.49,-9.21 -9.89,-7.81 -9.89,-7.81c "
+                    android:valueTo="M8.5 10.6 C8.5,10.6 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 9.9,9.2 9.9,9.2 C9.9,9.2 8.5,10.6 8.5,10.6c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="267"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M-5.05 -2.1 C-5.05,-1.06 -4.64,-0.4 -4.23,0.3 C-3.81,1 -3.28,1.75 -2.65,2.55 C-2.22,3.1 -1.78,3.71 -1.35,4.39 C-0.92,5.06 -0.39,5.6 0.01,6.43 C0.21,5.95 0.61,5.27 0.98,4.72 C1.44,4.01 2.13,3.09 2.55,2.54 C2.94,2.95 3.54,3.56 3.98,4 C3.47,4.64 2.65,5.82 2.1,6.77 C1.66,7.55 1.28,8.44 0.98,9.26 C0.88,9.55 0.77,9.67 0.59,9.81 C0.44,9.93 0.28,9.99 0,9.99 C-0.28,9.99 -0.48,9.89 -0.68,9.66 C-0.88,9.44 -1.03,9.18 -1.15,8.9 C-1.45,8.07 -1.68,7.43 -2.17,6.65 C-2.67,5.88 -3.27,4.87 -4.15,3.79 C-4.88,2.75 -5.67,1.6 -6.21,0.62 C-6.74,-0.36 -7,-1.76 -7,-3.01 C-7,-4.08 -6.77,-5.28 -6.23,-6.23 C-5.75,-5.73 -4.92,-4.92 -4.61,-4.61 C-4.87,-3.95 -5.06,-2.93 -5.05,-2.1c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_1_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M3.98 4.01 C3.98,4.01 2.56,2.54 2.56,2.54 C3.34,1.49 4.41,0.01 4.68,-0.84 C4.9,-1.45 5,-2.2 5,-3 C5,-4.38 4.51,-5.56 3.54,-6.54 C2.56,-7.51 1.38,-8 0,-8 C-0.7,-8 -1.36,-7.89 -1.99,-7.61 C-2.61,-7.34 -4.01,-6.61 -4.61,-4.61 C-4.61,-4.61 -6.24,-6.22 -6.24,-6.22 C-5.27,-8.11 -3.65,-9.09 -2.79,-9.46 C-1.94,-9.84 -1,-10 0,-10 C1.93,-10 3.6,-9.32 4.97,-7.96 C6.33,-6.59 7,-4.93 7,-3 C7,-1.85 6.86,-0.99 6.49,0.02 C6.12,1.04 4.57,3.23 3.98,4.01c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_1_P_1"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M-0.96 -0.67 C0.37,-0.16 1.79,-0.77 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-2.08,-4.88 -2.84,-3.58 -2.35,-2.11 C-2.16,-1.55 -1.58,-0.91 -0.96,-0.67c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_2_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#edf2eb"
+                        android:fillType="nonZero"
+                        android:pathData=" M-9.89 -7.81 C-9.89,-7.81 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 -8.49,-9.21 -8.49,-9.21 C-8.49,-9.21 -9.89,-7.81 -9.89,-7.81c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_location_icon_on.xml b/packages/SystemUI/res/drawable/qs_location_icon_on.xml
new file mode 100644
index 0000000..c56b650
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_location_icon_on.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 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.
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_0_G_D_1_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="100"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M5.18 2.33 C5.18,2.33 3.75,0.88 3.75,0.88 C4.13,0.29 4.45,-0.23 4.68,-0.84 C4.9,-1.45 5,-2.2 5,-3 C5,-4.38 4.51,-5.56 3.54,-6.54 C2.56,-7.51 1.38,-8 0,-8 C-0.7,-8 -1.36,-7.89 -1.99,-7.61 C-2.61,-7.34 -3.16,-6.94 -3.61,-6.46 C-3.61,-6.46 -5.07,-7.86 -5.07,-7.86 C-4.42,-8.54 -3.65,-9.09 -2.79,-9.46 C-1.94,-9.84 -1,-10 0,-10 C1.93,-10 3.6,-9.32 4.97,-7.96 C6.33,-6.59 7,-4.93 7,-3 C7,-1.85 6.84,-0.81 6.49,0.02 C6.14,0.86 5.68,1.58 5.18,2.33c "
+                    android:valueTo="M4.62 3.11 C4.62,3.11 3.2,1.65 3.2,1.65 C3.77,0.85 4.43,-0.12 4.68,-0.84 C4.9,-1.45 5,-2.2 5,-3 C5,-4.38 4.51,-5.56 3.54,-6.54 C2.56,-7.51 1.38,-8 0,-8 C-0.7,-8 -1.36,-7.89 -1.99,-7.61 C-2.61,-7.34 -3.55,-6.78 -4.16,-5.65 C-4.16,-5.65 -5.67,-7.13 -5.67,-7.13 C-4.81,-8.35 -3.65,-9.09 -2.79,-9.46 C-1.94,-9.84 -1,-10 0,-10 C1.93,-10 3.6,-9.32 4.97,-7.96 C6.33,-6.59 7,-4.93 7,-3 C7,-1.85 6.85,-0.89 6.49,0.02 C6.13,0.94 5.16,2.35 4.62,3.11c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="233"
+                    android:propertyName="pathData"
+                    android:startOffset="100"
+                    android:valueFrom="M4.62 3.11 C4.62,3.11 3.2,1.65 3.2,1.65 C3.77,0.85 4.43,-0.12 4.68,-0.84 C4.9,-1.45 5,-2.2 5,-3 C5,-4.38 4.51,-5.56 3.54,-6.54 C2.56,-7.51 1.38,-8 0,-8 C-0.7,-8 -1.36,-7.89 -1.99,-7.61 C-2.61,-7.34 -3.55,-6.78 -4.16,-5.65 C-4.16,-5.65 -5.67,-7.13 -5.67,-7.13 C-4.81,-8.35 -3.65,-9.09 -2.79,-9.46 C-1.94,-9.84 -1,-10 0,-10 C1.93,-10 3.6,-9.32 4.97,-7.96 C6.33,-6.59 7,-4.93 7,-3 C7,-1.85 6.85,-0.89 6.49,0.02 C6.13,0.94 5.16,2.35 4.62,3.11c "
+                    android:valueTo="M3.98 4.01 C3.98,4.01 2.56,2.54 2.56,2.54 C3.34,1.49 4.41,0.01 4.68,-0.84 C4.9,-1.45 5,-2.2 5,-3 C5,-4.38 4.51,-5.56 3.54,-6.54 C2.56,-7.51 1.38,-8 0,-8 C-0.7,-8 -1.36,-7.89 -1.99,-7.61 C-2.61,-7.34 -4.01,-6.61 -4.61,-4.61 C-4.61,-4.61 -6.24,-6.22 -6.24,-6.22 C-5.27,-8.11 -3.65,-9.09 -2.79,-9.46 C-1.94,-9.84 -1,-10 0,-10 C1.93,-10 3.6,-9.32 4.97,-7.96 C6.33,-6.59 7,-4.93 7,-3 C7,-1.85 6.86,-0.99 6.49,0.02 C6.12,1.04 4.57,3.23 3.98,4.01c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_1_P_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="100"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M1.8 -1.24 C2.03,-1.47 2.21,-1.76 2.33,-2.05 C2.44,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.25,-5.21 -1.57,-5.02 -1.77,-4.78 C-1.77,-4.78 1.8,-1.24 1.8,-1.24c "
+                    android:valueTo="M0.87 -0.65 C1.56,-0.93 2.02,-1.3 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.63,-5.06 -2.14,-4.44 -2.33,-3.91 C-2.11,-3.68 0.66,-0.85 0.87,-0.65c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="67"
+                    android:propertyName="pathData"
+                    android:startOffset="100"
+                    android:valueFrom="M0.87 -0.65 C1.56,-0.93 2.02,-1.3 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.63,-5.06 -2.14,-4.44 -2.33,-3.91 C-2.11,-3.68 0.66,-0.85 0.87,-0.65c "
+                    android:valueTo="M-0.29 -0.52 C0.81,-0.39 1.86,-0.95 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.93,-4.94 -2.6,-3.89 -2.49,-2.82 C-2.18,-2.46 -0.67,-0.84 -0.29,-0.52c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="pathData"
+                    android:startOffset="167"
+                    android:valueFrom="M-0.29 -0.52 C0.81,-0.39 1.86,-0.95 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.93,-4.94 -2.6,-3.89 -2.49,-2.82 C-2.18,-2.46 -0.67,-0.84 -0.29,-0.52c "
+                    android:valueTo="M-0.96 -0.67 C0.37,-0.16 1.79,-0.77 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-2.08,-4.88 -2.84,-3.58 -2.35,-2.11 C-2.16,-1.55 -1.58,-0.91 -0.96,-0.67c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_2_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M8.5 10.6 C8.5,10.6 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 9.9,9.2 9.9,9.2 C9.9,9.2 8.5,10.6 8.5,10.6c "
+                    android:valueTo="M8.5 10.6 C8.5,10.6 8.51,10.6 8.51,10.6 C8.51,10.6 9.91,9.2 9.91,9.2 C9.91,9.2 9.9,9.2 9.9,9.2 C9.9,9.2 8.5,10.6 8.5,10.6c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="350"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M-5.05 -2.1 C-5.05,-1.06 -4.64,-0.4 -4.23,0.3 C-3.81,1 -3.28,1.75 -2.65,2.55 C-2.22,3.1 -1.78,3.71 -1.35,4.39 C-0.92,5.06 -0.39,5.6 0.01,6.43 C0.21,5.95 0.61,5.27 0.98,4.72 C1.44,4.01 2.13,3.09 2.55,2.54 C2.94,2.95 3.54,3.56 3.98,4 C3.47,4.64 2.65,5.82 2.1,6.77 C1.66,7.55 1.28,8.44 0.98,9.26 C0.88,9.55 0.77,9.67 0.59,9.81 C0.44,9.93 0.28,9.99 0,9.99 C-0.28,9.99 -0.48,9.89 -0.68,9.66 C-0.88,9.44 -1.03,9.18 -1.15,8.9 C-1.45,8.07 -1.68,7.43 -2.17,6.65 C-2.67,5.88 -3.27,4.87 -4.15,3.79 C-4.88,2.75 -5.67,1.6 -6.21,0.62 C-6.74,-0.36 -7,-1.76 -7,-3.01 C-7,-4.08 -6.77,-5.28 -6.23,-6.23 C-5.75,-5.73 -4.92,-4.92 -4.61,-4.61 C-4.87,-3.95 -5.06,-2.93 -5.05,-2.1c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_1_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M5.18 2.33 C5.18,2.33 3.75,0.88 3.75,0.88 C4.13,0.29 4.45,-0.23 4.68,-0.84 C4.9,-1.45 5,-2.2 5,-3 C5,-4.38 4.51,-5.56 3.54,-6.54 C2.56,-7.51 1.38,-8 0,-8 C-0.7,-8 -1.36,-7.89 -1.99,-7.61 C-2.61,-7.34 -3.16,-6.94 -3.61,-6.46 C-3.61,-6.46 -5.07,-7.86 -5.07,-7.86 C-4.42,-8.54 -3.65,-9.09 -2.79,-9.46 C-1.94,-9.84 -1,-10 0,-10 C1.93,-10 3.6,-9.32 4.97,-7.96 C6.33,-6.59 7,-4.93 7,-3 C7,-1.85 6.84,-0.81 6.49,0.02 C6.14,0.86 5.68,1.58 5.18,2.33c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_1_P_1"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M1.8 -1.24 C2.03,-1.47 2.21,-1.76 2.33,-2.05 C2.44,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.25,-5.21 -1.57,-5.02 -1.77,-4.78 C-1.77,-4.78 1.8,-1.24 1.8,-1.24c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_2_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#edf2eb"
+                        android:fillType="nonZero"
+                        android:pathData=" M8.5 10.6 C8.5,10.6 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 9.9,9.2 9.9,9.2 C9.9,9.2 8.5,10.6 8.5,10.6c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_mic_access_off.xml b/packages/SystemUI/res/drawable/qs_mic_access_off.xml
new file mode 100644
index 0000000..63a9444
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_mic_access_off.xml
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 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
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M5.05 4.43 C3.98,5.25 3.08,5.53 2.53,5.73 C2.26,5.81 1.98,5.87 1.7,5.9 C1.7,5.9 1.7,9 1.7,9 C1.7,9 -0.3,9 -0.3,9 C-0.3,9 -0.3,5.9 -0.3,5.9 C-2.02,5.65 -3.44,4.88 -4.59,3.59 C-5.73,2.3 -6.3,0.77 -6.3,-1 C-6.3,-1 -4.3,-1 -4.3,-1 C-4.3,0.38 -3.81,1.56 -2.84,2.54 C-1.86,3.51 -0.68,4 0.7,4 C0.88,4 1.06,3.99 1.23,3.96 C1.39,3.94 2.58,3.77 3.61,2.99 C3.61,2.99 5.05,4.43 5.05,4.43c "
+                    android:valueTo="M5.02 4.5 C3.59,5.47 2.79,5.64 2.53,5.73 C2.26,5.81 1.98,5.87 1.7,5.9 C1.7,5.9 1.7,9 1.7,9 C1.7,9 -0.3,9 -0.3,9 C-0.3,9 -0.3,5.9 -0.3,5.9 C-2.02,5.65 -3.44,4.88 -4.59,3.59 C-5.73,2.3 -6.3,0.77 -6.3,-1 C-6.3,-1 -4.3,-1 -4.3,-1 C-4.3,0.38 -3.81,1.56 -2.84,2.54 C-1.86,3.51 -0.68,4 0.7,4 C0.88,4 1.06,3.99 1.23,3.96 C1.39,3.94 2.53,3.83 3.58,3.07 C3.58,3.07 5.02,4.5 5.02,4.5c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_1_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="44"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M2.31 1.86 C2.31,1.86 1.01,0.55 0.75,0.31 C1.7,0.27 1.7,-0.7 1.7,-0.7 C1.7,-0.7 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-0.66 -0.29,-0.66 C-0.29,-0.66 -2.31,-2.67 -2.31,-2.67 C-2.31,-2.67 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.7,-0.33 3.64,-0.03 C3.51,0.52 3.23,1.19 2.31,1.86c "
+                    android:valueTo="M2.86 1.48 C2.86,1.48 1.58,0.21 1.39,0.03 C1.77,-0.26 1.7,-1.03 1.7,-1.03 C1.7,-1.03 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-1.51 -0.29,-1.51 C-0.29,-1.51 -2.31,-3.5 -2.31,-3.5 C-2.31,-3.5 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.44 3.65,-0.17 C3.61,0.19 3.36,1.05 2.86,1.48c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="39"
+                    android:propertyName="pathData"
+                    android:startOffset="44"
+                    android:valueFrom="M2.86 1.48 C2.86,1.48 1.58,0.21 1.39,0.03 C1.77,-0.26 1.7,-1.03 1.7,-1.03 C1.7,-1.03 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-1.51 -0.29,-1.51 C-0.29,-1.51 -2.31,-3.5 -2.31,-3.5 C-2.31,-3.5 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.44 3.65,-0.17 C3.61,0.19 3.36,1.05 2.86,1.48c "
+                    android:valueTo="M3.12 0.99 C3.12,0.99 1.83,-0.26 1.71,-0.38 C1.72,-0.81 1.7,-1.31 1.7,-1.31 C1.7,-1.31 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-2.26 -0.29,-2.26 C-0.29,-2.26 -2.31,-4.23 -2.31,-4.23 C-2.31,-4.23 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.67,-0.54 3.66,-0.3 C3.63,0.12 3.38,0.7 3.12,0.99c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="pathData"
+                    android:startOffset="83"
+                    android:valueFrom="M3.12 0.99 C3.12,0.99 1.83,-0.26 1.71,-0.38 C1.72,-0.81 1.7,-1.31 1.7,-1.31 C1.7,-1.31 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-2.26 -0.29,-2.26 C-0.29,-2.26 -2.31,-4.23 -2.31,-4.23 C-2.31,-4.23 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.67,-0.54 3.66,-0.3 C3.63,0.12 3.38,0.7 3.12,0.99c "
+                    android:valueTo="M3.5 -0.05 C3.5,-0.05 1.7,-1.85 1.7,-1.85 C1.7,-1.85 1.7,-1.92 1.7,-1.92 C1.7,-1.92 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.3,-3.85 -0.3,-3.85 C-0.3,-3.85 -2.3,-5.85 -2.3,-5.85 C-2.3,-5.85 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.65 3.64,-0.5 C3.6,-0.35 3.55,-0.2 3.5,-0.05c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_2_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M5.04 4.45 C5.04,4.45 3.59,3.02 3.59,3.02 C4.82,1.94 5.31,0.96 5.53,0.3 C5.64,-0.12 5.7,-0.55 5.7,-1 C5.7,-1 7.7,-1 7.7,-1 C7.7,-0.27 7.59,0.43 7.38,1.09 C7.16,1.75 6.51,3.17 5.04,4.45c "
+                    android:valueTo="M6.45 2.95 C6.45,2.95 5,1.5 5,1.5 C5.23,1.12 5.41,0.72 5.53,0.3 C5.64,-0.12 5.7,-0.55 5.7,-1 C5.7,-1 7.7,-1 7.7,-1 C7.7,-0.27 7.59,0.43 7.38,1.09 C7.16,1.75 6.85,2.37 6.45,2.95c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_3_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="67"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C-0.4,2.17 -0.94,1.89 -1.41,1.42 C-1.89,0.94 -2.18,0.37 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c "
+                    android:valueTo="M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C-0.4,2.17 -0.94,1.89 -1.41,1.42 C-1.89,0.94 -2.18,0.37 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="100"
+                    android:propertyName="pathData"
+                    android:startOffset="67"
+                    android:valueFrom="M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C-0.4,2.17 -0.94,1.89 -1.41,1.42 C-1.89,0.94 -2.18,0.37 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c "
+                    android:valueTo="M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C0.09,2.2 -0.55,1.45 -1.02,0.98 C-1.5,0.5 -2.23,-0.14 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_4_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_4_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M-9.89 -7.81 C-9.89,-7.81 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 -8.49,-9.21 -8.49,-9.21 C-8.49,-9.21 -9.89,-7.81 -9.89,-7.81c "
+                    android:valueTo="M8.5 10.6 C8.5,10.6 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 9.9,9.2 9.9,9.2 C9.9,9.2 8.5,10.6 8.5,10.6c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="267"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#edf2eb"
+                        android:fillType="nonZero"
+                        android:pathData=" M5.05 4.43 C3.98,5.25 3.08,5.53 2.53,5.73 C2.26,5.81 1.98,5.87 1.7,5.9 C1.7,5.9 1.7,9 1.7,9 C1.7,9 -0.3,9 -0.3,9 C-0.3,9 -0.3,5.9 -0.3,5.9 C-2.02,5.65 -3.44,4.88 -4.59,3.59 C-5.73,2.3 -6.3,0.77 -6.3,-1 C-6.3,-1 -4.3,-1 -4.3,-1 C-4.3,0.38 -3.81,1.56 -2.84,2.54 C-1.86,3.51 -0.68,4 0.7,4 C0.88,4 1.06,3.99 1.23,3.96 C1.39,3.94 2.58,3.77 3.61,2.99 C3.61,2.99 5.05,4.43 5.05,4.43c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_1_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#edf2eb"
+                        android:fillType="nonZero"
+                        android:pathData=" M2.31 1.86 C2.31,1.86 1.01,0.55 0.75,0.31 C1.7,0.27 1.7,-0.7 1.7,-0.7 C1.7,-0.7 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-0.66 -0.29,-0.66 C-0.29,-0.66 -2.31,-2.67 -2.31,-2.67 C-2.31,-2.67 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.7,-0.33 3.64,-0.03 C3.51,0.52 3.23,1.19 2.31,1.86c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_2_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#edf2eb"
+                        android:fillType="nonZero"
+                        android:pathData=" M5.04 4.45 C5.04,4.45 3.59,3.02 3.59,3.02 C4.82,1.94 5.31,0.96 5.53,0.3 C5.64,-0.12 5.7,-0.55 5.7,-1 C5.7,-1 7.7,-1 7.7,-1 C7.7,-0.27 7.59,0.43 7.38,1.09 C7.16,1.75 6.51,3.17 5.04,4.45c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_3_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#edf2eb"
+                        android:fillType="nonZero"
+                        android:pathData=" M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C-0.4,2.17 -0.94,1.89 -1.41,1.42 C-1.89,0.94 -2.18,0.37 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_4_P_0"
+                        android:fillAlpha="0"
+                        android:fillColor="#edf2eb"
+                        android:fillType="nonZero"
+                        android:pathData=" M-9.89 -7.81 C-9.89,-7.81 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 -8.49,-9.21 -8.49,-9.21 C-8.49,-9.21 -9.89,-7.81 -9.89,-7.81c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_mic_access_on.xml b/packages/SystemUI/res/drawable/qs_mic_access_on.xml
new file mode 100644
index 0000000..b485f06
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_mic_access_on.xml
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 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
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M5.02 4.5 C3.59,5.47 2.79,5.64 2.53,5.73 C2.26,5.81 1.98,5.87 1.7,5.9 C1.7,5.9 1.7,9 1.7,9 C1.7,9 -0.3,9 -0.3,9 C-0.3,9 -0.3,5.9 -0.3,5.9 C-2.02,5.65 -3.44,4.88 -4.59,3.59 C-5.73,2.3 -6.3,0.77 -6.3,-1 C-6.3,-1 -4.3,-1 -4.3,-1 C-4.3,0.38 -3.81,1.56 -2.84,2.54 C-1.86,3.51 -0.68,4 0.7,4 C0.88,4 1.06,3.99 1.23,3.96 C1.39,3.94 2.53,3.83 3.58,3.07 C3.58,3.07 5.02,4.5 5.02,4.5c "
+                    android:valueTo="M5.05 4.43 C3.98,5.25 3.08,5.53 2.53,5.73 C2.26,5.81 1.98,5.87 1.7,5.9 C1.7,5.9 1.7,9 1.7,9 C1.7,9 -0.3,9 -0.3,9 C-0.3,9 -0.3,5.9 -0.3,5.9 C-2.02,5.65 -3.44,4.88 -4.59,3.59 C-5.73,2.3 -6.3,0.77 -6.3,-1 C-6.3,-1 -4.3,-1 -4.3,-1 C-4.3,0.38 -3.81,1.56 -2.84,2.54 C-1.86,3.51 -0.68,4 0.7,4 C0.88,4 1.06,3.99 1.23,3.96 C1.39,3.94 2.58,3.77 3.61,2.99 C3.61,2.99 5.05,4.43 5.05,4.43c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_1_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="125"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M3.5 -0.05 C3.5,-0.05 1.7,-1.85 1.7,-1.85 C1.7,-1.85 1.7,-1.92 1.7,-1.92 C1.7,-1.92 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.3,-3.85 -0.3,-3.85 C-0.3,-3.85 -2.3,-5.85 -2.3,-5.85 C-2.3,-5.85 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.65 3.64,-0.5 C3.6,-0.35 3.55,-0.2 3.5,-0.05c "
+                    android:valueTo="M3.12 0.99 C3.12,0.99 1.83,-0.26 1.71,-0.38 C1.72,-0.81 1.7,-1.31 1.7,-1.31 C1.7,-1.31 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-2.26 -0.29,-2.26 C-0.29,-2.26 -2.31,-4.23 -2.31,-4.23 C-2.31,-4.23 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.67,-0.54 3.66,-0.3 C3.63,0.12 3.38,0.7 3.12,0.99c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="58"
+                    android:propertyName="pathData"
+                    android:startOffset="125"
+                    android:valueFrom="M3.12 0.99 C3.12,0.99 1.83,-0.26 1.71,-0.38 C1.72,-0.81 1.7,-1.31 1.7,-1.31 C1.7,-1.31 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-2.26 -0.29,-2.26 C-0.29,-2.26 -2.31,-4.23 -2.31,-4.23 C-2.31,-4.23 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.67,-0.54 3.66,-0.3 C3.63,0.12 3.38,0.7 3.12,0.99c "
+                    android:valueTo="M2.86 1.48 C2.86,1.48 1.58,0.21 1.39,0.03 C1.77,-0.26 1.7,-1.03 1.7,-1.03 C1.7,-1.03 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-1.51 -0.29,-1.51 C-0.29,-1.51 -2.31,-3.5 -2.31,-3.5 C-2.31,-3.5 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.44 3.65,-0.17 C3.61,0.19 3.36,1.05 2.86,1.48c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="67"
+                    android:propertyName="pathData"
+                    android:startOffset="183"
+                    android:valueFrom="M2.86 1.48 C2.86,1.48 1.58,0.21 1.39,0.03 C1.77,-0.26 1.7,-1.03 1.7,-1.03 C1.7,-1.03 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-1.51 -0.29,-1.51 C-0.29,-1.51 -2.31,-3.5 -2.31,-3.5 C-2.31,-3.5 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.44 3.65,-0.17 C3.61,0.19 3.36,1.05 2.86,1.48c "
+                    android:valueTo="M2.42 1.81 C2.42,1.81 1.16,0.52 0.9,0.28 C1.7,0.14 1.7,-0.7 1.7,-0.7 C1.7,-0.7 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-0.66 -0.29,-0.66 C-0.29,-0.66 -2.31,-2.67 -2.31,-2.67 C-2.31,-2.67 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.7,-0.33 3.64,-0.03 C3.58,0.27 3.22,1.2 2.42,1.81c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_2_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M6.45 2.95 C6.45,2.95 5,1.5 5,1.5 C5.23,1.12 5.41,0.72 5.53,0.3 C5.64,-0.12 5.7,-0.55 5.7,-1 C5.7,-1 7.7,-1 7.7,-1 C7.7,-0.27 7.59,0.43 7.38,1.09 C7.16,1.75 6.85,2.37 6.45,2.95c "
+                    android:valueTo="M5.04 4.43 C5.04,4.43 3.59,2.98 3.59,2.98 C4.61,2.09 5.41,0.72 5.53,0.3 C5.64,-0.12 5.7,-0.55 5.7,-1 C5.7,-1 7.7,-1 7.7,-1 C7.7,-0.27 7.59,0.43 7.38,1.09 C7.16,1.75 6.19,3.44 5.04,4.43c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_3_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C0.09,2.2 -0.55,1.45 -1.02,0.98 C-1.5,0.5 -2.23,-0.14 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c "
+                    android:valueTo="M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C-0.4,2.17 -0.94,1.89 -1.41,1.42 C-1.89,0.94 -2.18,0.37 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_4_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="400"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="1"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="400"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_4_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M8.5 10.6 C8.5,10.6 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 9.9,9.2 9.9,9.2 C9.9,9.2 8.5,10.6 8.5,10.6c "
+                    android:valueTo="M8.5 10.6 C8.5,10.6 8.51,10.6 8.51,10.6 C8.51,10.6 9.91,9.2 9.91,9.2 C9.91,9.2 9.9,9.2 9.9,9.2 C9.9,9.2 8.5,10.6 8.5,10.6c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="433"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M5.02 4.5 C3.59,5.47 2.79,5.64 2.53,5.73 C2.26,5.81 1.98,5.87 1.7,5.9 C1.7,5.9 1.7,9 1.7,9 C1.7,9 -0.3,9 -0.3,9 C-0.3,9 -0.3,5.9 -0.3,5.9 C-2.02,5.65 -3.44,4.88 -4.59,3.59 C-5.73,2.3 -6.3,0.77 -6.3,-1 C-6.3,-1 -4.3,-1 -4.3,-1 C-4.3,0.38 -3.81,1.56 -2.84,2.54 C-1.86,3.51 -0.68,4 0.7,4 C0.88,4 1.06,3.99 1.23,3.96 C1.39,3.94 2.53,3.83 3.58,3.07 C3.58,3.07 5.02,4.5 5.02,4.5c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_1_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M3.5 -0.05 C3.5,-0.05 1.7,-1.85 1.7,-1.85 C1.7,-1.85 1.7,-1.92 1.7,-1.92 C1.7,-1.92 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.3,-3.85 -0.3,-3.85 C-0.3,-3.85 -2.3,-5.85 -2.3,-5.85 C-2.3,-5.85 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.65 3.64,-0.5 C3.6,-0.35 3.55,-0.2 3.5,-0.05c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_2_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M6.45 2.95 C6.45,2.95 5,1.5 5,1.5 C5.23,1.12 5.41,0.72 5.53,0.3 C5.64,-0.12 5.7,-0.55 5.7,-1 C5.7,-1 7.7,-1 7.7,-1 C7.7,-0.27 7.59,0.43 7.38,1.09 C7.16,1.75 6.85,2.37 6.45,2.95c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_3_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C0.09,2.2 -0.55,1.45 -1.02,0.98 C-1.5,0.5 -2.23,-0.14 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_4_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M8.5 10.6 C8.5,10.6 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 9.9,9.2 9.9,9.2 C9.9,9.2 8.5,10.6 8.5,10.6c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/screenshot_edit_background.xml b/packages/SystemUI/res/drawable/screenshot_edit_background.xml
index ff5c62e..a1185a2 100644
--- a/packages/SystemUI/res/drawable/screenshot_edit_background.xml
+++ b/packages/SystemUI/res/drawable/screenshot_edit_background.xml
@@ -17,7 +17,7 @@
 <!-- Long screenshot edit FAB background -->
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-        android:color="?android:textColorPrimary">
+        android:color="@color/overlay_button_ripple">
     <item android:id="@android:id/background">
         <shape android:shape="rectangle">
             <solid android:color="?androidprv:attr/colorAccentPrimary"/>
diff --git a/packages/SystemUI/res/layout/auth_container_view.xml b/packages/SystemUI/res/layout/auth_container_view.xml
index 3db01a4..2bd2e64 100644
--- a/packages/SystemUI/res/layout/auth_container_view.xml
+++ b/packages/SystemUI/res/layout/auth_container_view.xml
@@ -23,7 +23,6 @@
         android:id="@+id/background"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:background="@color/biometric_dialog_dim_color"
         android:contentDescription="@string/biometric_dialog_empty_space_description"/>
 
     <View
diff --git a/packages/SystemUI/res/layout/brightness_mirror_container.xml b/packages/SystemUI/res/layout/brightness_mirror_container.xml
index ac90db3..1bf45aa 100644
--- a/packages/SystemUI/res/layout/brightness_mirror_container.xml
+++ b/packages/SystemUI/res/layout/brightness_mirror_container.xml
@@ -23,7 +23,6 @@
     android:background="@drawable/brightness_mirror_background"
     android:layout_gravity="center_vertical"
     android:layout_margin="8dp"
-    android:padding="@dimen/rounded_slider_background_padding"
     android:gravity="center"
     android:visibility="invisible">
 
diff --git a/packages/SystemUI/res/layout/clipboard_overlay.xml b/packages/SystemUI/res/layout/clipboard_overlay.xml
index 99a5a2e..1a1fc75 100644
--- a/packages/SystemUI/res/layout/clipboard_overlay.xml
+++ b/packages/SystemUI/res/layout/clipboard_overlay.xml
@@ -115,6 +115,7 @@
                   android:autoSizeMinTextSize="@dimen/clipboard_overlay_min_font"
                   android:autoSizeMaxTextSize="@dimen/clipboard_overlay_max_font"
                   android:textColor="?attr/overlayButtonTextColor"
+                  android:textColorLink="?attr/overlayButtonTextColor"
                   android:background="?androidprv:attr/colorAccentSecondary"
                   android:layout_width="@dimen/clipboard_preview_size"
                   android:layout_height="@dimen/clipboard_preview_size"/>
diff --git a/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml b/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
index d0f4903..70a7709 100644
--- a/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
@@ -70,15 +70,32 @@
             android:visibility="gone"
             android:contentDescription="@string/dream_overlay_status_bar_wifi_off" />
 
-        <com.android.systemui.dreams.DreamOverlayDotImageView
-            android:id="@+id/dream_overlay_camera_mic_off"
-            android:layout_width="@dimen/dream_overlay_camera_mic_off_indicator_size"
-            android:layout_height="@dimen/dream_overlay_camera_mic_off_indicator_size"
-            android:layout_gravity="center_vertical"
+        <ImageView
+            android:id="@+id/dream_overlay_mic_off"
+            android:layout_width="@dimen/dream_overlay_grey_chip_width"
+            android:layout_height="match_parent"
             android:layout_marginEnd="@dimen/dream_overlay_status_icon_margin"
+            android:src="@drawable/dream_overlay_mic_off"
             android:visibility="gone"
-            android:contentDescription="@string/dream_overlay_status_bar_camera_mic_off"
-            app:dotColor="@color/dream_overlay_camera_mic_off_dot_color" />
+            android:contentDescription="@string/dream_overlay_status_bar_mic_off" />
+
+        <ImageView
+            android:id="@+id/dream_overlay_camera_off"
+            android:layout_width="@dimen/dream_overlay_grey_chip_width"
+            android:layout_height="match_parent"
+            android:layout_marginEnd="@dimen/dream_overlay_status_icon_margin"
+            android:src="@drawable/dream_overlay_camera_off"
+            android:visibility="gone"
+            android:contentDescription="@string/dream_overlay_status_bar_camera_off" />
+
+        <ImageView
+            android:id="@+id/dream_overlay_camera_mic_off"
+            android:layout_width="@dimen/dream_overlay_grey_chip_width"
+            android:layout_height="match_parent"
+            android:layout_marginEnd="@dimen/dream_overlay_status_icon_margin"
+            android:src="@drawable/dream_overlay_mic_and_camera_off"
+            android:visibility="gone"
+            android:contentDescription="@string/dream_overlay_status_bar_camera_mic_off" />
 
     </LinearLayout>
 </com.android.systemui.dreams.DreamOverlayStatusBarView>
diff --git a/packages/SystemUI/res/layout/keyguard_status_bar.xml b/packages/SystemUI/res/layout/keyguard_status_bar.xml
index e47eed9..d27fa19 100644
--- a/packages/SystemUI/res/layout/keyguard_status_bar.xml
+++ b/packages/SystemUI/res/layout/keyguard_status_bar.xml
@@ -60,9 +60,8 @@
         </com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherContainer>
 
         <FrameLayout android:id="@+id/system_icons_container"
-            android:layout_width="0dp"
+            android:layout_width="wrap_content"
             android:layout_height="match_parent"
-            android:layout_weight="1"
             android:layout_marginEnd="@dimen/status_bar_padding_end"
             android:gravity="center_vertical|end">
             <include layout="@layout/system_icons" />
diff --git a/packages/SystemUI/res/layout/media_output_dialog.xml b/packages/SystemUI/res/layout/media_output_dialog.xml
index 1efb479..93c16e4 100644
--- a/packages/SystemUI/res/layout/media_output_dialog.xml
+++ b/packages/SystemUI/res/layout/media_output_dialog.xml
@@ -42,12 +42,35 @@
             android:layout_height="wrap_content"
             android:paddingStart="12dp"
             android:orientation="vertical">
-            <ImageView
-                android:id="@+id/app_source_icon"
-                android:layout_width="20dp"
-                android:layout_height="20dp"
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
                 android:gravity="center_vertical"
-                android:importantForAccessibility="no"/>
+                android:orientation="horizontal">
+                <ImageView
+                    android:id="@+id/app_source_icon"
+                    android:layout_width="20dp"
+                    android:layout_height="20dp"
+                    android:gravity="center_vertical"
+                    android:importantForAccessibility="no"/>
+
+                <Space
+                    android:layout_weight="1"
+                    android:layout_width="0dp"
+                    android:layout_height="match_parent"/>
+
+                <ImageView
+                    android:id="@+id/broadcast_icon"
+                    android:src="@drawable/settings_input_antenna"
+                    android:contentDescription="@string/broadcasting_description_is_broadcasting"
+                    android:layout_width="48dp"
+                    android:layout_height="48dp"
+                    android:padding="12dp"
+                    android:gravity="center_vertical"
+                    android:clickable="true"
+                    android:focusable="true"
+                    android:visibility="gone"/>
+            </LinearLayout>
             <TextView
                 android:id="@+id/header_title"
                 android:layout_width="wrap_content"
@@ -89,8 +112,7 @@
             android:id="@+id/list_result"
             android:scrollbars="vertical"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:overScrollMode="never"/>
+            android:layout_height="wrap_content"/>
     </LinearLayout>
 
     <LinearLayout
diff --git a/packages/SystemUI/res/layout/media_session_view.xml b/packages/SystemUI/res/layout/media_session_view.xml
index 9c49607..c526d9c 100644
--- a/packages/SystemUI/res/layout/media_session_view.xml
+++ b/packages/SystemUI/res/layout/media_session_view.xml
@@ -150,7 +150,7 @@
 
     <!-- See comment in media_session_collapsed.xml for how these barriers are used -->
     <androidx.constraintlayout.widget.Barrier
-        android:id="@+id/media_action_barrier"
+        android:id="@+id/media_action_barrier_start"
         android:layout_width="0dp"
         android:layout_height="0dp"
         android:orientation="vertical"
@@ -172,6 +172,7 @@
         app:layout_constraintStart_toStartOf="parent"
         />
 
+    <!-- This barrier is used in expanded view to constrain the bottom row of actions -->
     <androidx.constraintlayout.widget.Barrier
         android:id="@+id/media_action_barrier_top"
         android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/notification_icon_area.xml b/packages/SystemUI/res/layout/notification_icon_area.xml
index fa696cc..aadfae8 100644
--- a/packages/SystemUI/res/layout/notification_icon_area.xml
+++ b/packages/SystemUI/res/layout/notification_icon_area.xml
@@ -14,18 +14,9 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-<com.android.keyguard.AlphaOptimizedLinearLayout
+<com.android.systemui.statusbar.phone.NotificationIconContainer
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/notification_icon_area_inner"
-    android:layout_width="match_parent"
+    android:id="@+id/notificationIcons"
+    android:layout_width="wrap_content"
     android:layout_height="match_parent"
-    android:clipChildren="false">
-    <com.android.systemui.statusbar.phone.NotificationIconContainer
-        android:id="@+id/notificationIcons"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_alignParentStart="true"
-        android:gravity="center_vertical"
-        android:orientation="horizontal"
-        android:clipChildren="false"/>
-</com.android.keyguard.AlphaOptimizedLinearLayout>
\ No newline at end of file
+    android:clipChildren="false"/>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/people_space_activity.xml b/packages/SystemUI/res/layout/people_space_activity.xml
index 7102375..f45cc7c 100644
--- a/packages/SystemUI/res/layout/people_space_activity.xml
+++ b/packages/SystemUI/res/layout/people_space_activity.xml
@@ -13,103 +13,11 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<LinearLayout
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-    android:id="@+id/top_level"
+    android:id="@+id/container"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical"
-    android:padding="8dp">
-    <TextView
-        android:id="@+id/select_conversation_title"
-        android:text="@string/select_conversation_title"
-        android:gravity="center"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center_horizontal"
-        android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
-        android:textColor="?android:attr/textColorPrimary"
-        android:textSize="24sp"/>
-
-    <TextView
-        android:id="@+id/select_conversation"
-        android:text="@string/select_conversation_text"
-        android:gravity="center"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center_horizontal"
-        android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
-        android:textColor="?android:attr/textColorPrimary"
-        android:textSize="16sp"
-        android:paddingVertical="24dp"
-        android:paddingHorizontal="48dp"/>
-
-    <androidx.core.widget.NestedScrollView
-        android:id="@+id/scroll_view"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent">
-
-        <LinearLayout
-            android:id="@+id/scroll_layout"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="16dp"
-            android:orientation="vertical">
-
-            <LinearLayout
-                android:id="@+id/priority"
-                android:orientation="vertical"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginBottom="35dp">
-                <TextView
-                    android:id="@+id/priority_header"
-                    android:text="@string/priority_conversations"
-                    android:layout_width="wrap_content"
-                    android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
-                    android:textColor="?androidprv:attr/colorAccentPrimaryVariant"
-                    android:textSize="14sp"
-                    android:paddingStart="16dp"
-                    android:layout_height="wrap_content"/>
-
-                <LinearLayout
-                    android:id="@+id/priority_tiles"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="10dp"
-                    android:orientation="vertical"
-                    android:background="@drawable/rounded_bg_full_large_radius"
-                    android:clipToOutline="true">
-                </LinearLayout>
-            </LinearLayout>
-
-            <LinearLayout
-                android:id="@+id/recent"
-                android:orientation="vertical"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content">
-                <TextView
-                    android:id="@+id/recent_header"
-                    android:gravity="start"
-                    android:text="@string/recent_conversations"
-                    android:layout_width="wrap_content"
-                    android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
-                    android:textColor="?androidprv:attr/colorAccentPrimaryVariant"
-                    android:textSize="14sp"
-                    android:paddingStart="16dp"
-                    android:layout_height="wrap_content"/>
-
-                <LinearLayout
-                    android:id="@+id/recent_tiles"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="10dp"
-                    android:orientation="vertical"
-                    android:background="@drawable/rounded_bg_full_large_radius"
-                    android:clipToOutline="true">
-                </LinearLayout>
-            </LinearLayout>
-        </LinearLayout>
-    </androidx.core.widget.NestedScrollView>
-</LinearLayout>
\ No newline at end of file
+    android:layout_height="match_parent">
+    <!-- The content of people_space_activity_(no|with)_conversations.xml will be added here at
+         runtime depending on the number of conversations to show. -->
+</FrameLayout>
diff --git a/packages/SystemUI/res/layout/people_space_activity_no_conversations.xml b/packages/SystemUI/res/layout/people_space_activity_no_conversations.xml
index 2e9ff07..e929169 100644
--- a/packages/SystemUI/res/layout/people_space_activity_no_conversations.xml
+++ b/packages/SystemUI/res/layout/people_space_activity_no_conversations.xml
@@ -16,7 +16,7 @@
 <RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-    android:id="@+id/top_level"
+    android:id="@+id/top_level_no_conversations"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:padding="24dp"
diff --git a/packages/SystemUI/res/layout/people_space_activity_with_conversations.xml b/packages/SystemUI/res/layout/people_space_activity_with_conversations.xml
new file mode 100644
index 0000000..2384963
--- /dev/null
+++ b/packages/SystemUI/res/layout/people_space_activity_with_conversations.xml
@@ -0,0 +1,115 @@
+<!--
+  ~ Copyright (C) 2022 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.
+  -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+    android:id="@+id/top_level_with_conversations"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:padding="8dp">
+    <TextView
+        android:id="@+id/select_conversation_title"
+        android:text="@string/select_conversation_title"
+        android:gravity="center"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_horizontal"
+        android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+        android:textColor="?android:attr/textColorPrimary"
+        android:textSize="24sp"/>
+
+    <TextView
+        android:id="@+id/select_conversation"
+        android:text="@string/select_conversation_text"
+        android:gravity="center"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_horizontal"
+        android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+        android:textColor="?android:attr/textColorPrimary"
+        android:textSize="16sp"
+        android:paddingVertical="24dp"
+        android:paddingHorizontal="48dp"/>
+
+    <androidx.core.widget.NestedScrollView
+        android:id="@+id/scroll_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <LinearLayout
+            android:id="@+id/scroll_layout"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="16dp"
+            android:orientation="vertical">
+
+            <LinearLayout
+                android:id="@+id/priority"
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginBottom="35dp">
+                <TextView
+                    android:id="@+id/priority_header"
+                    android:text="@string/priority_conversations"
+                    android:layout_width="wrap_content"
+                    android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
+                    android:textColor="?androidprv:attr/colorAccentPrimaryVariant"
+                    android:textSize="14sp"
+                    android:paddingStart="16dp"
+                    android:layout_height="wrap_content"/>
+
+                <LinearLayout
+                    android:id="@+id/priority_tiles"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="10dp"
+                    android:orientation="vertical"
+                    android:background="@drawable/rounded_bg_full_large_radius"
+                    android:clipToOutline="true">
+                </LinearLayout>
+            </LinearLayout>
+
+            <LinearLayout
+                android:id="@+id/recent"
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
+                <TextView
+                    android:id="@+id/recent_header"
+                    android:gravity="start"
+                    android:text="@string/recent_conversations"
+                    android:layout_width="wrap_content"
+                    android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
+                    android:textColor="?androidprv:attr/colorAccentPrimaryVariant"
+                    android:textSize="14sp"
+                    android:paddingStart="16dp"
+                    android:layout_height="wrap_content"/>
+
+                <LinearLayout
+                    android:id="@+id/recent_tiles"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="10dp"
+                    android:orientation="vertical"
+                    android:background="@drawable/rounded_bg_full_large_radius"
+                    android:clipToOutline="true">
+                </LinearLayout>
+            </LinearLayout>
+        </LinearLayout>
+    </androidx.core.widget.NestedScrollView>
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/people_space_tile_view.xml b/packages/SystemUI/res/layout/people_space_tile_view.xml
index 2a2c35d..b0599ca 100644
--- a/packages/SystemUI/res/layout/people_space_tile_view.xml
+++ b/packages/SystemUI/res/layout/people_space_tile_view.xml
@@ -37,8 +37,8 @@
 
             <ImageView
                 android:id="@+id/tile_view_person_icon"
-                android:layout_width="52dp"
-                android:layout_height="52dp" />
+                android:layout_width="@dimen/avatar_size_for_medium"
+                android:layout_height="@dimen/avatar_size_for_medium" />
 
             <LinearLayout
                 android:orientation="horizontal"
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index f560e61..80e65a3 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -47,52 +47,63 @@
         android:paddingStart="@dimen/status_bar_padding_start"
         android:paddingEnd="@dimen/status_bar_padding_end"
         android:paddingTop="@dimen/status_bar_padding_top"
-        android:orientation="horizontal"
-        >
+        android:orientation="horizontal">
+
+        <!-- Container for the entire start half of the status bar. It will always use the same
+             width, independent of the number of visible children and sub-children. -->
         <FrameLayout
+            android:id="@+id/status_bar_start_side_container"
             android:layout_height="match_parent"
             android:layout_width="0dp"
             android:layout_weight="1">
 
-            <include layout="@layout/heads_up_status_bar_layout" />
+            <!-- Container that is wrapped around the views on the start half of the status bar.
+                 Its width will change with the number of visible children and sub-children.
+                 It is useful when we want to know the visible bounds of the content. -->
+            <FrameLayout
+                android:id="@+id/status_bar_start_side_content"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:clipChildren="false">
 
-            <!-- The alpha of the left side is controlled by PhoneStatusBarTransitions, and the
-             individual views are controlled by StatusBarManager disable flags DISABLE_CLOCK and
-             DISABLE_NOTIFICATION_ICONS, respectively -->
-            <LinearLayout
-                android:id="@+id/status_bar_left_side"
-                android:layout_height="match_parent"
-                android:layout_width="match_parent"
-                android:clipChildren="false"
-            >
-                <ViewStub
-                    android:id="@+id/operator_name"
-                    android:layout_width="wrap_content"
-                    android:layout_height="match_parent"
-                    android:layout="@layout/operator_name" />
+                <include layout="@layout/heads_up_status_bar_layout" />
 
-                <com.android.systemui.statusbar.policy.Clock
-                    android:id="@+id/clock"
-                    android:layout_width="wrap_content"
-                    android:layout_height="match_parent"
-                    android:textAppearance="@style/TextAppearance.StatusBar.Clock"
-                    android:singleLine="true"
-                    android:paddingStart="@dimen/status_bar_left_clock_starting_padding"
-                    android:paddingEnd="@dimen/status_bar_left_clock_end_padding"
-                    android:gravity="center_vertical|start"
-                />
+                <!-- The alpha of the start side is controlled by PhoneStatusBarTransitions, and the
+                     individual views are controlled by StatusBarManager disable flags DISABLE_CLOCK
+                     and DISABLE_NOTIFICATION_ICONS, respectively -->
+                <LinearLayout
+                    android:id="@+id/status_bar_start_side_except_heads_up"
+                    android:layout_height="wrap_content"
+                    android:layout_width="match_parent"
+                    android:clipChildren="false">
+                    <ViewStub
+                        android:id="@+id/operator_name"
+                        android:layout_width="wrap_content"
+                        android:layout_height="match_parent"
+                        android:layout="@layout/operator_name" />
 
-                <include layout="@layout/ongoing_call_chip" />
+                    <com.android.systemui.statusbar.policy.Clock
+                        android:id="@+id/clock"
+                        android:layout_width="wrap_content"
+                        android:layout_height="match_parent"
+                        android:textAppearance="@style/TextAppearance.StatusBar.Clock"
+                        android:singleLine="true"
+                        android:paddingStart="@dimen/status_bar_left_clock_starting_padding"
+                        android:paddingEnd="@dimen/status_bar_left_clock_end_padding"
+                        android:gravity="center_vertical|start"
+                    />
 
-                <com.android.systemui.statusbar.AlphaOptimizedFrameLayout
-                    android:id="@+id/notification_icon_area"
-                    android:layout_width="0dp"
-                    android:layout_height="match_parent"
-                    android:layout_weight="1"
-                    android:orientation="horizontal"
-                    android:clipChildren="false"/>
+                    <include layout="@layout/ongoing_call_chip" />
 
-            </LinearLayout>
+                    <com.android.systemui.statusbar.AlphaOptimizedFrameLayout
+                        android:id="@+id/notification_icon_area"
+                        android:layout_width="wrap_content"
+                        android:layout_height="match_parent"
+                        android:orientation="horizontal"
+                        android:clipChildren="false"/>
+
+                </LinearLayout>
+            </FrameLayout>
         </FrameLayout>
 
         <!-- Space should cover the notch (if it exists) and let other views lay out around it -->
@@ -103,42 +114,57 @@
             android:gravity="center_horizontal|center_vertical"
         />
 
-        <com.android.keyguard.AlphaOptimizedLinearLayout android:id="@+id/system_icon_area"
+        <!-- Container for the entire end half of the status bar. It will always use the same
+             width, independent of the number of visible children and sub-children. -->
+        <FrameLayout
+            android:id="@+id/status_bar_end_side_container"
             android:layout_width="0dp"
             android:layout_height="match_parent"
             android:layout_weight="1"
-            android:orientation="horizontal"
-            android:gravity="center_vertical|end"
-            >
+            android:clipChildren="false">
 
-            <com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherContainer
-                android:id="@+id/user_switcher_container"
+            <!-- Container that is wrapped around the views on the end half of the
+                 status bar. Its width will change with the number of visible children and
+                 sub-children.
+                 It is useful when we want know the visible bounds of the content.-->
+            <com.android.keyguard.AlphaOptimizedLinearLayout
+                android:id="@+id/status_bar_end_side_content"
                 android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:gravity="center"
+                android:layout_height="match_parent"
+                android:layout_gravity="end"
                 android:orientation="horizontal"
-                android:paddingTop="4dp"
-                android:paddingBottom="4dp"
-                android:paddingStart="8dp"
-                android:paddingEnd="8dp"
-                android:layout_marginEnd="16dp"
-                android:background="@drawable/status_bar_user_chip_bg"
-                android:visibility="visible" >
-                <ImageView android:id="@+id/current_user_avatar"
-                    android:layout_width="@dimen/multi_user_avatar_keyguard_size"
-                    android:layout_height="@dimen/multi_user_avatar_keyguard_size"
-                    android:scaleType="centerInside"
-                    android:paddingEnd="4dp" />
+                android:gravity="center_vertical|end"
+                android:clipChildren="false">
 
-                <TextView android:id="@+id/current_user_name"
+                <com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherContainer
+                    android:id="@+id/user_switcher_container"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:textAppearance="@style/TextAppearance.StatusBar.Clock"
-                    />
-            </com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherContainer>
+                    android:gravity="center"
+                    android:orientation="horizontal"
+                    android:paddingTop="4dp"
+                    android:paddingBottom="4dp"
+                    android:paddingStart="8dp"
+                    android:paddingEnd="8dp"
+                    android:layout_marginEnd="16dp"
+                    android:background="@drawable/status_bar_user_chip_bg"
+                    android:visibility="visible" >
+                    <ImageView android:id="@+id/current_user_avatar"
+                        android:layout_width="@dimen/multi_user_avatar_keyguard_size"
+                        android:layout_height="@dimen/multi_user_avatar_keyguard_size"
+                        android:scaleType="centerInside"
+                        android:paddingEnd="4dp" />
 
-            <include layout="@layout/system_icons" />
-        </com.android.keyguard.AlphaOptimizedLinearLayout>
+                    <TextView android:id="@+id/current_user_name"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:textAppearance="@style/TextAppearance.StatusBar.Clock"
+                        />
+                </com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherContainer>
+
+                <include layout="@layout/system_icons" />
+            </com.android.keyguard.AlphaOptimizedLinearLayout>
+        </FrameLayout>
     </LinearLayout>
 
 </com.android.systemui.statusbar.phone.PhoneStatusBarView>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 91cf169..f0e49d5 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -18,7 +18,7 @@
 -->
 
 
-<com.android.systemui.statusbar.phone.NotificationPanelView
+<com.android.systemui.shade.NotificationPanelView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/notification_panel"
@@ -67,7 +67,7 @@
 
     </com.android.keyguard.LockIconView>
 
-    <com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer
+    <com.android.systemui.shade.NotificationsQuickSettingsContainer
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_gravity="@integer/notification_panel_layout_gravity"
@@ -143,11 +143,11 @@
             android:text="@string/tap_again"
             android:visibility="gone"
         />
-    </com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer>
+    </com.android.systemui.shade.NotificationsQuickSettingsContainer>
 
     <FrameLayout
         android:id="@+id/preview_container"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
     </FrameLayout>
-</com.android.systemui.statusbar.phone.NotificationPanelView>
+</com.android.systemui.shade.NotificationPanelView>
diff --git a/packages/SystemUI/res/layout/super_notification_shade.xml b/packages/SystemUI/res/layout/super_notification_shade.xml
index 60860ba..86f8ce2 100644
--- a/packages/SystemUI/res/layout/super_notification_shade.xml
+++ b/packages/SystemUI/res/layout/super_notification_shade.xml
@@ -18,7 +18,7 @@
 -->
 
 <!-- This is the notification shade window. -->
-<com.android.systemui.statusbar.phone.NotificationShadeWindowView
+<com.android.systemui.shade.NotificationShadeWindowView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:sysui="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
@@ -114,4 +114,4 @@
         android:importantForAccessibility="no"
         sysui:ignoreRightInset="true"
     />
-</com.android.systemui.statusbar.phone.NotificationShadeWindowView>
+</com.android.systemui.shade.NotificationShadeWindowView>
diff --git a/packages/SystemUI/res/layout/user_switcher_fullscreen.xml b/packages/SystemUI/res/layout/user_switcher_fullscreen.xml
index 0f2d372..c2c79cb 100644
--- a/packages/SystemUI/res/layout/user_switcher_fullscreen.xml
+++ b/packages/SystemUI/res/layout/user_switcher_fullscreen.xml
@@ -14,7 +14,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<androidx.constraintlayout.widget.ConstraintLayout
+<com.android.systemui.user.UserSwitcherRootView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
@@ -68,4 +68,4 @@
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintHeight_min="48dp" />
-</androidx.constraintlayout.widget.ConstraintLayout>
+</com.android.systemui.user.UserSwitcherRootView>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 5b2edbc..3d27dfd 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Toestel is gesluit"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skandeer tans gesig"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Stuur"</string>
-    <string name="phone_label" msgid="5715229948920451352">"maak foon oop"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"maak stembystand oop"</string>
-    <string name="camera_label" msgid="8253821920931143699">"maak kamera oop"</string>
     <string name="cancel" msgid="1089011503403416730">"Kanselleer"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bevestig"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Probeer weer"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Tik weer"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Swiep op om oop te maak"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Druk die onsluitikoon om oop te maak"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ontsluit met gesig. Druk die ontsluitikoon om oop te maak."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ontsluit met gesig. Druk om oop te maak."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Gesig is herken. Druk om oop te maak."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Saai <xliff:g id="SWITCHAPP">%1$s</xliff:g> uit"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Verander uitvoer"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Onbekend"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EE. d MMM."</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 7214ec7..78873e5 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"መሣሪያ ተቆልፏል"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"የቅኝት ፊት"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ላክ"</string>
-    <string name="phone_label" msgid="5715229948920451352">"ስልክ ክፈት"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"የድምጽ ረዳትን ክፈት"</string>
-    <string name="camera_label" msgid="8253821920931143699">"ካሜራ ክፈት"</string>
     <string name="cancel" msgid="1089011503403416730">"ይቅር"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"አረጋግጥ"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"እንደገና ይሞክሩ"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"እንደገና መታ ያድርጉ"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"ለመክፈት በጣት ወደ ላይ ጠረግ ያድርጉ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ለመክፈት የመክፈቻ አዶውን ይጫኑ"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"በመልክ ተከፍቷል። ለመክፈት የመክፈቻ አዶውን ይጫኑ።"</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"በመልክ ተከፍቷል። ለመክፈት ይጫኑ።"</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"መልክ ተለይቶ ታውቋል። ለመክፈት ይጫኑ።"</string>
@@ -547,7 +546,7 @@
     <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"ግራ"</string>
     <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"ቀኝ"</string>
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"መሃል"</string>
-    <string name="keyboard_key_tab" msgid="4592772350906496730">"ትር"</string>
+    <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"ክፍተት"</string>
     <string name="keyboard_key_enter" msgid="8633362970109751646">"አስገባ"</string>
     <string name="keyboard_key_backspace" msgid="4095278312039628074">"የኋሊት መደምሰሻ"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ያሰራጩ"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ውፅዓትን ይቀይሩ"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ያልታወቀ"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE፣ MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 3138bf9..98ab7a4 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"الجهاز مُقفل."</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"مسح الوجه"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"إرسال"</string>
-    <string name="phone_label" msgid="5715229948920451352">"فتح الهاتف"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"فتح المساعد الصوتي"</string>
-    <string name="camera_label" msgid="8253821920931143699">"فتح الكاميرا"</string>
     <string name="cancel" msgid="1089011503403416730">"إلغاء"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"تأكيد"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"إعادة المحاولة"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"انقر مرة أخرى"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"يمكنك الفتح بالتمرير سريعًا لأعلى."</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"اضغط على رمز فتح القفل لفتح قفل الشاشة."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"تم فتح القفل بالتعرّف على وجهك. لفتح الجهاز، اضغط على رمز فتح القفل."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"تم فتح قفل جهازك عند تقريبه من وجهك. اضغط لفتح الجهاز."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"تم التعرّف على الوجه. اضغط لفتح الجهاز."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"بث تطبيق <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"تغيير جهاز الإخراج"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"غير معروف"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"‏EEE،‏ d‏ MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index fdb27ff..564fd1b 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"ডিভাইচটো লক হৈ আছে"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"চেহেৰা স্কেন কৰি থকা হৈছে"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"পঠিয়াওক"</string>
-    <string name="phone_label" msgid="5715229948920451352">"ফ\'ন খোলক"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"কণ্ঠধ্বনিৰে সহায় খোলক"</string>
-    <string name="camera_label" msgid="8253821920931143699">"কেমেৰা খোলক"</string>
     <string name="cancel" msgid="1089011503403416730">"বাতিল কৰক"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"নিশ্চিত কৰক"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"আকৌ চেষ্টা কৰক"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"পুনৰ টিপক"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"খুলিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"খুলিবলৈ আনলক কৰক চিহ্নটোত টিপক"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। খুলিবলৈ আনলক কৰক চিহ্নটোত টিপক।"</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। খুলিবলৈ টিপক।"</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"মুখাৱয়ব চিনাক্ত কৰা হৈছে। খুলিবলৈ টিপক।"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> সম্প্ৰচাৰ কৰক"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"আউটপুট সলনি কৰক"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"অজ্ঞাত"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index e747282..4ce451c 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Cihaz kilidlənib"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Üzün skan edilməsi"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Göndərin"</string>
-    <string name="phone_label" msgid="5715229948920451352">"telefonu açın"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"səs yardımçısını açın"</string>
-    <string name="camera_label" msgid="8253821920931143699">"kemaranı açın"</string>
     <string name="cancel" msgid="1089011503403416730">"Ləğv edin"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Təsdiq"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Yenidən cəhd edin"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Yenidən toxunun"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Açmaq üçün yuxarı sürüşdürün"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"\"Kilidi aç\" ikonasına basıb açın"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Üzlə kilidi açılıb. \"Kilidi aç\" ikonasına basıb açın."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Üz ilə kiliddən çıxarılıb. Açmaq üçün basın."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Üz tanınıb. Açmaq üçün basın."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> tətbiqini yayımlayın"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Nəticəni dəyişdirin"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Naməlum"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"HHH, AAA g"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"s:dd"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ss:dd"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 2b6bd9a..e87cc5e 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Uređaj je zaključan"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skeniranje lica"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošalji"</string>
-    <string name="phone_label" msgid="5715229948920451352">"otvori telefon"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"otvori glasovnu pomoć"</string>
-    <string name="camera_label" msgid="8253821920931143699">"otvori kameru"</string>
     <string name="cancel" msgid="1089011503403416730">"Otkaži"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdi"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Probaj ponovo"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Dodirnite ponovo"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Prevucite nagore da biste otvorili"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pritisnite ikonu otključavanja da biste otvorili."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Otključano je licem. Pritisnite ikonu otključavanja da biste otvorili."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Otključano je licem. Pritisnite da biste otvorili."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Lice je prepoznato. Pritisnite da biste otvorili."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitujte aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Promenite izlaz"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nepoznato"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"DDD, d. MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"s:min"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"č:min"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index f7fabb7..5779cb3 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Прылада заблакіравана"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Сканіраванне твару"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Адправіць"</string>
-    <string name="phone_label" msgid="5715229948920451352">"адкрыць тэлефон"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"адкрыць галасавую дапамогу"</string>
-    <string name="camera_label" msgid="8253821920931143699">"адкрыць камеру"</string>
     <string name="cancel" msgid="1089011503403416730">"Скасаваць"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Пацвердзіць"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Паўтарыць спробу"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Націсніце яшчэ раз"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Каб адкрыць, прагарніце ўверх"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Каб адкрыць, націсніце значок разблакіроўкі"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Твар распазнаны. Для адкрыцця націсніце значок разблакіроўкі"</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Разблакіравана распазнаваннем твару. Націсніце, каб адкрыць."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Твар распазнаны. Націсніце, каб адкрыць."</string>
@@ -374,7 +373,7 @@
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> валодае гэтай прыладай і можа кантраляваць сеткавы трафік"</string>
     <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Гэта прылада належыць вашай арганізацыі і падключана да інтэрнэту праз праграму \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
-    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" і падключана да інтэрнэту праз праграму \"<xliff:g id="VPN_APP">%2$s</xliff:g>\""</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" і падключана да інтэрнэту праз \"<xliff:g id="VPN_APP">%2$s</xliff:g>\""</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Гэта прылада належыць вашай арганізацыі"</string>
     <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\""</string>
     <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Гэта прылада належыць вашай арганізацыі і падключана да інтэрнэту праз сеткі VPN"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Трансляцыя праграмы \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\""</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Змяненне вываду"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Невядома"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index e6608f3..1784939 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Устройството е заключено"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Извършва се сканиране на лице"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Изпращане"</string>
-    <string name="phone_label" msgid="5715229948920451352">"отваряне на телефона"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"отваряне на гласовата помощ"</string>
-    <string name="camera_label" msgid="8253821920931143699">"отваряне на камерата"</string>
     <string name="cancel" msgid="1089011503403416730">"Отказ"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Потвърждаване"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Нов опит"</string>
@@ -278,8 +275,8 @@
     <string name="quick_settings_dark_mode_secondary_label_on_at_bedtime" msgid="2274300599408864897">"Включване, когато стане време за сън"</string>
     <string name="quick_settings_dark_mode_secondary_label_until_bedtime_ends" msgid="1790772410777123685">"До края на времето за сън"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
-    <string name="quick_settings_nfc_off" msgid="3465000058515424663">"КБП е деактивирана"</string>
-    <string name="quick_settings_nfc_on" msgid="1004976611203202230">"КБП е активирана"</string>
+    <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC е деактивирана"</string>
+    <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC е активирана"</string>
     <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Запис на екрана"</string>
     <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Старт"</string>
     <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Стоп"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Докоснете отново"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Прекарайте пръст нагоре, за да отключите"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Натиснете иконата за отключване, за да отворите"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Отключено с лице. Натиснете иконата за отключване, за да отворите."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Отключено с лице. Натиснете за отваряне."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лицето бе разпознато. Натиснете за отваряне."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Предаване на <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Промяна на изхода"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Неизвестно"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 8a89491..dfc8a2b 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"ডিভাইস লক করা আছে"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"ফেস স্ক্যান করা হচ্ছে"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"পাঠান"</string>
-    <string name="phone_label" msgid="5715229948920451352">"ফোন খুলুন"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"ভয়েস সহায়তা খুলুন"</string>
-    <string name="camera_label" msgid="8253821920931143699">"ক্যামেরা খুলুন"</string>
     <string name="cancel" msgid="1089011503403416730">"বাতিল করুন"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"কনফার্ম করুন"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"আবার চেষ্টা করুন"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"আবার ট্যাপ করুন"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"খোলার জন্য উপরে সোয়াইপ করুন"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"খোলার জন্য আনলক আইকন প্রেস করুন"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ফেসের সাহায্যে আনলক করা হয়েছে। খোলার জন্য আনলক আইকন প্রেস করুন।"</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ফেসের সাহায্যে আনলক করা হয়েছে। খোলার জন্য প্রেস করুন।"</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ফেস শনাক্ত করা হয়েছে। খোলার জন্য প্রেস করুন।"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> সম্প্রচার করুন"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"আউটপুট পরিবর্তন করুন"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"অজানা"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index ad7f10b..1ae04fe 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Uređaj je zaključan"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skeniranje lica"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošalji"</string>
-    <string name="phone_label" msgid="5715229948920451352">"otvori telefon"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"otvori glasovnu pomoć"</string>
-    <string name="camera_label" msgid="8253821920931143699">"otvori kameru"</string>
     <string name="cancel" msgid="1089011503403416730">"Otkaži"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdite"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Pokušaj ponovo"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Ponovo dodirnite"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Prevucite da otvorite"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pritisnite ikonu za otključavanje da otvorite."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Otključano licem. Pritisnite ikonu za otklj. da otvorite."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Otključano licem. Pritisnite da otvorite."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Lice prepoznato. Pritisnite da otvorite."</string>
@@ -374,11 +373,11 @@
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> upravlja ovim uređajem i može nadzirati mrežni saobraćaj"</string>
     <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Ovaj uređaj pruža <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Ovaj uređaj pripada vašoj organizaciji i povezan je s internetom putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
-    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je na internet putem aplikacije <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s internetom putem aplikacije <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Ovaj uređaj pripada vašoj organizaciji"</string>
     <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
-    <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Ovaj uređaj pripada vašoj organizaciji i povezan je na internet putem VPN-ova"</string>
-    <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je na internet putem VPN-ova"</string>
+    <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Ovaj uređaj pripada vašoj organizaciji i povezan je s internetom putem VPN-ova"</string>
+    <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s internetom putem VPN-ova"</string>
     <string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Vaša organizacija može pratiti mrežni saobraćaj na vašem profilu."</string>
     <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> može pratiti mrežni saobraćaj na vašem radnom profilu"</string>
     <string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Mrežna aktivnost radnog profila je vidljiva vašem IT administratoru"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitiraj aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Promijeni izlaz"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nepoznato"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"DDD, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index f7441f3..0899d88 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositiu bloquejat"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"S\'està escanejant la cara"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Envia"</string>
-    <string name="phone_label" msgid="5715229948920451352">"obre el telèfon"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"obre l\'assistència per veu"</string>
-    <string name="camera_label" msgid="8253821920931143699">"obre la càmera"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancel·la"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirma"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Torna-ho a provar"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Torna a tocar"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Llisca cap amunt per obrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Prem la icona de desbloqueig per obrir"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"S\'ha desbloquejat amb la cara. Prem la icona per obrir."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"S\'ha desbloquejat amb la cara. Prem per obrir."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"S\'ha reconegut la cara. Prem per obrir."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emet <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Canvia la sortida"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconeguda"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"hh:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index bb2ec59..db65316 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Zařízení uzamčeno"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skenování obličeje"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Odeslat"</string>
-    <string name="phone_label" msgid="5715229948920451352">"otevřít telefon"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"otevřít hlasovou asistenci"</string>
-    <string name="camera_label" msgid="8253821920931143699">"spustit fotoaparát"</string>
     <string name="cancel" msgid="1089011503403416730">"Zrušit"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdit"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Zkusit znovu"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Znovu klepněte"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Otevřete přejetím prstem nahoru"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Otevřete klepnutím na ikonu odemknutí"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odemknuto obličejem. Klepněte na ikonu odemknutí."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Odemknuto obličejem. Stisknutím otevřete."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Obličej rozpoznán. Stisknutím otevřete."</string>
@@ -374,7 +373,7 @@
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Toto zařízení spravuje organizace <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, která může sledovat síťový provoz"</string>
     <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Toto zařízení poskytuje <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Toto zařízení patří vaší organizaci a je připojeno k internetu prostřednictvím aplikace <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
-    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Toto zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a je připojeno k internetu prostřednictvím aplikace <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a je připojeno k internetu pomocí aplikace <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Toto zařízení patří vaší organizaci"</string>
     <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Toto zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Toto zařízení patří vaší organizaci a je připojeno k internetu prostřednictvím sítí VPN"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Vysílat v aplikaci <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Změna výstupu"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Neznámé"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d. MMMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"H:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index c9722eb..c1e364b 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Enheden er låst"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanner ansigt"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
-    <string name="phone_label" msgid="5715229948920451352">"åbn telefon"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"åbn taleassistent"</string>
-    <string name="camera_label" msgid="8253821920931143699">"åbn kamera"</string>
     <string name="cancel" msgid="1089011503403416730">"Annuller"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bekræft"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Prøv igen"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Tryk igen"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Stryg opad for at åbne"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Tryk på oplåsningsikonet for at åbne"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Låst op vha. ansigt. Tryk på oplåsningsikonet for at åbne."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Låst op ved hjælp af ansigt. Tryk for at åbne."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ansigt genkendt. Tryk for at åbne."</string>
@@ -374,7 +373,7 @@
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ejer denne enhed og overvåger muligvis netværkstrafikken"</string>
     <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Denne enhed er leveret af <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Denne enhed tilhører din organisation, og den har forbindelse til internettet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
-    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, og den har forbindelse til nettet via <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, og den har forbindelse til internettet via <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Denne enhed tilhører din organisation"</string>
     <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Denne enhed tilhører din organisation, og den har forbindelse til nettet via VPN-forbindelser"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Udsend <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Skift output"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ukendt"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d. MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"tt.mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk.mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 169e475..618901c 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Gerät gesperrt"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Gesicht wird gescannt"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Senden"</string>
-    <string name="phone_label" msgid="5715229948920451352">"Telefon öffnen"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"Sprachassistent öffnen"</string>
-    <string name="camera_label" msgid="8253821920931143699">"Kamera öffnen"</string>
     <string name="cancel" msgid="1089011503403416730">"Abbrechen"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bestätigen"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Noch einmal versuchen"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Noch einmal tippen"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Zum Öffnen nach oben wischen"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Tippe zum Öffnen auf das Symbol „Entsperren“"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Gerät mit dem Gesicht entsperrt. Tippe zum Öffnen auf das Symbol „Entsperren“."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Gerät mit dem Gesicht entsperrt. Tippe zum Öffnen."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Gesicht erkannt. Tippe zum Öffnen."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> streamen"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Ausgabe ändern"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unbekannt"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index fc03b57..4a15ede 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Η συσκευή κλειδώθηκε"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Σάρωση προσώπου"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Αποστολή"</string>
-    <string name="phone_label" msgid="5715229948920451352">"άνοιγμα τηλεφώνου"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"άνοιγμα φωνητικής υποβοήθησης"</string>
-    <string name="camera_label" msgid="8253821920931143699">"άνοιγμα φωτογραφικής μηχανής"</string>
     <string name="cancel" msgid="1089011503403416730">"Ακύρωση"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Επιβεβαίωση"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Δοκιμάστε ξανά"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Πατήστε ξανά"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Σύρετε προς τα επάνω για άνοιγμα"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Πατήστε το εικονίδιο ξεκλειδώματος για άνοιγμα"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ξεκλείδωμα με πρόσωπο. Πατήστε το εικονίδιο ξεκλειδώματος."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ξεκλείδωμα με αναγνώριση προσώπου. Πατήστε για άνοιγμα."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Το πρόσωπο αναγνωρίστηκε. Πατήστε για άνοιγμα."</string>
@@ -374,7 +373,7 @@
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Ο οργανισμός <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> κατέχει αυτήν τη συσκευή και μπορεί να παρακολουθεί την επισκεψιμότητα δικτύου."</string>
     <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Αυτή η συσκευή παρέχεται από τον οργανισμό <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Αυτή η συσκευή ανήκει στον οργανισμό σας και συνδέεται στο διαδίκτυο μέσω της εφαρμογής <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
-    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Αυτή η συσκευή ανήκει στον οργανισμό <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> και συνδέεται στο διαδίκτυο μέσω της εφαρμογής <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Αυτή η συσκευή ανήκει σε <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> και συνδέεται στο διαδίκτυο μέσω  <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Αυτή η συσκευή ανήκει στον οργανισμό σας."</string>
     <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Αυτή η συσκευή ανήκει στον οργανισμό <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Αυτή η συσκευή ανήκει στον οργανισμό σας και συνδέεται στο διαδίκτυο μέσω VPN"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Μετάδοση με την εφαρμογή <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Αλλαγή εξόδου"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Άγνωστο"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"ΗΗΗ, ΜΜΜ η"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"ώ:λλ"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:λλ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 89b00b4..634a9da 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
-    <string name="phone_label" msgid="5715229948920451352">"open phone"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"open voice assist"</string>
-    <string name="camera_label" msgid="8253821920931143699">"open camera"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancel"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirm"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Try again"</string>
@@ -310,6 +307,7 @@
     <string name="tap_again" msgid="1315420114387908655">"Tap again"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Press the unlock icon to open"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Unlocked by face. Swipe up to open."</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Unlocked by face. Press the unlock icon to open."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Unlocked by face. Press to open."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Face recognised. Press to open."</string>
@@ -953,4 +951,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 0519c96..f0e2208 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
-    <string name="phone_label" msgid="5715229948920451352">"open phone"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"open voice assist"</string>
-    <string name="camera_label" msgid="8253821920931143699">"open camera"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancel"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirm"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Try again"</string>
@@ -310,6 +307,7 @@
     <string name="tap_again" msgid="1315420114387908655">"Tap again"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Press the unlock icon to open"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Unlocked by face. Swipe up to open."</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Unlocked by face. Press the unlock icon to open."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Unlocked by face. Press to open."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Face recognised. Press to open."</string>
@@ -953,4 +951,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 89b00b4..634a9da 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
-    <string name="phone_label" msgid="5715229948920451352">"open phone"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"open voice assist"</string>
-    <string name="camera_label" msgid="8253821920931143699">"open camera"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancel"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirm"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Try again"</string>
@@ -310,6 +307,7 @@
     <string name="tap_again" msgid="1315420114387908655">"Tap again"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Press the unlock icon to open"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Unlocked by face. Swipe up to open."</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Unlocked by face. Press the unlock icon to open."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Unlocked by face. Press to open."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Face recognised. Press to open."</string>
@@ -953,4 +951,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 89b00b4..634a9da 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
-    <string name="phone_label" msgid="5715229948920451352">"open phone"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"open voice assist"</string>
-    <string name="camera_label" msgid="8253821920931143699">"open camera"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancel"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirm"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Try again"</string>
@@ -310,6 +307,7 @@
     <string name="tap_again" msgid="1315420114387908655">"Tap again"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Press the unlock icon to open"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Unlocked by face. Swipe up to open."</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Unlocked by face. Press the unlock icon to open."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Unlocked by face. Press to open."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Face recognised. Press to open."</string>
@@ -953,4 +951,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index a341d59..1418095 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‎‏‏‏‎‎‎‎‏‏‎‎‎‎‎‏‏‏‏‎‎‎‏‎‎‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‏‏‏‏‎Device locked‎‏‎‎‏‎"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎Scanning face‎‏‎‎‏‎"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‏‏‏‎‎‏‎‎‏‎‎‏‏‎‏‎‏‎‎‎‎‏‎‎‏‏‎‏‎‎‏‎‏‎Send‎‏‎‎‏‎"</string>
-    <string name="phone_label" msgid="5715229948920451352">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‎‎‎‏‎‎‎‏‏‎‎‎‎open phone‎‏‎‎‏‎"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‏‎‎‏‎‏‏‏‏‎‎‎open voice assist‎‏‎‎‏‎"</string>
-    <string name="camera_label" msgid="8253821920931143699">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‏‎‏‎‎‏‏‏‎‎‏‏‏‎‏‎‎‎‏‏‎‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‏‎‎‏‏‎open camera‎‏‎‎‏‎"</string>
     <string name="cancel" msgid="1089011503403416730">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‏‎‏‎‎‏‎‎‎‏‎‏‎‏‏‎‎‏‎‏‏‏‏‎‎‏‎‎‏‏‎‏‎‎Cancel‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‎‏‏‎‏‎‏‎‏‎‏‎‏‏‎‎‎‏‎‎‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‎Confirm‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‏‎‎‏‏‎‎‎‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‎‎‎‏‏‎‎‎Try again‎‏‎‎‏‎"</string>
@@ -310,6 +307,7 @@
     <string name="tap_again" msgid="1315420114387908655">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‎‎‎‏‎‏‎‎‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎Tap again‎‏‎‎‏‎"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‏‏‏‎‎‎‏‎‎‏‎‎‎‎‎‏‎Swipe up to open‎‏‎‎‏‎"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‏‏‎‎‎‏‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‎‏‏‎‎‎‎‏‎‏‏‎‎‏‎‎‏‎Press the unlock icon to open‎‏‎‎‏‎"</string>
+    <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‎‎‎‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‎‏‎Unlocked by face. Swipe up to open.‎‏‎‎‏‎"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‏‎‏‎‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‏‏‎‎‏‏‎‏‎‎‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‎‎‎Unlocked by face. Press the unlock icon to open.‎‏‎‎‏‎"</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‎‎‎‏‎‏‏‎‎‏‎‏‏‎‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‏‎‎‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‎‎Unlocked by face. Press to open.‎‏‎‎‏‎"</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎‏‎‏‏‎‏‎‎‏‎‎‎‏‏‎‏‏‎‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎Face recognized. Press to open.‎‏‎‎‏‎"</string>
@@ -953,4 +951,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‎‎‎‏‏‎‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‎‏‎‏‏‎‏‎‎‏‏‏‎‎‎‏‎‎‎‏‎‏‎Broadcast ‎‏‎‎‏‏‎<xliff:g id="SWITCHAPP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‏‏‎‎‎‎‎‏‎‏‎‎‏‎‏‎‎‏‎‎‏‎‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‎‏‏‏‎‏‏‏‎‎‏‎‎Change output‎‏‎‎‏‎"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‎‎‎‎‎‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎Unknown‎‏‎‎‏‎"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‏‎‏‎‎‎‏‎‏‎‎‎‎‎‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎EEE, MMM d‎‏‎‎‏‎"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎h:mm‎‏‎‎‏‎"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‏‏‎‎‏‎‏‏‎‏‎‎‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎kk:mm‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index c759542..26d9801 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Escaneando rostro"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
-    <string name="phone_label" msgid="5715229948920451352">"abrir teléfono"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"abrir el asistente de voz"</string>
-    <string name="camera_label" msgid="8253821920931143699">"abrir cámara"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancelar"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Volver a intentarlo"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Presiona otra vez"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Desliza el dedo hacia arriba para abrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Presiona el ícono de desbloquear para abrir"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueo con rostro. Presiona el ícono para abrir."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueo con rostro. Presiona para abrir."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Rostro reconocido. Presiona para abrir."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambia la salida"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconocido"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d de MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index aff8998..1876d77 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Escaneando cara"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
-    <string name="phone_label" msgid="5715229948920451352">"abrir teléfono"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"abrir el asistente de voz"</string>
-    <string name="camera_label" msgid="8253821920931143699">"abrir cámara"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancelar"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Reintentar"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Toca de nuevo"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Desliza el dedo hacia arriba para abrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pulsa el icono desbloquear para abrir"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueado con la cara. Toca el icono de desbloquear para abrir."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueado con la cara. Pulsa para abrir."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Cara reconocida. Pulsa para abrir."</string>
@@ -402,7 +401,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Se ha instalado una entidad de certificación en este dispositivo. Es posible que se supervise o se modifique tu tráfico de red seguro."</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"El administrador ha activado el registro de la red para supervisar el tráfico en tu dispositivo."</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Tu administrador ha activado el registro de la red, por lo que se monitorizará el tráfico de tu perfil de trabajo, aunque no el de tu perfil personal."</string>
-    <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Este dispositivo está conectado a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. Tu actividad de red, como los correos electrónicos y los datos de navegación, es visible para tu administrador de TI."</string>
+    <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Este dispositivo está conectado a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. Tu actividad en esta red, como tus correos electrónicos y tus datos de navegación, es visible para tu administrador de TI."</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Este dispositivo está conectado a Internet a través de <xliff:g id="VPN_APP_0">%1$s</xliff:g> y <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Tu actividad de red, como los correos electrónicos y los datos de navegación, es visible para tu administrador de TI."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Tus aplicaciones de trabajo están conectadas a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. Tu actividad de red en las aplicaciones de trabajo, incluidos los correos electrónicos y los datos de navegación, es visible para tu administrador de TI y tu proveedor de VPN."</string>
     <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Tus aplicaciones personales están conectadas a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. Tu actividad de red, como los correos electrónicos y los datos de navegación, es visible para tu proveedor de VPN."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambiar salida"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconocido"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/tiles_states_strings.xml b/packages/SystemUI/res/values-es/tiles_states_strings.xml
index d3e7c8b..8d5c3c6 100644
--- a/packages/SystemUI/res/values-es/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-es/tiles_states_strings.xml
@@ -59,7 +59,7 @@
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"No disponible"</item>
     <item msgid="5044688398303285224">"Desactivada"</item>
-    <item msgid="8527389108867454098">"Activada"</item>
+    <item msgid="8527389108867454098">"Activado"</item>
   </string-array>
   <string-array name="tile_states_rotation">
     <item msgid="4578491772376121579">"No disponible"</item>
@@ -88,7 +88,7 @@
   </string-array>
   <string-array name="tile_states_color_correction">
     <item msgid="2840507878437297682">"No disponible"</item>
-    <item msgid="1909756493418256167">"Desactivada"</item>
+    <item msgid="1909756493418256167">"Desactivado"</item>
     <item msgid="4531508423703413340">"Activado"</item>
   </string-array>
   <string-array name="tile_states_inversion">
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index e11a165..c64fef9 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Seade on lukustatud"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Näo skannimine"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Saada"</string>
-    <string name="phone_label" msgid="5715229948920451352">"ava telefon"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"ava häälabi"</string>
-    <string name="camera_label" msgid="8253821920931143699">"ava kaamera"</string>
     <string name="cancel" msgid="1089011503403416730">"Tühista"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Kinnita"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Proovi uuesti"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Puudutage uuesti"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Pühkige avamiseks üles"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Avamiseks vajutage avamise ikooni"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Avati näoga. Avamiseks vajutage avamise ikooni."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Avati näoga. Avamiseks vajutage."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Nägu tuvastati. Avamiseks vajutage."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Rakenduse <xliff:g id="SWITCHAPP">%1$s</xliff:g> ülekandmine"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Väljundi muutmine"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Tundmatu"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 35142b9..0c1302e 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Gailua blokeatuta dago"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Aurpegia eskaneatzen"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Bidali"</string>
-    <string name="phone_label" msgid="5715229948920451352">"ireki telefonoan"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"ireki ahots-laguntza"</string>
-    <string name="camera_label" msgid="8253821920931143699">"ireki kamera"</string>
     <string name="cancel" msgid="1089011503403416730">"Utzi"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Berretsi"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Saiatu berriro"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Sakatu berriro"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Pasatu hatza gora irekitzeko"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Irekitzeko, sakatu desblokeatzeko ikonoa"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Aurpegiaren bidez desblokeatu da. Irekitzeko, sakatu desblokeatzeko ikonoa."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Aurpegiaren bidez desblokeatu da. Sakatu irekitzeko."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ezagutu da aurpegia. Sakatu irekitzeko."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Igorri <xliff:g id="SWITCHAPP">%1$s</xliff:g> aplikazioaren audioa"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Aldatu audio-irteera"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ezezaguna"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 8719b00..bd0b037 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"دستگاه قفل است"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"درحال اسکن کردن چهره"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ارسال"</string>
-    <string name="phone_label" msgid="5715229948920451352">"باز کردن تلفن"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"«دستیار صوتی» را باز کنید"</string>
-    <string name="camera_label" msgid="8253821920931143699">"باز کردن دوربین"</string>
     <string name="cancel" msgid="1089011503403416730">"لغو"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"تأیید"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"امتحان مجدد"</string>
@@ -293,9 +290,9 @@
     <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"میکروفن مسدود شده است"</string>
     <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"دوربین مسدود شده است"</string>
     <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"میکروفون و دوربین مسدود شده‌اند"</string>
-    <string name="sensor_privacy_start_use_mic_blocked_dialog_content" msgid="2138318880682877747">"برای لغو انسداد، کلید حریم‌خصوصی روی دستگاه را به موقعیت میکروفون روشن ببرید تا دسترسی به میکروفون مجاز شود. برای پیدا کردن کلید حریم‌خصوصی روی دستگاه، به دفترچه راهنمای دستگاه مراجعه کنید."</string>
-    <string name="sensor_privacy_start_use_camera_blocked_dialog_content" msgid="7216015168047965948">"برای لغو انسداد، کلید حریم‌خصوصی روی دستگاه را به موقعیت دوربین روشن ببرید تا دسترسی به دوربین مجاز شود. برای پیدا کردن کلید حریم‌خصوصی روی دستگاه، به دفترچه راهنمای دستگاه مراجعه کنید."</string>
-    <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_content" msgid="3960837827570483762">"برای لغو انسداد آن، کلید حریم‌خصوصی روی دستگاه را به موقعیت لغو انسداد ببرید تا دسترسی مجاز شود. برای پیدا کردن کلید حریم‌خصوصی روی دستگاه، به دفترچه راهنمای دستگاه مراجعه کنید."</string>
+    <string name="sensor_privacy_start_use_mic_blocked_dialog_content" msgid="2138318880682877747">"برای لغو انسداد، کلید حریم خصوصی روی دستگاه را به موقعیت میکروفون روشن ببرید تا دسترسی به میکروفون مجاز شود. برای پیدا کردن کلید حریم خصوصی روی دستگاه، به دفترچه راهنمای دستگاه مراجعه کنید."</string>
+    <string name="sensor_privacy_start_use_camera_blocked_dialog_content" msgid="7216015168047965948">"برای لغو انسداد، کلید حریم خصوصی روی دستگاه را به موقعیت دوربین روشن ببرید تا دسترسی به دوربین مجاز شود. برای پیدا کردن کلید حریم خصوصی روی دستگاه، به دفترچه راهنمای دستگاه مراجعه کنید."</string>
+    <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_content" msgid="3960837827570483762">"برای لغو انسداد آن، کلید حریم خصوصی روی دستگاه را به موقعیت لغو انسداد ببرید تا دسترسی مجاز شود. برای پیدا کردن کلید حریم خصوصی روی دستگاه، به دفترچه راهنمای دستگاه مراجعه کنید."</string>
     <string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"میکروفون دردسترس است"</string>
     <string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"دوربین دردسترس است"</string>
     <string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"میکروفون و دوربین دردسترس‌اند"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"دوباره ضربه بزنید"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"برای باز کردن، انگشتتان را تند به‌بالا بکشید"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"برای باز کردن، نماد قفل‌گشایی را فشار دهید"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"قفلْ با چهره باز شد. برای باز کردن، نماد قفل‌گشایی را فشار دهید."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"قفلْ با چهره باز شد. برای باز کردن، فشار دهید."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"چهره شناسایی شد. برای باز کردن، فشار دهید."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"همه‌فرستی <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"تغییر خروجی"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"نامشخص"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 54be04f..329cc44 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Laite lukittu"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Kasvojen skannaus"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Lähetä"</string>
-    <string name="phone_label" msgid="5715229948920451352">"avaa puhelin"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"Avaa ääniapuri"</string>
-    <string name="camera_label" msgid="8253821920931143699">"avaa kamera"</string>
     <string name="cancel" msgid="1089011503403416730">"Peru"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Vahvista"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Yritä uudelleen"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Napauta uudelleen"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Avaa pyyhkäisemällä ylös"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Jatka painamalla lukituksen avauskuvaketta."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Avattu kasvojen avulla. Jatka lukituksen avauskuvakkeella."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Avattu kasvojen avulla. Avaa painamalla."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Kasvot tunnistettu. Avaa painamalla."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Lähetä <xliff:g id="SWITCHAPP">%1$s</xliff:g>-sovellusta"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Muuta ulostuloa"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Tuntematon"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"VKP, KKK p"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index f9b1896..1fc6b8c 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Appareil verrouillé"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Numérisation du visage"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Envoyer"</string>
-    <string name="phone_label" msgid="5715229948920451352">"Ouvrir le téléphone"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"ouvrir l\'assistance vocale"</string>
-    <string name="camera_label" msgid="8253821920931143699">"Ouvrir l\'appareil photo"</string>
     <string name="cancel" msgid="1089011503403416730">"Annuler"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmer"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Réessayer"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Toucher de nouveau"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Balayez l\'écran vers le haut pour ouvrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Appuyez sur l\'icône Déverrouiller pour ouvrir"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Déverr. par reconn. faciale. App. sur l\'icône pour ouvrir."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Déverr. par reconnaissance faciale. Appuyez pour ouvrir."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Visage reconnu. Appuyez pour ouvrir."</string>
@@ -374,7 +373,7 @@
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> possède cet appareil et peut contrôler le trafic réseau"</string>
     <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Cet appareil est fourni par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Cet appareil appartient à votre organisation et est connecté à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
-    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> et est connecté à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> et est connecté à Internet par <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Cet appareil appartient à votre organisation"</string>
     <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Cet appareil appartient à votre organisation et est connecté à Internet par l\'intermédiaire de RPV"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Diffuser <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Changer la sortie"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Inconnue"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 815f018..79acfdb 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Appareil verrouillé"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Analyse du visage en cours"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Envoyer"</string>
-    <string name="phone_label" msgid="5715229948920451352">"ouvrir le téléphone"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"ouvrir l\'assistance vocale"</string>
-    <string name="camera_label" msgid="8253821920931143699">"ouvrir l\'appareil photo"</string>
     <string name="cancel" msgid="1089011503403416730">"Annuler"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmer"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Réessayer"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Appuyer à nouveau"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Balayer vers le haut pour ouvrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Appuyez sur l\'icône de déverrouillage pour ouvrir"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Déverrouillé par visage. Appuyez sur icône déverrouillage pour ouvrir."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Déverrouillé par visage. Appuyez pour ouvrir."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Visage reconnu. Appuyez pour ouvrir."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Diffuser <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Modifier le résultat"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Inconnue"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM j"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"hh:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index d510b83..e73aa03 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Analizando cara"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
-    <string name="phone_label" msgid="5715229948920451352">"abrir teléfono"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"abrir asistente de voz"</string>
-    <string name="camera_label" msgid="8253821920931143699">"abrir cámara"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancelar"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Tentar de novo"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Toca de novo"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Pasa o dedo cara arriba para abrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Preme a icona de desbloquear para abrir a porta"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Usouse o desbloqueo facial. Preme a icona de desbloquear."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Usouse o desbloqueo facial. Preme para abrir."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Recoñeceuse a cara. Preme para abrir."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitir contido a través de <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambiar de saída"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Descoñecida"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 6d14e46..e00f5ff 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"ડિવાઇસ લૉક કરેલું છે"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"ચહેરો સ્કૅન કરવો"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"મોકલો"</string>
-    <string name="phone_label" msgid="5715229948920451352">"ફોન ખોલો"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"વૉઇસ સહાય ખોલો"</string>
-    <string name="camera_label" msgid="8253821920931143699">"કૅમેરા ખોલો"</string>
     <string name="cancel" msgid="1089011503403416730">"રદ કરો"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"કન્ફર્મ કરો"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ફરી પ્રયાસ કરો"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"ફરીથી ટૅપ કરો"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"ખોલવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ખોલવા માટે \'અનલૉક કરો\' આઇકન દબાવો"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ચહેરા દ્વારા અનલૉક કર્યું. ખોલવા \'અનલૉક કરો\' આઇકન દબાવો."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ચહેરા દ્વારા અનલૉક કર્યું. ખોલવા માટે દબાવો."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ચહેરો ઓળખ્યો. ખોલવા માટે દબાવો."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> બ્રોડકાસ્ટ કરો"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"આઉટપુટ બદલો"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"અજાણ"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index d385337..b74d287 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"डिवाइस लॉक है"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"डिवाइस अनलॉक करने के लिए चेहरा स्कैन किया जाता है"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"भेजें"</string>
-    <string name="phone_label" msgid="5715229948920451352">"फ़ोन खोलें"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"आवाज़ से डिवाइस को इस्तेमाल करें"</string>
-    <string name="camera_label" msgid="8253821920931143699">"कैमरा खोलें"</string>
     <string name="cancel" msgid="1089011503403416730">"रद्द करें"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"पुष्टि करें"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"फिर से कोशिश करें"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"फिर से टैप करें"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"खोलने के लिए ऊपर स्वाइप करें"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"डिवाइस अनलॉक करने के लिए, अनलॉक आइकॉन को दबाएं"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"चेहरे से अनलॉक किया. डिवाइस अनलॉक करने के लिए, अनलॉक आइकॉन को दबाएं."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"चेहरे से अनलॉक किया गया. डिवाइस खोलने के लिए टैप करें."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"चेहरे की पहचान हो गई. डिवाइस खोलने के लिए टैप करें."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> पर ब्रॉडकास्ट करें"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"आउटपुट बदलें"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"कोई जानकारी नहीं"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 60a8402..823d2f4 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Uređaj je zaključan"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skeniranje lica"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošalji"</string>
-    <string name="phone_label" msgid="5715229948920451352">"otvaranje telefona"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"otvaranje glasovne pomoći"</string>
-    <string name="camera_label" msgid="8253821920931143699">"otvaranje fotoaparata"</string>
     <string name="cancel" msgid="1089011503403416730">"Odustani"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdi"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Pokušaj ponovo"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Dodirnite ponovo"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Prijeđite prstom prema gore da biste otvorili"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pritisnite ikonu otključavanja da biste otvorili"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Otključano pomoću lica. Pritisnite ikonu otključavanja da biste otvorili."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Otključano pomoću lica. Pritisnite da biste otvorili."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Lice je prepoznato. Pritisnite da biste otvorili."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitiranje aplikacije <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Promjena izlaza"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nepoznato"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE., d. MMM."</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 9b09ccc..12e2d70 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Az eszköz zárolva van"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Arc keresése"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Küldés"</string>
-    <string name="phone_label" msgid="5715229948920451352">"telefon megnyitása"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"hangsegéd megnyitása"</string>
-    <string name="camera_label" msgid="8253821920931143699">"kamera megnyitása"</string>
     <string name="cancel" msgid="1089011503403416730">"Mégse"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Megerősítés"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Újrapróbálkozás"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Koppintson újra"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Csúsztasson felfelé a megnyitáshoz"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Az eszköz használatához nyomja meg a feloldás ikonját"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Arccal feloldva. A megnyitáshoz nyomja meg a feloldás ikont."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Zárolás arccal feloldva. Koppintson az eszköz használatához."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Arc felismerve. Koppintson az eszköz használatához."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> közvetítése"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Kimenet módosítása"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ismeretlen"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, HHH n"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"ó:pp"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"óó:pp"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index a707c63..c702969 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Սարքը կողպված է"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Դեմքի սկանավորում"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Ուղարկել"</string>
-    <string name="phone_label" msgid="5715229948920451352">"բացել հեռախոսը"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"բացեք ձայնային հուշումը"</string>
-    <string name="camera_label" msgid="8253821920931143699">"բացել ֆոտոխցիկը"</string>
     <string name="cancel" msgid="1089011503403416730">"Չեղարկել"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Հաստատել"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Նորից փորձել"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Նորից հպեք"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Բացելու համար սահեցրեք վերև"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Բացեք՝ սեղմելով ապակողպման պատկերակը"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ապակողպվել է դեմքով։ Բացեք՝ սեղմելով ապակողպման պատկերակը։"</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ապակողպվել է դեմքով։ Սեղմեք բացելու համար։"</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Դեմքը ճանաչվեց։ Սեղմեք բացելու համար։"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Հեռարձակել <xliff:g id="SWITCHAPP">%1$s</xliff:g> հավելվածը"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Փոխել աուդիո ելքը"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Անհայտ"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index fb51e6b..e52d08d 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Perangkat terkunci"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Memindai wajah"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Kirim"</string>
-    <string name="phone_label" msgid="5715229948920451352">"buka ponsel"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"buka bantuan suara"</string>
-    <string name="camera_label" msgid="8253821920931143699">"buka kamera"</string>
     <string name="cancel" msgid="1089011503403416730">"Batal"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Konfirmasi"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Coba lagi"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Ketuk lagi"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Geser ke atas untuk membuka"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Tekan ikon buka kunci untuk membuka"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Kunci dibuka dengan wajah. Tekan ikon buka kunci untuk membuka."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Kunci dibuka dengan wajah. Tekan untuk membuka."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Wajah dikenali. Tekan untuk membuka."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Siarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Ubah output"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Tidak diketahui"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 7420ff1..e8d2d86 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Tækið er læst"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Andlit skannað"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Senda"</string>
-    <string name="phone_label" msgid="5715229948920451352">"opna síma"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"opna raddaðstoð"</string>
-    <string name="camera_label" msgid="8253821920931143699">"opna myndavél"</string>
     <string name="cancel" msgid="1089011503403416730">"Hætta við"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Staðfesta"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Reyna aftur"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Ýttu aftur"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Strjúktu upp til að opna"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Ýttu á táknið til að taka úr lás til að opna"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Opnað með andliti. Ýttu á táknið taka úr lás til að opna."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Opnað með andliti. Ýttu til að opna."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Andlitið var greint. Ýttu til að opna."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Senda út <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Skipta um úttak"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Óþekkt"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"k:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index e16fc15..5d318bf 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloccato"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scansione del viso"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Invia"</string>
-    <string name="phone_label" msgid="5715229948920451352">"apri telefono"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"apri Voice Assist"</string>
-    <string name="camera_label" msgid="8253821920931143699">"apri fotocamera"</string>
     <string name="cancel" msgid="1089011503403416730">"Annulla"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Conferma"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Riprova"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Tocca di nuovo"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Scorri verso l\'alto per aprire"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Premi l\'icona Sblocca per aprire"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Sbloccato con il volto. Premi l\'icona Sblocca per aprire."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Sbloccato con il volto. Premi per aprire."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Volto riconosciuto. Premi per aprire."</string>
@@ -953,4 +952,10 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Trasmetti l\'app <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambia uscita"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
+    <!-- no translation found for dream_date_complication_date_format (8191225366513860104) -->
+    <skip />
+    <!-- no translation found for dream_time_complication_12_hr_time_format (4691197486690291529) -->
+    <skip />
+    <!-- no translation found for dream_time_complication_24_hr_time_format (6248280719733640813) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index a889c9c..25e08c6 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"המכשיר נעול"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"סורק פנים"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"שליחה"</string>
-    <string name="phone_label" msgid="5715229948920451352">"פתיחת הטלפון"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"פתיחת האסיסטנט"</string>
-    <string name="camera_label" msgid="8253821920931143699">"פתיחת המצלמה"</string>
     <string name="cancel" msgid="1089011503403416730">"ביטול"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"אישור"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ניסיון נוסף"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"צריך להקיש פעם נוספת"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"צריך להחליק כדי לפתוח"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"לפתיחה, לוחצים על סמל ביטול הנעילה"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"הנעילה בוטלה בזיהוי פנים. פותחים בלחיצה על סמל ביטול הנעילה."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"הנעילה בוטלה באמצעות זיהוי הפנים. יש ללחוץ כדי לפתוח."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"הפנים זוהו. יש ללחוץ כדי לפתוח."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"שידור תוכן מאפליקציית <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"שינוי הפלט"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"לא ידוע"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"‏יום EEE,‏ d בMMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 7bfa60c..69a9592 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"デバイスはロックされています"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"顔のスキャン"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"送信"</string>
-    <string name="phone_label" msgid="5715229948920451352">"電話を起動"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"音声アシストを開く"</string>
-    <string name="camera_label" msgid="8253821920931143699">"カメラを起動"</string>
     <string name="cancel" msgid="1089011503403416730">"キャンセル"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"確認"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"再試行"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"もう一度タップしてください"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"開くには上にスワイプします"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ロック解除アイコンを押して開きます"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"顔でロック解除しました。アイコンを押すと開きます。"</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"顔でロック解除しました。押すと開きます。"</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"顔を認識しました。押すと開きます。"</string>
@@ -374,7 +373,7 @@
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスで、ネットワーク トラフィックが監視されることもあります"</string>
     <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"このデバイスは <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> から提供されています"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"これは組織が所有するデバイスで、<xliff:g id="VPN_APP">%1$s</xliff:g>を介してインターネットに接続しています"</string>
-    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスで、<xliff:g id="VPN_APP">%2$s</xliff:g>を介してインターネットに接続しています"</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"このデバイスは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有し、<xliff:g id="VPN_APP">%2$s</xliff:g> を介してインターネットに接続されています"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"これは組織が所有するデバイスです"</string>
     <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスです"</string>
     <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"これは組織が所有するデバイスで、VPN を介してインターネットに接続しています"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> をブロードキャスト"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"出力を変更"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"不明"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 406aea6..fc1ecda 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"მოწყობილობა ჩაკეტილია"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"მიმდინარეობს სახის სკანირება"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"გაგზავნა"</string>
-    <string name="phone_label" msgid="5715229948920451352">"ტელეფონის გახსნა"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"ხმოვანი დახმარების გახსნა"</string>
-    <string name="camera_label" msgid="8253821920931143699">"კამერის გახსნა"</string>
     <string name="cancel" msgid="1089011503403416730">"გაუქმება"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"დადასტურება"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ხელახლა ცდა"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"შეეხეთ ხელახლა"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"გასახსნელად გადაფურცლეთ ზემოთ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"გასახსნელად დააჭირეთ განბლოკვის ხატულას"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"განიბლოკა სახით. გასახსნელად დააჭირეთ განბლოკვის ხატულას."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"განიბლოკა სახით. დააჭირეთ გასახსნელად."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ამოცნობილია სახით. დააჭირეთ გასახსნელად."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-ის ტრანსლაცია"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"აუდიოს გამოსასვლელის შეცვლა"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"უცნობი"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"დდდ, თთთ თ"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"სთ:წთ"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"სთ:წთ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 4f5b7e0..d47c26d 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Құрылғы құлыпталды."</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Бетті сканерлеу"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Жіберу"</string>
-    <string name="phone_label" msgid="5715229948920451352">"телефонды ашу"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"ашық дауыс көмекшісі"</string>
-    <string name="camera_label" msgid="8253821920931143699">"камераны ашу"</string>
     <string name="cancel" msgid="1089011503403416730">"Бас тарту"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Растау"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Қайталап көріңіз"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Қайта түртіңіз."</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Ашу үшін жоғары қарай сырғытыңыз."</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Ашу үшін құлыпты ашу белгішесін басыңыз."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Бет үлгісі арқылы ашылды. Ашу үшін құлыпты ашу белгішесін басыңыз."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Бетпен ашылды. Ашу үшін басыңыз."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Бет танылды. Ашу үшін басыңыз."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> қолданбасын тарату"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Аудио шығысын өзгерту"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Белгісіз"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"d MMM EEEE"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index a921cb9..48fedd2 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"បានចាក់សោ​ឧបករណ៍"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"ការ​ស្កេន​មុខ"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ផ្ញើ"</string>
-    <string name="phone_label" msgid="5715229948920451352">"បើក​ទូរស័ព្ទ"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"បើកជំនួយសំឡេង"</string>
-    <string name="camera_label" msgid="8253821920931143699">"បើក​ម៉ាស៊ីន​ថត"</string>
     <string name="cancel" msgid="1089011503403416730">"បោះបង់"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"បញ្ជាក់"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ព្យាយាម​ម្ដង​ទៀត"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"ចុច​ម្ដងទៀត"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"អូសឡើងលើ​ដើម្បីបើក"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ចុចរូបដោះសោ ដើម្បីបើក"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"បានដោះសោ​ដោយប្រើមុខ។ សូមចុចរូបដោះសោ ដើម្បីបើក។"</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"បានដោះសោដោយប្រើមុខ។ សូមចុច ដើម្បីបើក។"</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"បានស្គាល់មុខ។ សូមចុច ដើម្បីបើក។"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"ការផ្សាយ <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ប្ដូរឧបករណ៍បញ្ចេញសំឡេង"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"មិនស្គាល់"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 46fa9a4..55afb91 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"ಸಾಧನ ಲಾಕ್ ಆಗಿದೆ"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"ಮುಖವನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ಕಳುಹಿಸಿ"</string>
-    <string name="phone_label" msgid="5715229948920451352">"ಫೋನ್ ತೆರೆಯಿರಿ"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"ಧ್ವನಿ ಸಹಾಯಕವನ್ನು ತೆರೆ"</string>
-    <string name="camera_label" msgid="8253821920931143699">"ಕ್ಯಾಮರಾ ತೆರೆಯಿರಿ"</string>
     <string name="cancel" msgid="1089011503403416730">"ರದ್ದುಮಾಡಿ"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"ದೃಢೀಕರಿಸಿ"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"ಪುನಃ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"ತೆರೆಯಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ತೆರೆಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ತೆರೆಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ತೆರೆಯಲು ಒತ್ತಿ."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ. ತೆರೆಯಲು ಒತ್ತಿ."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ಅನ್ನು ಪ್ರಸಾರ ಮಾಡಿ"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ಔಟ್‌ಪುಟ್ ಅನ್ನು ಬದಲಾಯಿಸಿ"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ಅಪರಿಚಿತ"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 47c2646..32d345f 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"기기 잠김"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"얼굴 스캔 중"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"보내기"</string>
-    <string name="phone_label" msgid="5715229948920451352">"휴대전화 열기"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"음성 지원 열기"</string>
-    <string name="camera_label" msgid="8253821920931143699">"카메라 열기"</string>
     <string name="cancel" msgid="1089011503403416730">"취소"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"확인"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"다시 시도하세요."</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"다시 탭하세요."</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"위로 스와이프하여 열기"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"기기를 열려면 잠금 해제 아이콘을 누르세요."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"얼굴 인식으로 잠금 해제되었습니다. 기기를 열려면 잠금 해제 아이콘을 누르세요."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"얼굴 인식으로 잠금 해제되었습니다. 열려면 누르세요."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"얼굴이 인식되었습니다. 열려면 누르세요."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> 방송"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"출력 변경"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"알 수 없음"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"MMM d일 EEE"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 437708a..a967058 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -50,7 +50,7 @@
     <string name="usb_debugging_title" msgid="8274884945238642726">"USB аркылуу жөндөөгө уруксат берилсинби?"</string>
     <string name="usb_debugging_message" msgid="5794616114463921773">"Компүтердин RSA ачкычынын контролдук суммасы:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="4003121804294739548">"Бул компүтерден дайыма уруксат берилсин"</string>
-    <string name="usb_debugging_allow" msgid="1722643858015321328">"Уруксат берүү"</string>
+    <string name="usb_debugging_allow" msgid="1722643858015321328">"Ооба"</string>
     <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB мүчүлүштүктөрүн оңдоого уруксат жок"</string>
     <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Учурда бул аккаунтта USB аркылуу мүчүлүштүктөрдү аныктоо функциясын иштетүүгө болбойт. Негизги колдонуучунун аккаунтуна кириңиз."</string>
     <string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Тутум тилин <xliff:g id="LANGUAGE">%1$s</xliff:g> тилине өзгөртөсүзбү?"</string>
@@ -60,7 +60,7 @@
     <string name="wifi_debugging_title" msgid="7300007687492186076">"Ушул тармакта мүчүлүштүктөрдү Wi-Fi аркылуу аныктоого уруксат бересизби?"</string>
     <string name="wifi_debugging_message" msgid="5461204211731802995">"Тармактын аталышы (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi дареги (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
     <string name="wifi_debugging_always" msgid="2968383799517975155">"Бул тармакта ар дайым уруксат берилсин"</string>
-    <string name="wifi_debugging_allow" msgid="4573224609684957886">"Уруксат берүү"</string>
+    <string name="wifi_debugging_allow" msgid="4573224609684957886">"Ооба"</string>
     <string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Мүчүлүштүктөрдү Wi-Fi аркылуу оңдоого уруксат берилген жок"</string>
     <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Учурда бул түзмөккө кирген колдонуучу мүчүлүштүктөрдү Wi-Fi аркылуу оңдоо функциясын күйгүзө албайт. Бул функцияны колдонуу үчүн негизги колдонуучунун аккаунтуна которулуңуз."</string>
     <string name="usb_contaminant_title" msgid="894052515034594113">"USB порту өчүрүлдү"</string>
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Түзмөк кулпуланды"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Жүз скандалууда"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Жөнөтүү"</string>
-    <string name="phone_label" msgid="5715229948920451352">"телефонду ачуу"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"үн жардамчысысын ачуу"</string>
-    <string name="camera_label" msgid="8253821920931143699">"камераны ачуу"</string>
     <string name="cancel" msgid="1089011503403416730">"Жок"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Ырастоо"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Кайталоо"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Кайра таптап коюңуз"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Ачуу үчүн өйдө сүрүңүз"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Кулпуну ачуу сүрөтчөсүн басыңыз"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Кулпуну жүзүңүз менен ачтыңыз. Эми кулпуну ачуу сүрөтчөсүн басыңыз."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Кулпуну жүзүңүз менен ачтыңыз. Ачуу үчүн басыңыз."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Жүз таанылды. Ачуу үчүн басыңыз."</string>
@@ -470,7 +469,7 @@
     <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Жаңырууда"</string>
     <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Колдонуу үчүн кулпусун ачыңыз"</string>
     <string name="wallet_error_generic" msgid="257704570182963611">"Кыйытмаларды алууда ката кетти. Бир аздан кийин кайталап көрүңүз."</string>
-    <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Кулпуланган экран жөндөөлөрү"</string>
+    <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Экранды кулпулоо параметрлери"</string>
     <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR кодун скандоо"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Жумуш профили"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Учак режими"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> колдонмосунда кабарлоо"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Аудионун чыгуусун өзгөртүү"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Белгисиз"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 8e84afe..d86198e 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"ອຸປະກອນຖືກລັອກໄວ້"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"ການສະແກນໜ້າ"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ສົ່ງ"</string>
-    <string name="phone_label" msgid="5715229948920451352">"​ເປີດ​​ແປ້ນ​ໂທ​ລະ​ສັບ"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"ຊ່ວ​ເຫຼືອ​ເປີດ​ສຽງ"</string>
-    <string name="camera_label" msgid="8253821920931143699">"ເປີດ​ກ້ອງ"</string>
     <string name="cancel" msgid="1089011503403416730">"ຍົກເລີກ"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"ຢືນຢັນ"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ລອງໃໝ່"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"ແຕະອີກເທື່ອໜຶ່ງ"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"ປັດຂຶ້ນເພື່ອເປີດ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ກົດໄອຄອນປົດລັອກເພື່ອເປີດ"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ປົດລັອກດ້ວຍໜ້າແລ້ວ. ກົດໄອຄອນປົດລັອກເພື່ອເປີດ."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ປົດລັອກດ້ວຍໜ້າແລ້ວ. ກົດເພື່ອເປີດ."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ຈຳແນກໜ້າໄດ້ແລ້ວ. ກົດເພື່ອເປີດ."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"ອອກອາກາດ <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ປ່ຽນເອົ້າພຸດ"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ບໍ່ຮູ້ຈັກ"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"ຊມ:ນທ"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ຊມ:ນທ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 3722176..56bfb2c 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Įrenginys užrakintas"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Nuskaitomas veidas"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Siųsti"</string>
-    <string name="phone_label" msgid="5715229948920451352">"atidaryti telefoną"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"atidaryti „Voice Assist“"</string>
-    <string name="camera_label" msgid="8253821920931143699">"atidaryti fotoaparatą"</string>
     <string name="cancel" msgid="1089011503403416730">"Atšaukti"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Patvirtinkite"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Bandyti dar kartą"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Palieskite dar kartą"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Perbraukite aukštyn, kad atidarytumėte"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Paspauskite atrakinimo piktogramą, kad atidarytumėte"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Atrakinta pagal veidą. Pasp. atr. pikt., kad atidarytumėte."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Atrakinta pagal veidą. Paspauskite, kad atidarytumėte."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Veidas atpažintas. Paspauskite, kad atidarytumėte."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transliuoti „<xliff:g id="SWITCHAPP">%1$s</xliff:g>“"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Keisti išvestį"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nežinoma"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index a1a2424..65e7c5d 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Ierīce ir bloķēta"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Sejas skenēšana"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Sūtīt"</string>
-    <string name="phone_label" msgid="5715229948920451352">"atvērt tālruni"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"atvērt balss palīgu"</string>
-    <string name="camera_label" msgid="8253821920931143699">"atvērt kameru"</string>
     <string name="cancel" msgid="1089011503403416730">"Atcelt"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Apstiprināt"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Mēģināt vēlreiz"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Pieskarieties vēlreiz"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Velciet augšup, lai atvērtu"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Lai atvērtu, nospiediet atbloķēšanas ikonu"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Atbloķēta ar seju. Atvērt: nospiediet atbloķēšanas ikonu."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ierīce atbloķēta ar seju. Nospiediet, lai atvērtu."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Seja atpazīta. Nospiediet, lai atvērtu."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Lietotnes <xliff:g id="SWITCHAPP">%1$s</xliff:g> apraide"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Izvades maiņa"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nezināms"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"hh:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 5c1bf4a..85f9cd5 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Уредот е заклучен"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Скенирање лице"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Испрати"</string>
-    <string name="phone_label" msgid="5715229948920451352">"отвори телефон"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"отвори гласовна помош"</string>
-    <string name="camera_label" msgid="8253821920931143699">"отвори камера"</string>
     <string name="cancel" msgid="1089011503403416730">"Откажи"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Потврди"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Обиди се повторно"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Допрете повторно"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Повлечете за да отворите"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Притиснете ја иконата за отклучување за да отворите"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Отклучено со лик. Притиснете ја иконата за отклучување за да отворите."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Отклучено со лик. Притиснете за да отворите."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лицето е препознаено. Притиснете за да отворите."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Емитување на <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Променете излез"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Непознато"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index e951978..49a8075 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"ഉപകരണം ലോക്ക് ചെയ്തു"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"മുഖം സ്കാൻ ചെയ്യുന്നു"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"അയയ്ക്കുക"</string>
-    <string name="phone_label" msgid="5715229948920451352">"ഫോൺ തുറക്കുക"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"വോയ്‌സ് അസിസ്റ്റ് തുറക്കുക"</string>
-    <string name="camera_label" msgid="8253821920931143699">"ക്യാമറ തുറക്കുക"</string>
     <string name="cancel" msgid="1089011503403416730">"റദ്ദാക്കുക"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"സ്ഥിരീകരിക്കുക"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"വീണ്ടും ശ്രമിക്കുക"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"വീണ്ടും ടാപ്പ് ചെയ്യുക"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"തുറക്കാൻ മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"തുറക്കാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്‌തു. തുറക്കാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്‌തു. തുറക്കാൻ അമർത്തുക."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"മുഖം തിരിച്ചറിഞ്ഞു. തുറക്കാൻ അമർത്തുക."</string>
@@ -406,7 +405,7 @@
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"ഈ ഉപകരണം <xliff:g id="VPN_APP_0">%1$s</xliff:g>, <xliff:g id="VPN_APP_1">%2$s</xliff:g> എന്നിവയിലൂടെ ഇന്റർനെറ്റിലേക്ക് കണക്‌റ്റ് ചെയ്‌തിരിക്കുന്നു. ഇമെയിലുകളും ബ്രൗസിംഗ് ഡാറ്റയും ഉൾപ്പെടെയുള്ള നിങ്ങളുടെ നെറ്റ്‌വർക്ക് ആക്‌റ്റിവിറ്റി നിങ്ങളുടെ ഐടി അഡ്‌മിന് ദൃശ്യമാകും."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"നിങ്ങളുടെ ഔദ്യോഗിക ആപ്പുകൾ <xliff:g id="VPN_APP">%1$s</xliff:g> വഴി ഇന്റർനെറ്റിലേക്ക് കണക്‌റ്റ് ചെയ്‌തിരിക്കുന്നു. ഇമെയിലുകളും ബ്രൗസിംഗ് ഡാറ്റയും ഉൾപ്പെടെയുള്ള, ഔദ്യോഗിക ആപ്പുകളിലെ നിങ്ങളുടെ നെറ്റ്‌വർക്ക് ആക്‌റ്റിവിറ്റി നിങ്ങളുടെ ഐടി അഡ്‌മിനും VPN ദാതാവിനും ദൃശ്യമാകും."</string>
     <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"നിങ്ങളുടെ വ്യക്തിപര ആപ്പുകൾ <xliff:g id="VPN_APP">%1$s</xliff:g> വഴി ഇന്റർനെറ്റിലേക്ക് കണക്‌റ്റ് ചെയ്‌തിരിക്കുന്നു. ഇമെയിലുകളും ബ്രൗസിംഗ് ഡാറ്റയും ഉൾപ്പെടെയുള്ള നിങ്ങളുടെ നെറ്റ്‌വർക്ക് ആക്‌റ്റിവിറ്റി നിങ്ങളുടെ VPN ദാതാവിന് ദൃശ്യമാകും."</string>
-    <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" 5"</string>
+    <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
     <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN ക്രമീകരണം തുറക്കുക"</string>
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ഈ ഉപകരണം മാനേജ് ചെയ്യുന്നത് നിങ്ങളുടെ രക്ഷിതാവാണ്. നിങ്ങൾ ഉപയോഗിക്കുന്ന ആപ്പുകൾ, സ്‌ക്രീൻ സമയം, ലൊക്കേഷൻ എന്നിവ പോലുള്ള വിവരങ്ങൾ നിങ്ങളുടെ രക്ഷിതാവിന് കാണാനും നിയന്ത്രിക്കാനുമാകും."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ബ്രോഡ്‌കാസ്റ്റ് ചെയ്യുക"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ഔട്ട്പുട്ട് മാറ്റുക"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"അജ്ഞാതം"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index f9ca17e..c9bd0bf 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Төхөөрөмжийг түгжсэн"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Скан хийх нүүр царай"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Илгээх"</string>
-    <string name="phone_label" msgid="5715229948920451352">"утас нээх"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"дуут туслахыг нээнэ"</string>
-    <string name="camera_label" msgid="8253821920931143699">"камер нээх"</string>
     <string name="cancel" msgid="1089011503403416730">"Цуцлах"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Баталгаажуулах"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Дахин оролдох"</string>
@@ -173,7 +170,7 @@
     <string name="cell_data_off" msgid="4886198950247099526">"Идэвхгүй"</string>
     <string name="accessibility_airplane_mode" msgid="1899529214045998505">"Нислэгийн горим"</string>
     <string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN асаалттай байна."</string>
-    <string name="accessibility_battery_level" msgid="5143715405241138822">"Батерей <xliff:g id="NUMBER">%d</xliff:g> хувьтай."</string>
+    <string name="accessibility_battery_level" msgid="5143715405241138822">"Батарей <xliff:g id="NUMBER">%d</xliff:g> хувьтай."</string>
     <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Батарей <xliff:g id="PERCENTAGE">%1$s</xliff:g> хувьтай байна. Таны хэрэглээнд тулгуурлан ойролцоогоор <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string>
     <string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Батарейг цэнэглэж байна, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_overflow_action" msgid="8555835828182509104">"Бүх мэдэгдлийг харах"</string>
@@ -214,7 +211,7 @@
     <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Бүү саад бол"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Хослуулсан төхөөрөмж байхгүй"</string>
-    <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> батерей"</string>
+    <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> батарей"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Чихэвч"</string>
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Оролт"</string>
@@ -248,7 +245,7 @@
     <string name="quick_settings_done" msgid="2163641301648855793">"Дууссан"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Хаах"</string>
     <string name="quick_settings_connected" msgid="3873605509184830379">"Холбогдсон"</string>
-    <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Холбогдсон, батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Холбогдсон, батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="2381969772953268809">"Холбогдож байна..."</string>
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Сүлжээний цэг"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Асааж байна…"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Дaхин товшино уу"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Нээхийн тулд дээш шударна уу"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Нээхийн тулд түгжээг тайлах дүрс тэмдэг дээр дараарай"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Царайгаар түгжээг тайлсан. Нээхийн тулд түгжээг тайлах дүрс тэмдэг дээр дараарай."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Царайгаар түгжээг тайлсан. Нээхийн тулд дарна уу."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Царайг таньсан. Нээхийн тулд дарна уу."</string>
@@ -706,7 +705,7 @@
     <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Апп (<xliff:g id="ID_1">%s</xliff:g>) Бүү саад бол горимыг асаасан."</string>
     <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Автомат дүрэм эсвэл апп Бүү саад бол горимыг асаасан."</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Цаана ажиллаж буй апп"</string>
-    <string name="running_foreground_services_msg" msgid="3009459259222695385">"Батерей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string>
+    <string name="running_foreground_services_msg" msgid="3009459259222695385">"Батарей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Мобайл датаг унтраах уу?"</string>
     <string name="mobile_data_disable_message" msgid="8604966027899770415">"Та <xliff:g id="CARRIER">%s</xliff:g>-р дата эсвэл интернэтэд хандах боломжгүй болно. Интернэтэд зөвхөн Wi-Fi-р холбогдох боломжтой болно."</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"таны оператор компани"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-г нэвтрүүлэх"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Гаралтыг өөрчлөх"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Тодорхойгүй"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"MMM d EEE"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 19694db..5922126 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"डिव्हाइस लॉक केले"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"चेहरा स्कॅन करत आहे"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"पाठवा"</string>
-    <string name="phone_label" msgid="5715229948920451352">"फोन उघडा"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"व्हॉइस सहाय्य उघडा"</string>
-    <string name="camera_label" msgid="8253821920931143699">"कॅमेरा उघडा"</string>
     <string name="cancel" msgid="1089011503403416730">"रद्द करा"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"कंफर्म करा"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"पुन्हा प्रयत्न करा"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"पुन्हा टॅप करा"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"उघडण्यासाठी वर स्वाइप करा"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"उघडण्यासाठी अनलॉक करा आयकन दाबा"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"चेहऱ्याने अनलॉक केले. उघडण्यासाठी अनलॉक करा आयकन दाबा."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"चेहऱ्याने अनलॉक केले आहे. उघडण्यासाठी दाबा."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"चेहरा ओळखला आहे. उघडण्यासाठी दाबा."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> चे प्रसारण करा"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"आउटपूट बदला"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"अज्ञात"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index e85b3a0..ac6f3de 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Peranti dikunci"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Mengimbas wajah"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Hantar"</string>
-    <string name="phone_label" msgid="5715229948920451352">"buka telefon"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"buka bantuan suara"</string>
-    <string name="camera_label" msgid="8253821920931143699">"buka kamera"</string>
     <string name="cancel" msgid="1089011503403416730">"Batal"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Sahkan"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Cuba lagi"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Ketik sekali lagi"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Leret ke atas untuk buka"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Tekan ikon buka kunci untuk buka"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Dibuka kunci dengan wajah. Tekan ikon buka kunci untuk buka."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Dibuka kunci dengan wajah. Tekan untuk membuka."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Wajah dicam. Tekan untuk membuka."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Siarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Tukar output"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Tidak diketahui"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 81f8189..09de745 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"စက်ပစ္စည်းကို လော့ခ်ချထားသည်"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"မျက်နှာ စကင်ဖတ်နေသည်"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ပို့ရန်"</string>
-    <string name="phone_label" msgid="5715229948920451352">"ဖုန်းကို ဖွင့်ရန်"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"အသံ အကူအညီအား ဖွင့်ရန်"</string>
-    <string name="camera_label" msgid="8253821920931143699">"ကင်မရာ ဖွင့်ရန်"</string>
     <string name="cancel" msgid="1089011503403416730">"မလုပ်တော့"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"အတည်ပြုပါ"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ထပ်စမ်းကြည့်ရန်"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"ထပ်တို့ပါ"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"ဖွင့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ဖွင့်ရန် လော့ခ်ဖွင့်သင်္ကေတကို နှိပ်ပါ"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"မျက်နှာပြ လော့ခ်ဖွင့်ထားသည်။ လော့ခ်ဖွင့်သင်္ကေတ နှိပ်၍ဝင်ပါ။"</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"မျက်နှာဖြင့် ဖွင့်ထားသည်။ ဖွင့်ရန် နှိပ်ပါ။"</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"မျက်နှာ မှတ်မိသည်။ ဖွင့်ရန် နှိပ်ပါ။"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ထုတ်လွှင့်ခြင်း"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"အထွက်ကို ပြောင်းခြင်း"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"မသိ"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE၊ MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index d6ce3fe..8b435c2 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Enheten er låst"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skanning av ansikt"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
-    <string name="phone_label" msgid="5715229948920451352">"åpne telefonen"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"åpne talehjelp"</string>
-    <string name="camera_label" msgid="8253821920931143699">"åpne kamera"</string>
     <string name="cancel" msgid="1089011503403416730">"Avbryt"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bekreft"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Prøv på nytt"</string>
@@ -136,7 +133,7 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Ansiktet er autentisert"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bekreftet"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Trykk på Bekreft for å fullføre"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Låst opp med ansiktet. Trykk på lås opp-ikon for å fortsette"</string>
+    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Låst opp med ansiktet. Trykk på lås opp-ikonet for å fortsette"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Låst opp med ansiktet. Trykk for å fortsette."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ansiktet er gjenkjent. Trykk for å fortsette."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansiktet er gjenkjent. Trykk på lås opp-ikon for å fortsette"</string>
@@ -250,7 +247,7 @@
     <string name="quick_settings_connected" msgid="3873605509184830379">"Tilkoblet"</string>
     <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Tilkoblet, batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="2381969772953268809">"Kobler til …"</string>
-    <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Wi-Fi-sone"</string>
+    <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Wifi-sone"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Slår på …"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Datasparing er på"</string>
     <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# enhet}other{# enheter}}"</string>
@@ -310,7 +307,9 @@
     <string name="tap_again" msgid="1315420114387908655">"Trykk igjen"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Sveip opp for å åpne"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Trykk på lås opp-ikonet for å åpne"</string>
-    <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Låst opp med ansiktet. Trykk på lås opp-ikon for å fortsette"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
+    <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Låst opp med ansiktet. Trykk på lås opp-ikonet for å fortsette"</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Låst opp med ansiktet. Trykk for å åpne."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ansiktet er gjenkjent. Trykk for å åpne."</string>
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Ansiktet er gjenkjent. Trykk på lås opp-ikon for å fortsette"</string>
@@ -477,7 +476,7 @@
     <string name="zen_alarm_warning" msgid="7844303238486849503">"Du hører ikke neste innstilte alarm <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template" msgid="2234991538018805736">"kl. <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string>
-    <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Wi-Fi-sone"</string>
+    <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Wifi-sone"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Work-profil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Gøy for noen – ikke for alle"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Med System UI Tuner har du flere måter å justere og tilpasse Android-brukergrensesnittet på. Disse eksperimentelle funksjonene kan endres, avbrytes eller fjernes i fremtidige utgivelser. Fortsett med forbehold."</string>
@@ -912,7 +911,7 @@
     <string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi kobles ikke til automatisk inntil videre"</string>
     <string name="see_all_networks" msgid="3773666844913168122">"Se alle"</string>
     <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"For å bytte nettverk, koble fra Ethernet"</string>
-    <string name="wifi_scan_notify_message" msgid="3753839537448621794">"For å forbedre brukeropplevelsen på enheten kan apper og tjenester søke etter Wi-Fi-nettverk når som helst – også når Wi-Fi er slått av. Du kan endre dette i innstillingene for Wi-Fi-skanning. "<annotation id="link">"Endre"</annotation></string>
+    <string name="wifi_scan_notify_message" msgid="3753839537448621794">"For å forbedre brukeropplevelsen på enheten kan apper og tjenester søke etter Wi-Fi-nettverk når som helst – også når Wi-Fi er slått av. Du kan endre dette i innstillingene for wifi-skanning. "<annotation id="link">"Endre"</annotation></string>
     <string name="turn_off_airplane_mode" msgid="8425587763226548579">"Slå av flymodus"</string>
     <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> vil legge til denne brikken i Hurtiginnstillinger"</string>
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Legg til brikke"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Kringkast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Endre utgang"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ukjent"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d. MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"t:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"tt:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 409db0b..05bb286 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"यन्त्र लक गरिएको छ"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"अनुहार स्क्यान गर्दै"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"पठाउनुहोस्"</string>
-    <string name="phone_label" msgid="5715229948920451352">"फोन खोल्नुहोस्"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"आवाज सहायता खोल्नुहोस्"</string>
-    <string name="camera_label" msgid="8253821920931143699">"क्यामेरा खोल्नुहोस्"</string>
     <string name="cancel" msgid="1089011503403416730">"रद्द गर्नुहोस्"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"पुष्टि गर्नुहोस्"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"फेरि प्रयास गर्नुहोस्"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"फेरि ट्याप गर्नुहोस्"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"खोल्न माथितिर स्वाइप गर्नुहोस्"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"खोल्न अनलक आइकनमा थिच्नुहोस्"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"अनुहार प्रयोग गरी अनलक गरियो। खोल्न अनलक आइकनमा थिच्नुहोस्।"</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"अनुहार प्रयोग गरी अनलक गरियो। डिभाइस खोल्न थिच्नुहोस्।"</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"अनुहार पहिचान गरियो। डिभाइस खोल्न थिच्नुहोस्।"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ब्रोडकास्ट गर्नुहोस्"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"आउटपुट परिवर्तन गर्नुहोस्"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"अज्ञात"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 9501ddf..2c91600 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Apparaat vergrendeld"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Gezicht scannen"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Verzenden"</string>
-    <string name="phone_label" msgid="5715229948920451352">"telefoon openen"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"spraakassistent openen"</string>
-    <string name="camera_label" msgid="8253821920931143699">"camera openen"</string>
     <string name="cancel" msgid="1089011503403416730">"Annuleren"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bevestigen"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Opnieuw proberen"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Tik nog een keer"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe omhoog om te openen"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Druk op het ontgrendelicoon om te openen"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ontgrendeld via gezicht. Druk op het ontgrendelicoon."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ontgrendeld via gezicht. Druk om te openen."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Gezicht herkend. Druk om te openen."</string>
@@ -374,7 +373,7 @@
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> is eigenaar van dit apparaat en kan het netwerkverkeer bijhouden"</string>
     <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Dit apparaat wordt geleverd door <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Dit apparaat is eigendom van je organisatie en heeft verbinding met internet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
-    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> en heeft verbinding met internet via <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> en heeft internetverbinding via <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Dit apparaat is eigendom van je organisatie"</string>
     <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Dit apparaat is eigendom van je organisatie en heeft verbinding met internet via VPN\'s"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> uitzenden"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Uitvoer wijzigen"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Onbekend"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d mmm"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"u:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 681c2bb..f30f7d1 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -79,8 +79,8 @@
     <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"ସ୍କ୍ରିନସଟକୁ ସେଭ୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ଆପ୍‍ କିମ୍ବା ସଂସ୍ଥା ଦ୍ୱାରା ସ୍କ୍ରୀନଶଟ୍‍ ନେବାକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ"</string>
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ସ୍କ୍ରିନସଟଗୁଡ଼ିକ ନେବା ଆପଣଙ୍କ IT ଆଡମିନଙ୍କ ଦ୍ୱାରା ବ୍ଲକ କରାଯାଇଛି"</string>
-    <string name="screenshot_edit_label" msgid="8754981973544133050">"ଏଡିଟ୍ କରନ୍ତୁ"</string>
-    <string name="screenshot_edit_description" msgid="3333092254706788906">"ସ୍କ୍ରିନସଟ୍ ଏଡିଟ୍ କରନ୍ତୁ"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"ଏଡିଟ କରନ୍ତୁ"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"ସ୍କ୍ରିନସଟ୍ ଏଡିଟ କରନ୍ତୁ"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"ସ୍କ୍ରିନସଟ ସେୟାର କରନ୍ତୁ"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"ଅଧିକ କ୍ୟାପଚର୍ କରନ୍ତୁ"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ସ୍କ୍ରିନସଟ୍ ଖାରଜ କରନ୍ତୁ"</string>
@@ -124,13 +124,10 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"ଡିଭାଇସ୍ ଲକ୍ ହୋଇଯାଇଛି"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"ଫେସ୍ ସ୍କାନିଙ୍ଗ କରାଯାଉଛି"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ପଠାନ୍ତୁ"</string>
-    <string name="phone_label" msgid="5715229948920451352">"ଫୋନ୍‌ ଖୋଲନ୍ତୁ"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"ଭଏସ୍‍ ସହାୟକ ଖୋଲନ୍ତୁ"</string>
-    <string name="camera_label" msgid="8253821920931143699">"କ୍ୟାମେରା ଖୋଲନ୍ତୁ"</string>
-    <string name="cancel" msgid="1089011503403416730">"ବାତିଲ୍ କରନ୍ତୁ"</string>
+    <string name="cancel" msgid="1089011503403416730">"ବାତିଲ କରନ୍ତୁ"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"ନିଶ୍ଚିତ କରନ୍ତୁ"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
-    <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"ପ୍ରାମାଣିକତା ବାତିଲ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
+    <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"ପ୍ରାମାଣିକତା ବାତିଲ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
     <string name="biometric_dialog_face_icon_description_idle" msgid="4351777022315116816">"ଦୟାକରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="3401633342366146535">"ଆପଣଙ୍କର ମୁହଁକୁ ପ୍ରମାଣ କରୁଛି"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ମୁହଁ ପ୍ରାମାଣିକତା ହୋଇଛି"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"ପୁଣି ଟାପ୍ କରନ୍ତୁ"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"ଖୋଲିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ଖୋଲିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଖୋଲିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ।"</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଖୋଲିବାକୁ ଦବାନ୍ତୁ।"</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି। ଖୋଲିବାକୁ ଦବାନ୍ତୁ।"</string>
@@ -622,7 +621,7 @@
     <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"ଟାଇଲ୍‍ ପୁଣି ସଜାଇବାକୁ ଦାବିଧରି ଟାଣନ୍ତୁ"</string>
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"ବାହାର କରିବାକୁ ଏଠାକୁ ଡ୍ରାଗ୍‍ କରନ୍ତୁ"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"ଆପଣଙ୍କର ଅତିକମ୍‌ରେ <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>ଟି ଟାଇଲ୍ ଆବଶ୍ୟକ"</string>
-    <string name="qs_edit" msgid="5583565172803472437">"ଏଡିଟ୍‌ କରନ୍ତୁ"</string>
+    <string name="qs_edit" msgid="5583565172803472437">"ଏଡିଟ କରନ୍ତୁ"</string>
     <string name="tuner_time" msgid="2450785840990529997">"ସମୟ"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"ଘଣ୍ଟା, ମିନିଟ୍‍ ଏବଂ ସେକେଣ୍ଡ ଦେଖାନ୍ତୁ"</item>
@@ -654,7 +653,7 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ଉପଯୋଗକର୍ତ୍ତା ବାଛନ୍ତୁ"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"କୌଣସି ଇଣ୍ଟରନେଟ୍‌ କନେକ୍ସନ୍ ନାହିଁ"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> ସେଟିଙ୍ଗ ଖୋଲନ୍ତୁ।"</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ସେଟିଙ୍ଗର କ୍ରମ ସଂଶୋଧନ କରନ୍ତୁ।"</string>
+    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ସେଟିଂସର କ୍ରମ ଏଡିଟ କରନ୍ତୁ।"</string>
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ପାୱାର ମେନୁ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ପୃଷ୍ଠା <xliff:g id="ID_1">%1$d</xliff:g> ମୋଟ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ଲକ୍‌ ସ୍କ୍ରୀନ୍‌"</string>
@@ -826,7 +825,7 @@
     <string name="controls_error_generic" msgid="352500456918362905">"ସ୍ଥିତି ଲୋଡ୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
     <string name="controls_error_failed" msgid="960228639198558525">"ତ୍ରୁଟି ହୋଇଛି, ପୁଣି ଚେଷ୍ଟା କର"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ ଯୋଗ କରନ୍ତୁ"</string>
-    <string name="controls_menu_edit" msgid="890623986951347062">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ଏଡିଟ୍ କରନ୍ତୁ"</string>
+    <string name="controls_menu_edit" msgid="890623986951347062">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ଏଡିଟ କରନ୍ତୁ"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"ଆଉଟପୁଟ୍ ଯୋଗ କରନ୍ତୁ"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"ଗୋଷ୍ଠୀ"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1ଟି ଡିଭାଇସ୍ ଚୟନ କରାଯାଇଛି"</string>
@@ -938,7 +937,7 @@
     <string name="clipboard_editor" msgid="2971197550401892843">"କ୍ଲିପବୋର୍ଡ ଏଡିଟର"</string>
     <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"କ୍ଲିପବୋର୍ଡ"</string>
     <string name="clipboard_image_preview" msgid="2156475174343538128">"ଇମେଜ ପ୍ରିଭ୍ୟୁ"</string>
-    <string name="clipboard_edit" msgid="4500155216174011640">"ଏଡିଟ"</string>
+    <string name="clipboard_edit" msgid="4500155216174011640">"ଏଡିଟ କରନ୍ତୁ"</string>
     <string name="add" msgid="81036585205287996">"ଯୋଗ କରନ୍ତୁ"</string>
     <string name="manage_users" msgid="1823875311934643849">"ଉପଯୋଗକର୍ତ୍ତାମାନଙ୍କୁ ପରିଚାଳନା କରନ୍ତୁ"</string>
     <string name="drag_split_not_supported" msgid="4326847447699729722">"ଏହି ବିଜ୍ଞପ୍ତି ସ୍ପ୍ଲିଟସ୍କ୍ରିନକୁ ଡ୍ରାଗ କରିବାକୁ ସମର୍ଥନ କରେ ନାହିଁ।"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରନ୍ତୁ"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ଆଉଟପୁଟ ବଦଳାନ୍ତୁ"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ଅଜଣା"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 0ca2cde..d41e43c 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"ਡੀਵਾਈਸ ਲਾਕ ਹੈ"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"ਚਿਹਰਾ ਸਕੈਨ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ਭੇਜੋ"</string>
-    <string name="phone_label" msgid="5715229948920451352">"ਫ਼ੋਨ ਖੋਲ੍ਹੋ"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"ਅਵਾਜ਼ੀ ਸਹਾਇਕ ਖੋਲ੍ਹੋ"</string>
-    <string name="camera_label" msgid="8253821920931143699">"ਕੈਮਰਾ ਖੋਲ੍ਹੋ"</string>
     <string name="cancel" msgid="1089011503403416730">"ਰੱਦ ਕਰੋ"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"ਤਸਦੀਕ ਕਰੋ"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"ਦੁਬਾਰਾ ਟੈਪ ਕਰੋ"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"ਖੋਲ੍ਹਣ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ਖੋਲ੍ਹਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਖੋਲ੍ਹਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ।"</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਖੋਲ੍ਹਣ ਲਈ ਦਬਾਓ।"</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ। ਖੋਲ੍ਹਣ ਲਈ ਦਬਾਓ।"</string>
@@ -365,7 +364,7 @@
     <string name="notification_section_header_gentle" msgid="6804099527336337197">"ਸ਼ਾਂਤ"</string>
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"ਸੂਚਨਾਵਾਂ"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"ਗੱਲਾਂਬਾਤਾਂ"</string>
-    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ਸਾਰੀਆਂ ਖਾਮੋਸ਼ ਸੂਚਨਾਵਾਂ ਕਲੀਅਰ ਕਰੋ"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ਸਾਰੀਆਂ ਸ਼ਾਂਤ ਸੂਚਨਾਵਾਂ ਕਲੀਅਰ ਕਰੋ"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਰੋਕਿਆ ਗਿਆ"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"ਹੁਣੇ ਸ਼ੁਰੂ ਕਰੋ"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"ਕੋਈ ਸੂਚਨਾਵਾਂ ਨਹੀਂ"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ਦਾ ਪ੍ਰਸਾਰਨ ਕਰੋ"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ਆਊਟਪੁੱਟ ਬਦਲੋ"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ਅਗਿਆਤ"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 0da22d5..36bbbc4 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Urządzenie zablokowane"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skanowanie twarzy"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Wyślij"</string>
-    <string name="phone_label" msgid="5715229948920451352">"otwórz telefon"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"otwórz pomoc głosową"</string>
-    <string name="camera_label" msgid="8253821920931143699">"otwórz aparat"</string>
     <string name="cancel" msgid="1089011503403416730">"Anuluj"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potwierdź"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Spróbuj jeszcze raz"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Kliknij jeszcze raz"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Przesuń w górę, by otworzyć"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Aby otworzyć, kliknij ikonę odblokowywania"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odblokowano skanem twarzy. Aby otworzyć, kliknij ikonę odblokowywania."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Odblokowano rozpoznawaniem twarzy. Naciśnij, by otworzyć."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Twarz rozpoznana. Naciśnij, by otworzyć."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmisja aplikacji <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Zmień dane wyjściowe"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Brak informacji"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index d166901..0cb7420 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Verificando rosto"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
-    <string name="phone_label" msgid="5715229948920451352">"abrir telefone"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"abrir assistência de voz"</string>
-    <string name="camera_label" msgid="8253821920931143699">"abrir câmera"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancelar"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Tentar novamente"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Toque novamente"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Deslize para cima para abrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pressione o ícone de desbloqueio para abrir"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueado pelo rosto. Toque no ícone do cadeado para abrir."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueado pelo rosto. Pressione para abrir."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Rosto reconhecido. Pressione para abrir."</string>
@@ -374,7 +373,7 @@
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"A organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
     <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Este dispositivo é fornecido pela <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Este dispositivo pertence à sua organização e está conectado à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
-    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado à Internet usando o <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado à Internet usando o <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertence à sua organização"</string>
     <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Este dispositivo pertence à sua organização e está conectado à Internet usando VPNs"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Mudar saída"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconhecido"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d de MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 8c53698..9702b97 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"A analisar o rosto…"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
-    <string name="phone_label" msgid="5715229948920451352">"abrir telemóvel"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"abrir assistente de voz"</string>
-    <string name="camera_label" msgid="8253821920931143699">"abrir câmara"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancelar"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Tentar novamente"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Toque novamente"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Deslize rapidamente para cima para abrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Prima o ícone de desbloqueio para abrir"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueio com a face. Prima ícone de desbloqueio p/ abrir."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueado com o rosto. Prima para abrir."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Rosto reconhecido. Prima para abrir."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmita a app <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Altere a saída"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconhecida"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d de MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index d166901..0cb7420 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Verificando rosto"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
-    <string name="phone_label" msgid="5715229948920451352">"abrir telefone"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"abrir assistência de voz"</string>
-    <string name="camera_label" msgid="8253821920931143699">"abrir câmera"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancelar"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Tentar novamente"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Toque novamente"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Deslize para cima para abrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pressione o ícone de desbloqueio para abrir"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueado pelo rosto. Toque no ícone do cadeado para abrir."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueado pelo rosto. Pressione para abrir."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Rosto reconhecido. Pressione para abrir."</string>
@@ -374,7 +373,7 @@
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"A organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
     <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Este dispositivo é fornecido pela <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Este dispositivo pertence à sua organização e está conectado à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
-    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado à Internet usando o <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado à Internet usando o <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertence à sua organização"</string>
     <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Este dispositivo pertence à sua organização e está conectado à Internet usando VPNs"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Mudar saída"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconhecido"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d de MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 88f9963..99d2f06 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Dispozitiv blocat"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanarea chipului"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Trimiteți"</string>
-    <string name="phone_label" msgid="5715229948920451352">"deschideți telefonul"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"deschideți asistentul vocal"</string>
-    <string name="camera_label" msgid="8253821920931143699">"deschideți camera foto"</string>
     <string name="cancel" msgid="1089011503403416730">"Anulați"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmați"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Încercați din nou"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Atingeți din nou"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Glisați în sus pentru a deschide"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Apăsați pictograma de deblocare pentru a deschide"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"S-a deblocat cu ajutorul feței. Apăsați pictograma de deblocare pentru a deschide"</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"S-a deblocat cu ajutorul feței. Apăsați pentru a deschide."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Chipul a fost recunoscut. Apăsați pentru a deschide."</string>
@@ -374,7 +373,7 @@
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> deține acest dispozitiv și poate monitoriza traficul din rețea"</string>
     <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Acest dispozitiv este oferit de <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Acest dispozitiv aparține organizației dvs. și este conectat la internet prin aplicația <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
-    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Acest dispozitiv aparține organizației <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> și este conectat la internet prin aplicația <xliff:g id="VPN_APP">%2$s</xliff:g>."</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Acest dispozitiv aparține organizației <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> și e conectat la internet prin <xliff:g id="VPN_APP">%2$s</xliff:g>."</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Dispozitivul aparține organizației dvs."</string>
     <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Acest dispozitiv aparține organizației <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Acest dispozitiv aparține organizației dvs. și este conectat la internet prin rețele VPN."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Difuzați <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Schimbați rezultatul"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Necunoscută"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EE, z LLL"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index fefdd81..817fdc0 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Устройство заблокировано"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Сканирование лица"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Отправить"</string>
-    <string name="phone_label" msgid="5715229948920451352">"Открыть телефон."</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"включить аудиоподсказки"</string>
-    <string name="camera_label" msgid="8253821920931143699">"Открыть камеру."</string>
     <string name="cancel" msgid="1089011503403416730">"Отмена"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Подтвердить"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Повторить попытку"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Нажмите ещё раз"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Проведите вверх, чтобы открыть"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Нажмите на значок разблокировки."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Сканирование выполнено. Нажмите на значок разблокировки."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Разблокировано сканированием лица. Нажмите, чтобы открыть."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лицо распознано. Нажмите, чтобы открыть."</string>
@@ -374,7 +373,7 @@
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Организация \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" управляет этим устройством и может отслеживать сетевой трафик"</string>
     <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Устройство предоставлено компанией \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\"."</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Это устройство принадлежит вашей организации и подключено к интернету через сервис \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
-    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Это устройство принадлежит организации \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" и подключено к интернету через сервис \"<xliff:g id="VPN_APP">%2$s</xliff:g>\""</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Это устр-во принадлежит организации \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" и подключено к интернету через сервис \"<xliff:g id="VPN_APP">%2$s</xliff:g>\""</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Это устройство принадлежит вашей организации"</string>
     <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Это устройство принадлежит организации \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\""</string>
     <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Это устройство принадлежит вашей организации и подключено к интернету через сети VPN"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Транслировать \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\""</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Транслировать на другое устройство"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Неизвестно"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"d MMM EEEE"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 3c0d839..8c7b85c 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"උපාංගය අගුලු දමා ඇත"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"මුහුණ ස්කෑන් කිරීම"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"යවන්න"</string>
-    <string name="phone_label" msgid="5715229948920451352">"දුරකථනය විවෘත කරන්න"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"විවෘත හඬ සහාය"</string>
-    <string name="camera_label" msgid="8253821920931143699">"කැමරාව විවෘත කරන්න"</string>
     <string name="cancel" msgid="1089011503403416730">"අවලංගු කරන්න"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"තහවුරු කරන්න"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"නැවත උත්සාහ කරන්න"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"නැවත තට්ටු කරන්න"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"විවෘත කිරීමට ස්වයිප් කරන්න"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"විවෘත කිරීමට අගුලු හැරීමේ නිරූපකය ඔබන්න"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"මුහුණ මගින් අගුලු හරින ලදි. විවෘත කිරීමට අගුලු හැරීමේ නිරූපකය ඔබන්න."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"මුහුණ මගින් අගුලු හරින ලදි. විවෘත කිරීමට ඔබන්න."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"මුහුණ හඳුනා ගන්නා ලදි. විවෘත කිරීමට ඔබන්න."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> විකාශනය"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ප්‍රතිදානය වෙනස් කරන්න"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"නොදනී"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index cbd4559..4bdd206 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Zariadenie je uzamknuté"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skenovanie tváre"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Odoslať"</string>
-    <string name="phone_label" msgid="5715229948920451352">"otvoriť telefón"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"otvoriť hlasového asistenta"</string>
-    <string name="camera_label" msgid="8253821920931143699">"spustiť fotoaparát"</string>
     <string name="cancel" msgid="1089011503403416730">"Zrušiť"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdiť"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Skúsiť znova"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Klepnite znova"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Otvorte potiahnutím prstom nahor"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Otvorte klepnutím na ikonu odomknutia"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odomknuté tvárou. Otvorte klepnutím na ikonu odomknutia."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Odomknuté tvárou. Otvorte stlačením."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Tvár bola rozpoznaná. Otvorte stlačením."</string>
@@ -374,7 +373,7 @@
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> vlastní toto zariadenie a môže sledovať sieťovú premávku"</string>
     <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Toto zariadenie poskytuje <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Toto zariadenie patrí vašej organizácii a k internetu je pripojené prostredníctvom aplikácie <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
-    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Toto zariadenie patrí organizácii <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a k internetu je pripojené prostredníctvom aplikácie <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Zariadenie patrí organizácii <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a k internetu je pripojené cez aplikáciu <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Toto zariadenie patrí vašej organizácii"</string>
     <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Toto zariadení patrí organizácii <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Toto zariadenie patrí vašej organizácii a k internetu je pripojené prostredníctvom sietí VPN"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Vysielanie aplikácie <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Zmena výstupu"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Neznáme"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index e723b1b..c1afc12 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Naprava je zaklenjena."</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Optično branje obraza"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošlji"</string>
-    <string name="phone_label" msgid="5715229948920451352">"odpri telefon"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"odpri glasovnega pomočnika"</string>
-    <string name="camera_label" msgid="8253821920931143699">"odpri fotoaparat"</string>
     <string name="cancel" msgid="1089011503403416730">"Prekliči"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potrdite"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Poskusi znova"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Znova se dotaknite možnosti"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Povlecite navzgor, da odprete"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Za odpiranje pritisnite ikono za odklepanje."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odklenjeno z obrazom. Za odpiranje pritisnite ikono za odklepanje."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Odklenjeno z obrazom. Pritisnite za odpiranje."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Obraz je prepoznan. Pritisnite za odpiranje."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Oddajaj aplikacijo <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Sprememba izhoda"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Neznano"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 4b19b36..c3cdf21 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Pajisja është e kyçur"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Po skanon fytyrën"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Dërgo"</string>
-    <string name="phone_label" msgid="5715229948920451352">"hap telefonin"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"hap ndihmën zanore"</string>
-    <string name="camera_label" msgid="8253821920931143699">"hap kamerën"</string>
     <string name="cancel" msgid="1089011503403416730">"Anulo"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Konfirmo"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Provo përsëri"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Trokit sërish"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Rrëshqit lart për ta hapur"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Shtyp ikonën e shkyçjes për ta hapur"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"U shkyç me fytyrë. Shtyp ikonën e shkyçjes për ta hapur."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"U shkyç me fytyrë. Shtyp për ta hapur."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Fytyra u njoh. Shtyp për ta hapur."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmeto <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Ndrysho daljen"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"I panjohur"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 15d31bd..ef5993b 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Уређај је закључан"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Скенирање лица"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Пошаљи"</string>
-    <string name="phone_label" msgid="5715229948920451352">"отвори телефон"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"отвори гласовну помоћ"</string>
-    <string name="camera_label" msgid="8253821920931143699">"отвори камеру"</string>
     <string name="cancel" msgid="1089011503403416730">"Откажи"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Потврди"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Пробај поново"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Додирните поново"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Превуците нагоре да бисте отворили"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Притисните икону откључавања да бисте отворили."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Откључано је лицем. Притисните икону откључавања да бисте отворили."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Откључано је лицем. Притисните да бисте отворили."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лице је препознато. Притисните да бисте отворили."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Емитујте апликацију <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Промените излаз"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Непознато"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"ДДД, д. МММ"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"с:мин"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ч:мин"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index effe9e5..20bc29f 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Enheten är låst"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Registrerar ansikte"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Skicka"</string>
-    <string name="phone_label" msgid="5715229948920451352">"öppna mobilen"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"öppna röstassistenten"</string>
-    <string name="camera_label" msgid="8253821920931143699">"öppna kameran"</string>
     <string name="cancel" msgid="1089011503403416730">"Avbryt"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bekräfta"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Försök igen"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Tryck igen"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Öppna genom att svepa uppåt"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Tryck på ikonen lås upp för att öppna"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Upplåst med ansiktslås. Tryck på ikonen lås upp för att öppna."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Upplåst med ansiktslås. Tryck för att öppna."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ansiktet har identifierats. Tryck för att öppna."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Sänd från <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Byt ljudutgång"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Okänt"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h.mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk.mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 6c8e02f..418b88e 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Kifaa kimefungwa"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Inachanganua uso"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Tuma"</string>
-    <string name="phone_label" msgid="5715229948920451352">"fungua simu"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"fungua mapendekezo ya sauti"</string>
-    <string name="camera_label" msgid="8253821920931143699">"fungua kamera"</string>
     <string name="cancel" msgid="1089011503403416730">"Ghairi"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Thibitisha"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Jaribu tena"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Gusa tena"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Telezesha kidole juu ili ufungue"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Bonyeza aikoni ya kufungua ili ufungue"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Imefunguliwa kwa kutumia uso wako. Bonyeza aikoni ya kufungua ili ufungue."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Imefunguliwa kwa kutumia uso wako. Bonyeza ili ufungue."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Uso umetambuliwa. Bonyeza ili ufungue."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Tangaza kwenye <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Badilisha maudhui"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Haijulikani"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"saa:dk"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:dk"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 36767ea..34cb0cf 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"சாதனம் பூட்டப்பட்டுள்ளது"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"முகத்தை ஸ்கேன் செய்கிறது"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"அனுப்பு"</string>
-    <string name="phone_label" msgid="5715229948920451352">"ஃபோனைத் திற"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"குரல் உதவியைத் திற"</string>
-    <string name="camera_label" msgid="8253821920931143699">"கேமராவைத் திற"</string>
     <string name="cancel" msgid="1089011503403416730">"ரத்துசெய்"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"உறுதிப்படுத்துக"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"மீண்டும் முயல்க"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"மீண்டும் தட்டவும்"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"திறப்பதற்கு மேல் நோக்கி ஸ்வைப் செய்யவும்"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"திறக்க, அன்லாக் ஐகானை அழுத்தவும்"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. திறக்க, அன்லாக் ஐகானை அழுத்துக."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. திறக்க அழுத்தவும்."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"முகம் அங்கீகரிக்கப்பட்டது. திறக்க அழுத்தவும்."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ஆப்ஸை ஒலிபரப்பு"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"அவுட்புட்டை மாற்று"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"தெரியவில்லை"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 4d124f5..720c909 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -50,7 +50,7 @@
     <string name="usb_debugging_title" msgid="8274884945238642726">"USB డీబగ్గింగ్‌ను అనుమతించాలా?"</string>
     <string name="usb_debugging_message" msgid="5794616114463921773">"ఇది కంప్యూటర్ యొక్క RSA కీ వేలిముద్ర:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="4003121804294739548">"ఈ కంప్యూటర్ నుండి ఎల్లప్పుడూ అనుమతించు"</string>
-    <string name="usb_debugging_allow" msgid="1722643858015321328">"అనుమతించు"</string>
+    <string name="usb_debugging_allow" msgid="1722643858015321328">"అనుమతించండి"</string>
     <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB డీబగ్గింగ్‌కి అనుమతి లేదు"</string>
     <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"ఈ పరికరానికి ప్రస్తుతం సైన్ ఇన్ చేసిన వినియోగదారు USB డీబగ్గింగ్ ఆన్ చేయలేరు. ఈ ఫీచర్ ఉపయోగించడానికి, ప్రాథమిక వినియోగదారుకి మారాలి."</string>
     <string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"మీరు సిస్టమ్ భాషను <xliff:g id="LANGUAGE">%1$s</xliff:g> భాషకు మార్చాలనుకుంటున్నారా?"</string>
@@ -60,7 +60,7 @@
     <string name="wifi_debugging_title" msgid="7300007687492186076">"ఈ నెట్‌వర్క్ ద్వారా వైర్‌లెస్ డీబగ్గింగ్‌ను అనుమతించాలా?"</string>
     <string name="wifi_debugging_message" msgid="5461204211731802995">"నెట్‌వర్క్ పేరు (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi అడ్రస్ (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
     <string name="wifi_debugging_always" msgid="2968383799517975155">"ఈ నెట్‌వర్క్ నుండి ఎల్లప్పుడూ అనుమతించు"</string>
-    <string name="wifi_debugging_allow" msgid="4573224609684957886">"అనుమతించు"</string>
+    <string name="wifi_debugging_allow" msgid="4573224609684957886">"అనుమతించండి"</string>
     <string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"వైర్‌లెస్ డీబగ్గింగ్‌కి అనుమతి లేదు"</string>
     <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"ఈ పరికరానికి ప్రస్తుతం సైన్ ఇన్ చేసిన యూజర్, వైర్‌లెస్ డీబగ్గింగ్ ఆన్ చేయలేరు. ఈ ఫీచర్ ఉపయోగించడానికి, ప్రాథమిక యూజర్ కి స్విచ్ అవ్వండి."</string>
     <string name="usb_contaminant_title" msgid="894052515034594113">"USB పోర్ట్‌ నిలిపివేయబడింది"</string>
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"పరికరం లాక్ చేయబడింది"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"ముఖాన్ని స్కాన్ చేస్తోంది"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"పంపు"</string>
-    <string name="phone_label" msgid="5715229948920451352">"ఫోన్‌ను తెరువు"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"వాయిస్ అసిస్టెంట్‌ను తెరువు"</string>
-    <string name="camera_label" msgid="8253821920931143699">"కెమెరాను తెరవండి"</string>
     <string name="cancel" msgid="1089011503403416730">"రద్దు చేయండి"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"నిర్ధారించు"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"మళ్లీ ప్రయత్నించు"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"మళ్లీ ట్యాప్ చేయండి"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"తెరవడానికి, పైకి స్వైప్ చేయండి"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"తెరవడానికి అన్‌లాక్ చిహ్నాన్ని నొక్కండి"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ముఖం ద్వారా అన్‌లాక్ చేయబడింది. తెరవడానికి అన్‌లాక్ చిహ్నాన్ని నొక్కండి."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ముఖం ద్వారా అన్‌లాక్ చేయబడింది. తెరవడానికి నొక్కండి."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ముఖం గుర్తించబడింది. తెరవడానికి నొక్కండి."</string>
@@ -480,7 +479,7 @@
     <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"హాట్‌స్పాట్"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"ఆఫీస్ ప్రొఫైల్‌"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"కొందరికి సరదాగా ఉంటుంది కానీ అందరికీ అలాగే ఉండదు"</string>
-    <string name="tuner_warning" msgid="1861736288458481650">"సిస్టమ్ UI ట్యూనర్ Android వినియోగదారు ఇంటర్‌ఫేస్‌ను మెరుగుపరచడానికి మరియు అనుకూలీకరించడానికి మీకు మరిన్ని మార్గాలను అందిస్తుంది. ఈ ప్రయోగాత్మక లక్షణాలు భవిష్యత్తు విడుదలల్లో మార్పుకు లోనవ్వచ్చు, తాత్కాలికంగా లేదా పూర్తిగా నిలిపివేయవచ్చు. జాగ్రత్తగా కొనసాగండి."</string>
+    <string name="tuner_warning" msgid="1861736288458481650">"సిస్టమ్ UI ట్యూనర్ Android వినియోగదారు ఇంటర్‌ఫేస్‌ను మెరుగుపరచడానికి మరియు అనుకూలంగా మార్చడానికి మీకు మరిన్ని మార్గాలను అందిస్తుంది. ఈ ప్రయోగాత్మక లక్షణాలు భవిష్యత్తు విడుదలల్లో మార్పుకు లోనవ్వచ్చు, తాత్కాలికంగా లేదా పూర్తిగా నిలిపివేయవచ్చు. జాగ్రత్తగా కొనసాగండి."</string>
     <string name="tuner_persistent_warning" msgid="230466285569307806">"ఈ ప్రయోగాత్మక లక్షణాలు భవిష్యత్తు విడుదలల్లో మార్పుకు లోనవ్వచ్చు, తాత్కాలికంగా లేదా పూర్తిగా నిలిపివేయవచ్చు. జాగ్రత్తగా కొనసాగండి."</string>
     <string name="got_it" msgid="477119182261892069">"అర్థమైంది"</string>
     <string name="tuner_toast" msgid="3812684836514766951">"అభినందనలు! సెట్టింగ్‌లకు సిస్టమ్ UI ట్యూనర్ జోడించబడింది"</string>
@@ -715,7 +714,7 @@
     <string name="slice_permission_text_1" msgid="6675965177075443714">"- ఇది <xliff:g id="APP">%1$s</xliff:g> నుండి సమాచారాన్ని చదువుతుంది"</string>
     <string name="slice_permission_text_2" msgid="6758906940360746983">"- ఇది <xliff:g id="APP">%1$s</xliff:g> లోపల చర్యలు తీసుకుంటుంది"</string>
     <string name="slice_permission_checkbox" msgid="4242888137592298523">"ఏ యాప్ నుండి అయినా స్లైస్‌లను చూపించడానికి <xliff:g id="APP">%1$s</xliff:g>ని అనుమతించండి"</string>
-    <string name="slice_permission_allow" msgid="6340449521277951123">"అనుమతించు"</string>
+    <string name="slice_permission_allow" msgid="6340449521277951123">"అనుమతించండి"</string>
     <string name="slice_permission_deny" msgid="6870256451658176895">"తిరస్కరించు"</string>
     <string name="auto_saver_title" msgid="6873691178754086596">"బ్యాటరీ సేవర్‌ని షెడ్యూల్ చేయడానికి నొక్కండి"</string>
     <string name="auto_saver_text" msgid="3214960308353838764">"బ్యాటరీ ఛార్జింగ్ పూర్తిగా అయిపోతున్న తరుణంలో ఆన్ చేస్తుంది"</string>
@@ -750,7 +749,7 @@
     <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ఫుల్ స్క్రీన్‌ను మ్యాగ్నిఫై చేయండి"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"స్క్రీన్‌లో భాగాన్ని మాగ్నిఫై చేయండి"</string>
     <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"స్విచ్ చేయి"</string>
-    <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"యాక్సెసిబిలిటీ ఫీచర్‌లను తెరవడానికి ట్యాప్ చేయండి. సెట్టింగ్‌లలో ఈ బటన్‌ను అనుకూలీకరించండి లేదా రీప్లేస్ చేయండి.\n\n"<annotation id="link">"వీక్షణ సెట్టింగ్‌లు"</annotation></string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"యాక్సెసిబిలిటీ ఫీచర్‌లను తెరవడానికి ట్యాప్ చేయండి. సెట్టింగ్‌లలో ఈ బటన్‌ను అనుకూలంగా మార్చండి లేదా రీప్లేస్ చేయండి.\n\n"<annotation id="link">"వీక్షణ సెట్టింగ్‌లు"</annotation></string>
     <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"తాత్కాలికంగా దానిని దాచడానికి బటన్‌ను చివరకు తరలించండి"</string>
     <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"ఎగువ ఎడమ వైపునకు తరలించు"</string>
     <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"ఎగువ కుడి వైపునకు తరలించు"</string>
@@ -821,7 +820,7 @@
     <string name="controls_error_timeout" msgid="794197289772728958">"ఇన్‌యాక్టివ్, యాప్ చెక్ చేయండి"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"కనుగొనబడలేదు"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"కంట్రోల్ అందుబాటులో లేదు"</string>
-    <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g>ను యాక్సెస్ చేయడం సాధ్యపడలేదు. <xliff:g id="APPLICATION">%2$s</xliff:g> యాప్‌ను తనిఖీ చేసి, కంట్రోల్ ఇప్పటికీ అందుబాటులో ఉందని, యాప్ సెట్టింగ్‌లు మారలేదని నిర్ధారించుకోండి."</string>
+    <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g>ను యాక్సెస్ చేయడం సాధ్యపడలేదు. <xliff:g id="APPLICATION">%2$s</xliff:g> యాప్‌ను చెక్ చేసి, కంట్రోల్ ఇప్పటికీ అందుబాటులో ఉందని, యాప్ సెట్టింగ్‌లు మారలేదని నిర్ధారించుకోండి."</string>
     <string name="controls_open_app" msgid="483650971094300141">"యాప్‌ను తెరువు"</string>
     <string name="controls_error_generic" msgid="352500456918362905">"స్టేటస్ లోడ్ చేయడం సాధ్యపడలేదు"</string>
     <string name="controls_error_failed" msgid="960228639198558525">"ఎర్రర్, మళ్లీ ప్రయత్నించండి"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ప్రసారం చేయండి"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"అవుట్‌పుట్‌ను మార్చండి"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"తెలియదు"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-television/config.xml b/packages/SystemUI/res/values-television/config.xml
index 94f6c39..375bd39 100644
--- a/packages/SystemUI/res/values-television/config.xml
+++ b/packages/SystemUI/res/values-television/config.xml
@@ -22,7 +22,7 @@
 <resources>
     <!-- SystemUIFactory component -->
     <string name="config_systemUIFactoryComponent" translatable="false">
-        com.android.systemui.tv.TvSystemUIFactory
+        com.android.systemui.tv.TvSystemUIInitializer
     </string>
 
     <!-- Svelte specific logic, see RecentsConfiguration.SVELTE_* constants. -->
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 8daf4b5..8958be0 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"อุปกรณ์ถูกล็อก"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"กำลังสแกนใบหน้า"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ส่ง"</string>
-    <string name="phone_label" msgid="5715229948920451352">"เปิดโทรศัพท์"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"เปิดตัวช่วยเสียง"</string>
-    <string name="camera_label" msgid="8253821920931143699">"เปิดกล้อง"</string>
     <string name="cancel" msgid="1089011503403416730">"ยกเลิก"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"ยืนยัน"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ลองอีกครั้ง"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"แตะอีกครั้ง"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"เลื่อนขึ้นเพื่อเปิด"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"กดไอคอนปลดล็อกเพื่อเปิด"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ปลดล็อกด้วยใบหน้าแล้ว กดไอคอนปลดล็อกเพื่อเปิด"</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ปลดล็อกด้วยใบหน้าแล้ว กดเพื่อเปิด"</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"จดจำใบหน้าได้ กดเพื่อเปิด"</string>
@@ -915,12 +914,12 @@
     <string name="wifi_scan_notify_message" msgid="3753839537448621794">"เพื่อปรับปรุงประสบการณ์การใช้อุปกรณ์ แอปและบริการต่างๆ จะยังคงสแกนหาเครือข่าย Wi‑Fi ได้ทุกเมื่อแม้ว่า Wi‑Fi จะปิดอยู่ คุณเปลี่ยนตัวเลือกนี้ได้ในการตั้งค่าการสแกนหา Wi-Fi "<annotation id="link">"เปลี่ยนการตั้งค่า"</annotation></string>
     <string name="turn_off_airplane_mode" msgid="8425587763226548579">"ปิดโหมดบนเครื่องบิน"</string>
     <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> ต้องการเพิ่มองค์ประกอบต่อไปนี้ในการตั้งค่าด่วน"</string>
-    <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"เพิ่มชิ้นส่วน"</string>
-    <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ไม่ต้องเพิ่มชิ้นส่วน"</string>
+    <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"เพิ่มองค์ประกอบ"</string>
+    <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ไม่เพิ่มองค์ประกอบ"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"เลือกผู้ใช้"</string>
     <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{ทำงานอยู่ # แอป}other{ทำงานอยู่ # แอป}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"ข้อมูลใหม่"</string>
-    <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"แอปที่ใช้งานอยู่"</string>
+    <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"แอปที่ทำงานอยู่"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"แอปเหล่านี้กำลังทำงานแม้ว่าคุณจะไม่ได้ใช้งานอยู่ก็ตาม วิธีนี้ช่วยให้ฟังก์ชันการทำงานของแอปมีประสิทธิภาพมากขึ้น แต่ก็อาจส่งผลต่ออายุการใช้งานแบตเตอรี่ด้วย"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"หยุด"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"หยุดแล้ว"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"ออกอากาศ <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"เปลี่ยนเอาต์พุต"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ไม่ทราบ"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"HH:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index e8c191b..134005c 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Naka-lock ang device"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Sina-scan ang mukha"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Ipadala"</string>
-    <string name="phone_label" msgid="5715229948920451352">"buksan ang telepono"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"buksan ang voice assist"</string>
-    <string name="camera_label" msgid="8253821920931143699">"buksan ang camera"</string>
     <string name="cancel" msgid="1089011503403416730">"Kanselahin"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Kumpirmahin"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Subukang muli"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"I-tap ulit"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Mag-swipe pataas para buksan"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pindutin ang icon ng unlock para buksan"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Na-unlock gamit ang mukha. Pindutin ang icon ng unlock para buksan."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Na-unlock gamit ang mukha. Pindutin para buksan."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Nakilala ang mukha. Pindutin para buksan."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"I-broadcast ang <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Baguhin ang output"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Hindi alam"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index adb3fb4..fb928b2 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Cihaz kilitlendi"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Yüz taranıyor"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Gönder"</string>
-    <string name="phone_label" msgid="5715229948920451352">"telefonu aç"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"sesli yardımı aç"</string>
-    <string name="camera_label" msgid="8253821920931143699">"kamerayı aç"</string>
     <string name="cancel" msgid="1089011503403416730">"İptal"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Onayla"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Tekrar dene"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Tekrar dokunun"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Açmak için yukarı kaydırın"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Açmak için Kilit açma simgesine basın"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Kilit, yüzünüzle açıldı. Kilit açma simgesine basın."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Cihazın kilidini yüzünüzle açtınız. Açmak için basın."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Yüzünüz tanındı. Açmak için basın."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> uygulamasında anons yapın"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Çıkışı değiştirme"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Bilinmiyor"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"d MMM, EEE"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:dd"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 66fb209..3df26f6 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Пристрій заблоковано"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Сканування обличчя"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Надіслати"</string>
-    <string name="phone_label" msgid="5715229948920451352">"відкрити телефон"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"запустити голосові підказки"</string>
-    <string name="camera_label" msgid="8253821920931143699">"відкрити камеру"</string>
     <string name="cancel" msgid="1089011503403416730">"Скасувати"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Підтвердити"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Повторити спробу"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Натисніть знову"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Проведіть пальцем угору, щоб відкрити"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Щоб відкрити, натисніть значок розблокування."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Розблоковано (фейсконтроль). Натисніть значок розблокування."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Розблоковано (фейсконтроль). Натисніть, щоб відкрити."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Обличчя розпізнано. Натисніть, щоб відкрити."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Змінити додаток для трансляції на <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Змінити аудіовихід"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Невідомо"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index c40927e..40e0bb3 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"آلہ مقفل کر دیا گیا"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"اسکیننگ چہرہ"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"بھیجیں"</string>
-    <string name="phone_label" msgid="5715229948920451352">"فون کھولیں"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"صوتی معاون کھولیں"</string>
-    <string name="camera_label" msgid="8253821920931143699">"کیمرا کھولیں"</string>
     <string name="cancel" msgid="1089011503403416730">"منسوخ کريں"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"تصدیق کریں"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"دوبارہ کوشش کریں"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"دوبارہ تھپتھپائیں"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"کھولنے کے لیے اوپر سوائپ کريں"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"کھولنے کیلئے انلاک آئیکن دبائیں"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"چہرے سے انلاک کیا گیا۔ کھولنے کیلئے انلاک آئیکن دبائیں۔"</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"چہرے سے انلاک کیا گیا۔ کھولنے کے لیے دبائیں۔"</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"چہرے کی شناخت ہو گئی۔ کھولنے کے لیے دبائیں۔"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> پر براڈکاسٹ کریں"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"آؤٹ پٹ تبدیل کریں"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"نامعلوم"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index f9ad0b7..a6490f4 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Qurilma qulflandi"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Yuzni skanerlash"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Yuborish"</string>
-    <string name="phone_label" msgid="5715229948920451352">"telefonni ochish"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"ovozli yordamni yoqish"</string>
-    <string name="camera_label" msgid="8253821920931143699">"kamerani ochish"</string>
     <string name="cancel" msgid="1089011503403416730">"Bekor qilish"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"OK"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Qayta urinish"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Yana bosing"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Ochish uchun tepaga suring"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Ochish uchun ochish belgisini bosing"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Yuz orqali ochilgan. Ochish uchun ochish belgisini bosing."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Yuz orqali ochildi. Ochish uchun bosing."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Yuz aniqlandi. Ochish uchun bosing."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ilovasiga translatsiya"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Ovoz chiqishini oʻzgartirish"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Noaniq"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"s:dd"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 7df4339..3a579f1 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Đã khóa thiết bị"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Quét tìm khuôn mặt"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Gửi"</string>
-    <string name="phone_label" msgid="5715229948920451352">"mở điện thoại"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"mở trợ lý thoại"</string>
-    <string name="camera_label" msgid="8253821920931143699">"mở máy ảnh"</string>
     <string name="cancel" msgid="1089011503403416730">"Hủy"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Xác nhận"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Thử lại"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Nhấn lại"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Vuốt lên để mở"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Nhấn biểu tượng mở khoá để mở"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Đã mở khoá bằng khuôn mặt. Nhấn vào biểu tượng mở khoá để mở."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Đã mở khoá bằng khuôn mặt. Nhấn để mở."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Đã nhận diện khuôn mặt. Nhấn để mở."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Phát <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Thay đổi đầu ra"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Không xác định"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 62b1bd8..b46406e 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"设备已锁定"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"正在扫描面孔"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"发送"</string>
-    <string name="phone_label" msgid="5715229948920451352">"打开电话"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"打开语音助理"</string>
-    <string name="camera_label" msgid="8253821920931143699">"打开相机"</string>
     <string name="cancel" msgid="1089011503403416730">"取消"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"确认"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"重试"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"请再点按一次"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"向上滑动即可打开"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"按下解锁图标即可打开"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"已通过面孔识别解锁。按下解锁图标即可打开。"</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"已通过面孔识别解锁。点按即可打开。"</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"识别出面孔。点按即可打开。"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"广播“<xliff:g id="SWITCHAPP">%1$s</xliff:g>”的内容"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"更改输出来源"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"未知"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 2ac494a..1958d0d 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"裝置已上鎖"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"掃瞄緊面孔"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"傳送"</string>
-    <string name="phone_label" msgid="5715229948920451352">"開啟電話"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"開啟語音助手"</string>
-    <string name="camera_label" msgid="8253821920931143699">"開啟相機"</string>
     <string name="cancel" msgid="1089011503403416730">"取消"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"確認"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"請再試一次"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"再次輕按"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"按解鎖圖示即可開啟"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"已使用面孔解鎖。按解鎖圖示即可開啟。"</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"已使用面孔解鎖。按下即可開啟。"</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"已識別面孔。按下即可開啟。"</string>
@@ -374,7 +373,7 @@
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」擁有此裝置,並可能會監察網絡流量"</string>
     <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"此裝置由 <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> 提供"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"此裝置屬於您的機構,並已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網"</string>
-    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"此裝置屬於「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」,並已透過「<xliff:g id="VPN_APP">%2$s</xliff:g>」連接至互聯網"</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"此裝置由「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」所有,並透過「<xliff:g id="VPN_APP">%2$s</xliff:g>」連接至互聯網"</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"此裝置屬於您的機構"</string>
     <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"此裝置屬於「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」"</string>
     <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"此裝置屬於您的機構,並已透過 VPN 連接至互聯網"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"廣播「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"變更輸出來源"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"不明"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"MMM d EEE"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index a0fe941..22d0544 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"裝置已鎖定"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"掃描臉孔"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"傳送"</string>
-    <string name="phone_label" msgid="5715229948920451352">"開啟電話"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"開啟語音小幫手"</string>
-    <string name="camera_label" msgid="8253821920931143699">"開啟攝影機"</string>
     <string name="cancel" msgid="1089011503403416730">"取消"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"確認"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"再試一次"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"再輕觸一次"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"按下「解鎖」圖示即可開啟"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"裝置已透過人臉解鎖,按下「解鎖」圖示即可開啟。"</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"裝置已透過你的臉解鎖,按下即可開啟。"</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"臉孔辨識完成,按下即可開啟。"</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"播送「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"變更輸出來源"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"不明"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"MMM d EEE"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 47de98e..4000ce0 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -124,9 +124,6 @@
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Idivayisi ikhiyiwe"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Ukuskena ubuso"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Thumela"</string>
-    <string name="phone_label" msgid="5715229948920451352">"vula ifoni"</string>
-    <string name="voice_assist_label" msgid="3725967093735929020">"vula isilekeleli sezwi"</string>
-    <string name="camera_label" msgid="8253821920931143699">"vula ikhamera"</string>
     <string name="cancel" msgid="1089011503403416730">"Khansela"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Qinisekisa"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Zama futhi"</string>
@@ -310,6 +307,8 @@
     <string name="tap_again" msgid="1315420114387908655">"Thepha futhi"</string>
     <string name="keyguard_unlock" msgid="8031975796351361601">"Swayiphela phezulu ukuze uvule"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Cindezela isithonjana sokuvula ukuze uvule"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+    <skip />
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ivulwe ngobuso. Cindezela isithonjana sokuvula ukuze uvule."</string>
     <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Vula ngobuso. Cindezela ukuze uvule."</string>
     <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ubuso buyaziwa. Cindezela ukuze uvule."</string>
@@ -953,4 +952,7 @@
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Sakaza i-<xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Shintsha okuphumayo"</string>
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Akwaziwa"</string>
+    <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+    <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+    <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index ccf18d2..1eece4c 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -129,7 +129,6 @@
     <color name="smart_reply_button_stroke">@*android:color/accent_device_default</color>
 
     <!-- Biometric dialog colors -->
-    <color name="biometric_dialog_dim_color">#80000000</color>              <!-- 50% black -->
     <color name="biometric_dialog_gray">#ff757575</color>
     <color name="biometric_dialog_accent">@color/material_dynamic_primary40</color>
     <color name="biometric_dialog_error">#ffd93025</color>                  <!-- red 600 -->
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 771973c..82a3b58 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -286,7 +286,7 @@
     <bool name="config_enableFullscreenUserSwitcher">false</bool>
 
     <!-- SystemUIFactory component -->
-    <string name="config_systemUIFactoryComponent" translatable="false">com.android.systemui.SystemUIFactory</string>
+    <string name="config_systemUIFactoryComponent" translatable="false">com.android.systemui.SystemUIInitializerImpl</string>
 
     <!-- QS tile shape store width. negative implies fill configuration instead of stroke-->
     <dimen name="config_qsTileStrokeWidthActive">-1dp</dimen>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 13250c8..ec69d72 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1443,6 +1443,7 @@
         @*android:dimen/status_bar_system_icon_size</dimen>
     <dimen name="dream_overlay_camera_mic_off_indicator_size">8dp</dimen>
     <dimen name="dream_overlay_notification_indicator_size">6dp</dimen>
+    <dimen name="dream_overlay_grey_chip_width">56dp</dimen>
 
     <!-- Dream overlay complications related dimensions -->
     <dimen name="dream_overlay_complication_clock_time_text_size">100sp</dimen>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index f013f9b..dca5ea8 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -132,9 +132,6 @@
     <item type="id" name="status_bar_view_state_tag" />
 
     <item type="id" name="display_cutout" />
-    <item type="id" name="display_cutout_left" />
-    <item type="id" name="display_cutout_right" />
-    <item type="id" name="display_cutout_bottom" />
 
     <item type="id" name="row_tag_for_content_view" />
 
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index ef672f3..9c2542c 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -802,6 +802,8 @@
     <!-- Message shown when lock screen is unlocked (ie: by trust agent) and the user taps the empty space on the lock screen and UDFPS is supported. Provides extra instructions for how the user can enter their device [CHAR LIMIT=60] -->
     <string name="keyguard_unlock_press">Press the unlock icon to open</string>
 
+    <!-- Message shown when non-bypass face authentication succeeds. Provides extra instructions for how the user can enter their device [CHAR LIMIT=60] -->
+    <string name="keyguard_face_successful_unlock_swipe">Unlocked by face. Swipe up to open.</string>
     <!-- Message shown when non-bypass face authentication succeeds and UDFPS is supported. Provides extra instructions for how the user can enter their device [CHAR LIMIT=60] -->
     <string name="keyguard_face_successful_unlock_press">Unlocked by face. Press the unlock icon to open.</string>
     <!-- Message shown when non-bypass face authentication succeeds and UDFPS is supported. Provides extra instructions for how the user can enter their device [CHAR LIMIT=60] -->
@@ -2295,8 +2297,8 @@
     <string name="media_output_dialog_disconnected">(disconnected)</string>
     <!-- Summary for connecting error message [CHAR LIMIT=NONE] -->
     <string name="media_output_dialog_connect_failed">Can\'t switch. Tap to try again.</string>
-    <!-- Title for pairing item [CHAR LIMIT=60] -->
-    <string name="media_output_dialog_pairing_new">Pair new device</string>
+    <!-- Title for connecting item [CHAR LIMIT=60] -->
+    <string name="media_output_dialog_pairing_new">Connect a device</string>
     <!-- Title for launch app [CHAR LIMIT=60] -->
     <string name="media_output_dialog_launch_app_text">To cast this session, please open the app.</string>
     <!-- App name when can't get app name [CHAR LIMIT=60] -->
@@ -2553,6 +2555,10 @@
     <string name="dream_overlay_status_bar_priority_mode">Priority mode</string>
     <!-- Content description for the alarm set icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
     <string name="dream_overlay_status_bar_alarm_set">Alarm set</string>
+    <!-- Content description for the camera off icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
+    <string name="dream_overlay_status_bar_camera_off">Camera is off</string>
+    <!-- Content description for the mic off icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
+    <string name="dream_overlay_status_bar_mic_off">Mic is off</string>
     <!-- Content description for the camera and mic off icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
     <string name="dream_overlay_status_bar_camera_mic_off">Camera and mic are off</string>
     <!-- Content description for the notifications indicator icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
@@ -2560,6 +2566,10 @@
     =1 {# notification}
     other {# notifications}
     }</string>
+    <!-- Accessibility label for weather complication on dreams with weather condition and temperature [CHAR_LIMIT=200] -->
+    <string name="dream_overlay_weather_complication_desc">
+        <xliff:g id="weather_condition" example="Partly cloudy">%1$s</xliff:g>, <xliff:g id="temperature" example="7°C">%2$s</xliff:g>
+    </string>
 
     <!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, media app is broadcasting -->
     <string name="broadcasting_description_is_broadcasting">Broadcasting</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 758c16d..2227978 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -265,6 +265,10 @@
     <style name="Animation.ShutdownUi" parent="@android:style/Animation.Toast">
     </style>
 
+    <style name="Theme.SystemUI.MediaProjectionAppSelector"
+        parent="@*android:style/Theme.DeviceDefault.Chooser">
+    </style>
+
     <!-- Standard animations for hiding and showing the status bar. -->
 
     <style name="Theme.SystemUI" parent="@*android:style/Theme.DeviceDefault.SystemUI">
diff --git a/packages/SystemUI/res/xml/media_session_collapsed.xml b/packages/SystemUI/res/xml/media_session_collapsed.xml
index eab7def..9115d42 100644
--- a/packages/SystemUI/res/xml/media_session_collapsed.xml
+++ b/packages/SystemUI/res/xml/media_session_collapsed.xml
@@ -19,7 +19,7 @@
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
     <Constraint
-        android:id="@+id/media_action_barrier"
+        android:id="@+id/media_action_barrier_start"
         android:layout_width="0dp"
         android:layout_height="0dp"
         app:layout_constraintTop_toBottomOf="@id/media_seamless"
@@ -91,12 +91,16 @@
         app:layout_constraintRight_toLeftOf="@id/media_progress_bar"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintTop_toBottomOf="@id/media_seamless"
-        app:layout_constraintLeft_toRightOf="@id/media_action_barrier" />
+        app:layout_constraintLeft_toRightOf="@id/media_action_barrier_start" />
 
     <!-- Showing time while scrubbing isn't available in collapsed mode. -->
     <Constraint
         android:id="@+id/media_scrubbing_elapsed_time"
-        android:visibility="gone" />
+        android:visibility="gone"
+        app:layout_constraintRight_toLeftOf="@id/media_progress_bar"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/media_seamless"
+        app:layout_constraintLeft_toRightOf="@id/media_action_barrier_start" />
 
     <Constraint
         android:id="@+id/media_progress_bar"
@@ -124,7 +128,12 @@
     <!-- Showing time while scrubbing isn't available in collapsed mode. -->
     <Constraint
         android:id="@+id/media_scrubbing_total_time"
-        android:visibility="gone" />
+        android:visibility="gone"
+        app:layout_constraintVertical_bias="1"
+        app:layout_constraintLeft_toRightOf="@id/media_progress_bar"
+        app:layout_constraintRight_toLeftOf="@id/action0"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/media_seamless" />
 
     <Constraint
         android:id="@+id/action0"
diff --git a/packages/SystemUI/screenshot/Android.bp b/packages/SystemUI/screenshot/Android.bp
index a79fd9040d..f449398 100644
--- a/packages/SystemUI/screenshot/Android.bp
+++ b/packages/SystemUI/screenshot/Android.bp
@@ -26,11 +26,7 @@
     manifest: "AndroidManifest.xml",
 
     srcs: [
-        // All files in this library should be in Kotlin besides some exceptions.
         "src/**/*.kt",
-
-        // This file was forked from google3, so exceptionally it can be in Java.
-        "src/com/android/systemui/testing/screenshot/DynamicColorsTestUtils.java",
     ],
 
     resource_dirs: [
@@ -42,6 +38,7 @@
         "androidx.test.espresso.core",
         "androidx.appcompat_appcompat",
         "platform-screenshot-diff-core",
+        "guava",
     ],
 
     kotlincflags: ["-Xjvm-default=all"],
diff --git a/packages/SystemUI/screenshot/AndroidManifest.xml b/packages/SystemUI/screenshot/AndroidManifest.xml
index 3b703be..a405836 100644
--- a/packages/SystemUI/screenshot/AndroidManifest.xml
+++ b/packages/SystemUI/screenshot/AndroidManifest.xml
@@ -23,6 +23,4 @@
             android:exported="true"
             android:theme="@style/Theme.SystemUI.Screenshot" />
     </application>
-
-    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 </manifest>
diff --git a/packages/SystemUI/screenshot/res/values/themes.xml b/packages/SystemUI/screenshot/res/values/themes.xml
index 40e50bb..a7f8a26 100644
--- a/packages/SystemUI/screenshot/res/values/themes.xml
+++ b/packages/SystemUI/screenshot/res/values/themes.xml
@@ -19,6 +19,12 @@
         <item name="android:windowActionBar">false</item>
         <item name="android:windowNoTitle">true</item>
 
+        <!-- We make the status and navigation bars transparent so that the screenshotted content is
+             not clipped by the status bar height when drawn into the Bitmap (which is what happens
+             given that we draw the view into the Bitmap using hardware acceleration). -->
+        <item name="android:statusBarColor">@android:color/transparent</item>
+        <item name="android:navigationBarColor">@android:color/transparent</item>
+
         <!-- Make sure that device specific cutouts don't impact the outcome of screenshot tests -->
         <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
     </style>
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/Bitmap.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/Bitmap.kt
new file mode 100644
index 0000000..a4a70a4
--- /dev/null
+++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/Bitmap.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.testing.screenshot
+
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.os.Build
+import android.view.View
+import platform.test.screenshot.matchers.MSSIMMatcher
+import platform.test.screenshot.matchers.PixelPerfectMatcher
+
+/** Draw this [View] into a [Bitmap]. */
+// TODO(b/195673633): Remove this once Compose screenshot tests use hardware rendering for their
+// tests.
+fun View.drawIntoBitmap(): Bitmap {
+    val bitmap =
+        Bitmap.createBitmap(
+            measuredWidth,
+            measuredHeight,
+            Bitmap.Config.ARGB_8888,
+        )
+    val canvas = Canvas(bitmap)
+    draw(canvas)
+    return bitmap
+}
+
+/**
+ * The [BitmapMatcher][platform.test.screenshot.matchers.BitmapMatcher] that should be used for
+ * screenshot *unit* tests.
+ */
+val UnitTestBitmapMatcher =
+    if (Build.CPU_ABI == "x86_64") {
+        // Different CPU architectures can sometimes end up rendering differently, so we can't do
+        // pixel-perfect matching on different architectures using the same golden. Given that our
+        // presubmits are run on cf_x86_64_phone, our goldens should be perfectly matched on the
+        // x86_64 architecture and use the Structural Similarity Index on others.
+        // TODO(b/237511747): Run our screenshot presubmit tests on arm64 instead so that we can
+        // do pixel perfect matching both at presubmit time and at development time with actual
+        // devices.
+        PixelPerfectMatcher()
+    } else {
+        MSSIMMatcher()
+    }
+
+/**
+ * The [BitmapMatcher][platform.test.screenshot.matchers.BitmapMatcher] that should be used for
+ * screenshot *unit* tests.
+ *
+ * We use the Structural Similarity Index for integration tests because they usually contain
+ * additional information and noise that shouldn't break the test.
+ */
+val IntegrationTestBitmapMatcher = MSSIMMatcher()
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/DynamicColorsTestUtils.java b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/DynamicColorsTestUtils.java
deleted file mode 100644
index 96ec4c5..0000000
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/DynamicColorsTestUtils.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.testing.screenshot;
-
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-
-import android.app.UiAutomation;
-import android.content.Context;
-import android.provider.Settings;
-import android.util.Log;
-
-import androidx.annotation.ColorInt;
-import androidx.annotation.ColorRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
-import androidx.core.content.ContextCompat;
-import androidx.test.espresso.Espresso;
-import androidx.test.espresso.IdlingRegistry;
-import androidx.test.espresso.IdlingResource;
-
-import org.json.JSONObject;
-import org.junit.function.ThrowingRunnable;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/*
- * Note: This file was forked from
- * google3/third_party/java_src/android_libs/material_components/screenshot_tests/java/android/
- * support/design/scuba/color/DynamicColorsTestUtils.java.
- */
-
-/** Utility that helps change the dynamic system colors for testing. */
-@RequiresApi(32)
-public class DynamicColorsTestUtils {
-
-    private static final String TAG = DynamicColorsTestUtils.class.getSimpleName();
-
-    private static final String THEME_CUSTOMIZATION_KEY = "theme_customization_overlay_packages";
-    private static final String THEME_CUSTOMIZATION_SYSTEM_PALETTE_KEY =
-            "android.theme.customization.system_palette";
-
-    private static final int ORANGE_SYSTEM_SEED_COLOR = 0xA66800;
-    private static final int ORANGE_EXPECTED_SYSTEM_ACCENT1_600_COLOR = -8235756;
-
-    private DynamicColorsTestUtils() {
-    }
-
-    /**
-     * Update system dynamic colors (e.g., android.R.color.system_accent1_600) based on an orange
-     * seed color, and then wait for the change to propagate to the app by comparing
-     * android.R.color.system_accent1_600 to the expected orange value.
-     */
-    public static void updateSystemColorsToOrange() {
-        updateSystemColors(ORANGE_SYSTEM_SEED_COLOR, ORANGE_EXPECTED_SYSTEM_ACCENT1_600_COLOR);
-    }
-
-    /**
-     * Update system dynamic colors (e.g., android.R.color.system_accent1_600) based on the provided
-     * {@code seedColor}, and then wait for the change to propagate to the app by comparing
-     * android.R.color.system_accent1_600 to {@code expectedSystemAccent1600}.
-     */
-    public static void updateSystemColors(
-            @ColorInt int seedColor, @ColorInt int expectedSystemAccent1600) {
-        Context context = getInstrumentation().getTargetContext();
-
-        int actualSystemAccent1600 =
-                ContextCompat.getColor(context, android.R.color.system_accent1_600);
-
-        if (expectedSystemAccent1600 == actualSystemAccent1600) {
-            String expectedColorString = Integer.toHexString(expectedSystemAccent1600);
-            Log.d(
-                    TAG,
-                    "Skipped updating system colors since system_accent1_600 is already equal to "
-                            + "expected: "
-                            + expectedColorString);
-            return;
-        }
-
-        updateSystemColors(seedColor);
-    }
-
-    /**
-     * Update system dynamic colors (e.g., android.R.color.system_accent1_600) based on the provided
-     * {@code seedColor}, and then wait for the change to propagate to the app by checking
-     * android.R.color.system_accent1_600 for any change.
-     */
-    public static void updateSystemColors(@ColorInt int seedColor) {
-        Context context = getInstrumentation().getTargetContext();
-
-        // Initialize system color idling resource with original system_accent1_600 value.
-        ColorChangeIdlingResource systemColorIdlingResource =
-                new ColorChangeIdlingResource(context, android.R.color.system_accent1_600);
-
-        // Update system theme color setting to trigger fabricated resource overlay.
-        runWithShellPermissionIdentity(
-                () ->
-                        Settings.Secure.putString(
-                                context.getContentResolver(),
-                                THEME_CUSTOMIZATION_KEY,
-                                buildThemeCustomizationString(seedColor)));
-
-        // Wait for system color update to propagate to app.
-        IdlingRegistry idlingRegistry = IdlingRegistry.getInstance();
-        idlingRegistry.register(systemColorIdlingResource);
-        Espresso.onIdle();
-        idlingRegistry.unregister(systemColorIdlingResource);
-
-        Log.d(TAG,
-                Settings.Secure.getString(context.getContentResolver(), THEME_CUSTOMIZATION_KEY));
-    }
-
-    private static String buildThemeCustomizationString(@ColorInt int seedColor) {
-        String seedColorHex = Integer.toHexString(seedColor);
-        Map<String, String> themeCustomizationMap = new HashMap<>();
-        themeCustomizationMap.put(THEME_CUSTOMIZATION_SYSTEM_PALETTE_KEY, seedColorHex);
-        return new JSONObject(themeCustomizationMap).toString();
-    }
-
-    private static void runWithShellPermissionIdentity(@NonNull ThrowingRunnable runnable) {
-        UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
-        uiAutomation.adoptShellPermissionIdentity();
-        try {
-            runnable.run();
-        } catch (Throwable e) {
-            throw new RuntimeException(e);
-        } finally {
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    private static class ColorChangeIdlingResource implements IdlingResource {
-
-        private final Context mContext;
-        private final int mColorResId;
-        private final int mInitialColorInt;
-
-        private ResourceCallback mResourceCallback;
-        private boolean mIdleNow;
-
-        ColorChangeIdlingResource(Context context, @ColorRes int colorResId) {
-            this.mContext = context;
-            this.mColorResId = colorResId;
-            this.mInitialColorInt = ContextCompat.getColor(context, colorResId);
-        }
-
-        @Override
-        public String getName() {
-            return ColorChangeIdlingResource.class.getName();
-        }
-
-        @Override
-        public boolean isIdleNow() {
-            if (mIdleNow) {
-                return true;
-            }
-
-            int currentColorInt = ContextCompat.getColor(mContext, mColorResId);
-
-            String initialColorString = Integer.toHexString(mInitialColorInt);
-            String currentColorString = Integer.toHexString(currentColorInt);
-            Log.d(TAG, String.format("Initial=%s, Current=%s", initialColorString,
-                    currentColorString));
-
-            mIdleNow = currentColorInt != mInitialColorInt;
-            Log.d(TAG, String.format("idleNow=%b", mIdleNow));
-
-            if (mIdleNow) {
-                mResourceCallback.onTransitionToIdle();
-            }
-            return mIdleNow;
-        }
-
-        @Override
-        public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
-            this.mResourceCallback = resourceCallback;
-        }
-    }
-}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt
deleted file mode 100644
index 363ce10..0000000
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.testing.screenshot
-
-import android.app.UiModeManager
-import android.content.Context
-import android.graphics.Bitmap
-import android.graphics.Canvas
-import android.os.UserHandle
-import android.view.Display
-import android.view.View
-import android.view.WindowManagerGlobal
-import androidx.test.platform.app.InstrumentationRegistry
-import org.junit.rules.TestRule
-import org.junit.runner.Description
-import org.junit.runners.model.Statement
-import platform.test.screenshot.GoldenImagePathManager
-import platform.test.screenshot.PathConfig
-import platform.test.screenshot.PathElementNoContext
-import platform.test.screenshot.ScreenshotTestRule
-import platform.test.screenshot.matchers.PixelPerfectMatcher
-
-/**
- * A base rule for screenshot diff tests.
- *
- * This rules takes care of setting up the activity according to [testSpec] by:
- * - emulating the display size and density.
- * - setting the dark/light mode.
- * - setting the system (Material You) colors to a fixed value.
- *
- * @see ComposeScreenshotTestRule
- * @see ViewScreenshotTestRule
- */
-class ScreenshotTestRule(private val testSpec: ScreenshotTestSpec) : TestRule {
-    private var currentDisplay: DisplaySpec? = null
-    private var currentGoldenIdentifier: String? = null
-
-    private val pathConfig =
-        PathConfig(
-            PathElementNoContext("model", isDir = true) {
-                currentDisplay?.name ?: error("currentDisplay is null")
-            },
-        )
-    private val defaultMatcher = PixelPerfectMatcher()
-
-    private val screenshotRule =
-        ScreenshotTestRule(
-            SystemUIGoldenImagePathManager(
-                pathConfig,
-                currentGoldenIdentifier = {
-                    currentGoldenIdentifier ?: error("currentGoldenIdentifier is null")
-                },
-            )
-        )
-
-    override fun apply(base: Statement, description: Description): Statement {
-        // The statement which call beforeTest() before running the test and afterTest() afterwards.
-        val statement =
-            object : Statement() {
-                override fun evaluate() {
-                    try {
-                        beforeTest()
-                        base.evaluate()
-                    } finally {
-                        afterTest()
-                    }
-                }
-            }
-
-        return screenshotRule.apply(statement, description)
-    }
-
-    private fun beforeTest() {
-        // Update the system colors to a fixed color, so that tests don't depend on the host device
-        // extracted colors. Note that we don't restore the default device colors at the end of the
-        // test because changing the colors (and waiting for them to be applied) is costly and makes
-        // the screenshot tests noticeably slower.
-        DynamicColorsTestUtils.updateSystemColorsToOrange()
-
-        // Emulate the display size and density.
-        val display = testSpec.display
-        val density = display.densityDpi
-        val wm = WindowManagerGlobal.getWindowManagerService()
-        val (width, height) = getEmulatedDisplaySize()
-        wm.setForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY, density, UserHandle.myUserId())
-        wm.setForcedDisplaySize(Display.DEFAULT_DISPLAY, width, height)
-
-        // Force the dark/light theme.
-        val uiModeManager =
-            InstrumentationRegistry.getInstrumentation()
-                .targetContext
-                .getSystemService(Context.UI_MODE_SERVICE) as UiModeManager
-        uiModeManager.setApplicationNightMode(
-            if (testSpec.isDarkTheme) {
-                UiModeManager.MODE_NIGHT_YES
-            } else {
-                UiModeManager.MODE_NIGHT_NO
-            }
-        )
-    }
-
-    private fun afterTest() {
-        // Reset the density and display size.
-        val wm = WindowManagerGlobal.getWindowManagerService()
-        wm.clearForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY, UserHandle.myUserId())
-        wm.clearForcedDisplaySize(Display.DEFAULT_DISPLAY)
-
-        // Reset the dark/light theme.
-        val uiModeManager =
-            InstrumentationRegistry.getInstrumentation()
-                .targetContext
-                .getSystemService(Context.UI_MODE_SERVICE) as UiModeManager
-        uiModeManager.setApplicationNightMode(UiModeManager.MODE_NIGHT_AUTO)
-    }
-
-    /**
-     * Compare the content of [view] with the golden image identified by [goldenIdentifier] in the
-     * context of [testSpec].
-     */
-    fun screenshotTest(goldenIdentifier: String, view: View) {
-        val bitmap = drawIntoBitmap(view)
-
-        // Compare bitmap against golden asset.
-        val isDarkTheme = testSpec.isDarkTheme
-        val isLandscape = testSpec.isLandscape
-        val identifierWithSpec = buildString {
-            append(goldenIdentifier)
-            if (isDarkTheme) append("_dark")
-            if (isLandscape) append("_landscape")
-        }
-
-        // TODO(b/230832101): Provide a way to pass a PathConfig and override the file name on
-        // device to assertBitmapAgainstGolden instead?
-        currentDisplay = testSpec.display
-        currentGoldenIdentifier = goldenIdentifier
-        screenshotRule.assertBitmapAgainstGolden(bitmap, identifierWithSpec, defaultMatcher)
-        currentDisplay = null
-        currentGoldenIdentifier = goldenIdentifier
-    }
-
-    /** Draw [view] into a [Bitmap]. */
-    private fun drawIntoBitmap(view: View): Bitmap {
-        val bitmap =
-            Bitmap.createBitmap(
-                view.measuredWidth,
-                view.measuredHeight,
-                Bitmap.Config.ARGB_8888,
-            )
-        val canvas = Canvas(bitmap)
-        view.draw(canvas)
-        return bitmap
-    }
-
-    /** Get the emulated display size for [testSpec]. */
-    private fun getEmulatedDisplaySize(): Pair<Int, Int> {
-        val display = testSpec.display
-        val isPortraitNaturalPosition = display.width < display.height
-        return if (testSpec.isLandscape) {
-            if (isPortraitNaturalPosition) {
-                display.height to display.width
-            } else {
-                display.width to display.height
-            }
-        } else {
-            if (isPortraitNaturalPosition) {
-                display.width to display.height
-            } else {
-                display.height to display.width
-            }
-        }
-    }
-}
-
-private class SystemUIGoldenImagePathManager(
-    pathConfig: PathConfig,
-    private val currentGoldenIdentifier: () -> String,
-) :
-    GoldenImagePathManager(
-        appContext = InstrumentationRegistry.getInstrumentation().context,
-        deviceLocalPath =
-            InstrumentationRegistry.getInstrumentation()
-                .targetContext
-                .filesDir
-                .absolutePath
-                .toString() + "/sysui_screenshots",
-        pathConfig = pathConfig,
-    ) {
-    // This string is appended to all actual/expected screenshots on the device. We append the
-    // golden identifier so that our pull_golden.py scripts can map a screenshot on device to its
-    // asset (and automatically update it, if necessary).
-    override fun toString() = currentGoldenIdentifier()
-}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestSpec.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestSpec.kt
deleted file mode 100644
index 7fc6245..0000000
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestSpec.kt
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.testing.screenshot
-
-/** The specification of a device display to be used in a screenshot test. */
-data class DisplaySpec(
-    val name: String,
-    val width: Int,
-    val height: Int,
-    val densityDpi: Int,
-)
-
-/** The specification of a screenshot diff test. */
-class ScreenshotTestSpec(
-    val display: DisplaySpec,
-    val isDarkTheme: Boolean = false,
-    val isLandscape: Boolean = false,
-) {
-    companion object {
-        /**
-         * Return a list of [ScreenshotTestSpec] for each of the [displays].
-         *
-         * If [isDarkTheme] is null, this will create a spec for both light and dark themes, for
-         * each of the orientation.
-         *
-         * If [isLandscape] is null, this will create a spec for both portrait and landscape, for
-         * each of the light/dark themes.
-         */
-        fun forDisplays(
-            vararg displays: DisplaySpec,
-            isDarkTheme: Boolean? = null,
-            isLandscape: Boolean? = null,
-        ): List<ScreenshotTestSpec> {
-            return displays.flatMap { display ->
-                buildList {
-                    fun addDisplay(isLandscape: Boolean) {
-                        if (isDarkTheme != true) {
-                            add(ScreenshotTestSpec(display, isDarkTheme = false, isLandscape))
-                        }
-
-                        if (isDarkTheme != false) {
-                            add(ScreenshotTestSpec(display, isDarkTheme = true, isLandscape))
-                        }
-                    }
-
-                    if (isLandscape != true) {
-                        addDisplay(isLandscape = false)
-                    }
-
-                    if (isLandscape != false) {
-                        addDisplay(isLandscape = true)
-                    }
-                }
-            }
-        }
-    }
-
-    override fun toString(): String = buildString {
-        // This string is appended to PNGs stored in the device, so let's keep it simple.
-        append(display.name)
-        if (isDarkTheme) append("_dark")
-        if (isLandscape) append("_landscape")
-    }
-}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/SystemUIGoldenImagePathManager.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/SystemUIGoldenImagePathManager.kt
new file mode 100644
index 0000000..cbab0a7
--- /dev/null
+++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/SystemUIGoldenImagePathManager.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.testing.screenshot
+
+import androidx.test.platform.app.InstrumentationRegistry
+import platform.test.screenshot.GoldenImagePathManager
+import platform.test.screenshot.PathConfig
+
+/** A [GoldenImagePathManager] that should be used for all SystemUI screenshot tests. */
+class SystemUIGoldenImagePathManager(
+    pathConfig: PathConfig,
+) :
+    GoldenImagePathManager(
+        appContext = InstrumentationRegistry.getInstrumentation().context,
+        deviceLocalPath =
+            InstrumentationRegistry.getInstrumentation()
+                .targetContext
+                .filesDir
+                .absolutePath
+                .toString() + "/sysui_screenshots",
+        pathConfig = pathConfig,
+    ) {
+    override fun toString(): String {
+        // This string is appended to all actual/expected screenshots on the device, so make sure
+        // it is a static value.
+        return "SystemUIGoldenImagePathManager"
+    }
+}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewCapture.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewCapture.kt
new file mode 100644
index 0000000..c609e6f
--- /dev/null
+++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewCapture.kt
@@ -0,0 +1,180 @@
+package com.android.systemui.testing.screenshot
+
+import android.app.Activity
+import android.content.Context
+import android.content.ContextWrapper
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.Rect
+import android.os.Build
+import android.os.Handler
+import android.os.Looper
+import android.util.Log
+import android.view.PixelCopy
+import android.view.SurfaceView
+import android.view.View
+import android.view.ViewTreeObserver
+import android.view.Window
+import androidx.annotation.RequiresApi
+import androidx.concurrent.futures.ResolvableFuture
+import androidx.test.annotation.ExperimentalTestApi
+import androidx.test.core.internal.os.HandlerExecutor
+import androidx.test.platform.graphics.HardwareRendererCompat
+import com.google.common.util.concurrent.ListenableFuture
+
+/*
+ * This file was forked from androidx/test/core/view/ViewCapture.kt to add [Window] parameter to
+ * [View.captureToBitmap].
+ * TODO(b/195673633): Remove this fork and use the AndroidX version instead.
+ */
+
+/**
+ * Asynchronously captures an image of the underlying view into a [Bitmap].
+ *
+ * For devices below [Build.VERSION_CODES#O] (or if the view's window cannot be determined), the
+ * image is obtained using [View#draw]. Otherwise, [PixelCopy] is used.
+ *
+ * This method will also enable [HardwareRendererCompat#setDrawingEnabled(boolean)] if required.
+ *
+ * This API is primarily intended for use in lower layer libraries or frameworks. For test authors,
+ * its recommended to use espresso or compose's captureToImage.
+ *
+ * This API is currently experimental and subject to change or removal.
+ */
+@ExperimentalTestApi
+@RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
+fun View.captureToBitmap(window: Window? = null): ListenableFuture<Bitmap> {
+    val bitmapFuture: ResolvableFuture<Bitmap> = ResolvableFuture.create()
+    val mainExecutor = HandlerExecutor(Handler(Looper.getMainLooper()))
+
+    // disable drawing again if necessary once work is complete
+    if (!HardwareRendererCompat.isDrawingEnabled()) {
+        HardwareRendererCompat.setDrawingEnabled(true)
+        bitmapFuture.addListener({ HardwareRendererCompat.setDrawingEnabled(false) }, mainExecutor)
+    }
+
+    mainExecutor.execute {
+        val forceRedrawFuture = forceRedraw()
+        forceRedrawFuture.addListener({ generateBitmap(bitmapFuture, window) }, mainExecutor)
+    }
+
+    return bitmapFuture
+}
+
+/**
+ * Trigger a redraw of the given view.
+ *
+ * Should only be called on UI thread.
+ *
+ * @return a [ListenableFuture] that will be complete once ui drawing is complete
+ */
+// NoClassDefFoundError occurs on API 15
+@RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
+// @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+@ExperimentalTestApi
+fun View.forceRedraw(): ListenableFuture<Void> {
+    val future: ResolvableFuture<Void> = ResolvableFuture.create()
+
+    if (Build.VERSION.SDK_INT >= 29 && isHardwareAccelerated) {
+        viewTreeObserver.registerFrameCommitCallback() { future.set(null) }
+    } else {
+        viewTreeObserver.addOnDrawListener(
+            object : ViewTreeObserver.OnDrawListener {
+                var handled = false
+                override fun onDraw() {
+                    if (!handled) {
+                        handled = true
+                        future.set(null)
+                        // cannot remove on draw listener inside of onDraw
+                        Handler(Looper.getMainLooper()).post {
+                            viewTreeObserver.removeOnDrawListener(this)
+                        }
+                    }
+                }
+            }
+        )
+    }
+    invalidate()
+    return future
+}
+
+private fun View.generateBitmap(
+    bitmapFuture: ResolvableFuture<Bitmap>,
+    window: Window? = null,
+) {
+    if (bitmapFuture.isCancelled) {
+        return
+    }
+    val destBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
+    when {
+        Build.VERSION.SDK_INT < 26 -> generateBitmapFromDraw(destBitmap, bitmapFuture)
+        this is SurfaceView -> generateBitmapFromSurfaceViewPixelCopy(destBitmap, bitmapFuture)
+        else -> {
+            val window = window ?: getActivity()?.window
+            if (window != null) {
+                generateBitmapFromPixelCopy(window, destBitmap, bitmapFuture)
+            } else {
+                Log.i(
+                    "View.captureToImage",
+                    "Could not find window for view. Falling back to View#draw instead of PixelCopy"
+                )
+                generateBitmapFromDraw(destBitmap, bitmapFuture)
+            }
+        }
+    }
+}
+
+@SuppressWarnings("NewApi")
+private fun SurfaceView.generateBitmapFromSurfaceViewPixelCopy(
+    destBitmap: Bitmap,
+    bitmapFuture: ResolvableFuture<Bitmap>
+) {
+    val onCopyFinished =
+        PixelCopy.OnPixelCopyFinishedListener { result ->
+            if (result == PixelCopy.SUCCESS) {
+                bitmapFuture.set(destBitmap)
+            } else {
+                bitmapFuture.setException(
+                    RuntimeException(String.format("PixelCopy failed: %d", result))
+                )
+            }
+        }
+    PixelCopy.request(this, null, destBitmap, onCopyFinished, handler)
+}
+
+internal fun View.generateBitmapFromDraw(
+    destBitmap: Bitmap,
+    bitmapFuture: ResolvableFuture<Bitmap>
+) {
+    destBitmap.density = resources.displayMetrics.densityDpi
+    computeScroll()
+    val canvas = Canvas(destBitmap)
+    canvas.translate((-scrollX).toFloat(), (-scrollY).toFloat())
+    draw(canvas)
+    bitmapFuture.set(destBitmap)
+}
+
+private fun View.getActivity(): Activity? {
+    fun Context.getActivity(): Activity? {
+        return when (this) {
+            is Activity -> this
+            is ContextWrapper -> this.baseContext.getActivity()
+            else -> null
+        }
+    }
+    return context.getActivity()
+}
+
+private fun View.generateBitmapFromPixelCopy(
+    window: Window,
+    destBitmap: Bitmap,
+    bitmapFuture: ResolvableFuture<Bitmap>
+) {
+    val locationInWindow = intArrayOf(0, 0)
+    getLocationInWindow(locationInWindow)
+    val x = locationInWindow[0]
+    val y = locationInWindow[1]
+    val boundsInWindow = Rect(x, y, x + width, y + height)
+
+    return window.generateBitmapFromPixelCopy(boundsInWindow, destBitmap, bitmapFuture)
+}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt
index 35812e3..60130e1 100644
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt
+++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt
@@ -1,58 +1,114 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.android.systemui.testing.screenshot
 
 import android.app.Activity
 import android.app.Dialog
+import android.graphics.Bitmap
+import android.graphics.HardwareRenderer
+import android.os.Looper
 import android.view.View
 import android.view.ViewGroup
 import android.view.ViewGroup.LayoutParams
+import android.view.ViewGroup.LayoutParams.MATCH_PARENT
+import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
+import android.view.Window
+import androidx.activity.ComponentActivity
+import androidx.test.espresso.Espresso
 import androidx.test.ext.junit.rules.ActivityScenarioRule
+import com.google.common.util.concurrent.FutureCallback
+import com.google.common.util.concurrent.Futures
+import kotlin.coroutines.suspendCoroutine
+import kotlinx.coroutines.runBlocking
 import org.junit.Assert.assertEquals
 import org.junit.rules.RuleChain
 import org.junit.rules.TestRule
 import org.junit.runner.Description
 import org.junit.runners.model.Statement
+import platform.test.screenshot.DeviceEmulationRule
+import platform.test.screenshot.DeviceEmulationSpec
+import platform.test.screenshot.MaterialYouColorsRule
+import platform.test.screenshot.ScreenshotTestRule
+import platform.test.screenshot.getEmulatedDevicePathConfig
 
-/** A rule for View screenshot diff tests. */
-class ViewScreenshotTestRule(testSpec: ScreenshotTestSpec) : TestRule {
+/** A rule for View screenshot diff unit tests. */
+class ViewScreenshotTestRule(emulationSpec: DeviceEmulationSpec) : TestRule {
+    private val colorsRule = MaterialYouColorsRule()
+    private val deviceEmulationRule = DeviceEmulationRule(emulationSpec)
+    private val screenshotRule =
+        ScreenshotTestRule(
+            SystemUIGoldenImagePathManager(getEmulatedDevicePathConfig(emulationSpec))
+        )
     private val activityRule = ActivityScenarioRule(ScreenshotActivity::class.java)
-    private val screenshotRule = ScreenshotTestRule(testSpec)
-
-    private val delegate = RuleChain.outerRule(screenshotRule).around(activityRule)
+    private val delegateRule =
+        RuleChain.outerRule(colorsRule)
+            .around(deviceEmulationRule)
+            .around(screenshotRule)
+            .around(activityRule)
+    private val matcher = UnitTestBitmapMatcher
 
     override fun apply(base: Statement, description: Description): Statement {
-        return delegate.apply(base, description)
+        return delegateRule.apply(base, description)
     }
 
     /**
      * Compare the content of the view provided by [viewProvider] with the golden image identified
-     * by [goldenIdentifier] in the context of [testSpec].
+     * by [goldenIdentifier] in the context of [emulationSpec].
      */
     fun screenshotTest(
         goldenIdentifier: String,
-        layoutParams: LayoutParams =
-            LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT),
-        viewProvider: (Activity) -> View,
+        mode: Mode = Mode.WrapContent,
+        viewProvider: (ComponentActivity) -> View,
     ) {
         activityRule.scenario.onActivity { activity ->
             // Make sure that the activity draws full screen and fits the whole display instead of
             // the system bars.
-            activity.window.setDecorFitsSystemWindows(false)
-            activity.setContentView(viewProvider(activity), layoutParams)
+            val window = activity.window
+            window.setDecorFitsSystemWindows(false)
+
+            // Set the content.
+            activity.setContentView(viewProvider(activity), mode.layoutParams)
+
+            // Elevation/shadows is not deterministic when doing hardware rendering, so we disable
+            // it for any view in the hierarchy.
+            window.decorView.removeElevationRecursively()
         }
 
         // We call onActivity again because it will make sure that our Activity is done measuring,
         // laying out and drawing its content (that we set in the previous onActivity lambda).
+        var contentView: View? = null
         activityRule.scenario.onActivity { activity ->
             // Check that the content is what we expected.
             val content = activity.requireViewById<ViewGroup>(android.R.id.content)
             assertEquals(1, content.childCount)
-            screenshotRule.screenshotTest(goldenIdentifier, content.getChildAt(0))
+            contentView = content.getChildAt(0)
         }
+
+        val bitmap = contentView?.toBitmap() ?: error("contentView is null")
+        screenshotRule.assertBitmapAgainstGolden(
+            bitmap,
+            goldenIdentifier,
+            matcher,
+        )
     }
 
     /**
      * Compare the content of the dialog provided by [dialogProvider] with the golden image
-     * identified by [goldenIdentifier] in the context of [testSpec].
+     * identified by [goldenIdentifier] in the context of [emulationSpec].
      */
     fun dialogScreenshotTest(
         goldenIdentifier: String,
@@ -60,21 +116,88 @@
     ) {
         var dialog: Dialog? = null
         activityRule.scenario.onActivity { activity ->
-            // Make sure that the dialog draws full screen and fits the whole display instead of the
-            // system bars.
             dialog =
                 dialogProvider(activity).apply {
+                    // Make sure that the dialog draws full screen and fits the whole display
+                    // instead of the system bars.
                     window.setDecorFitsSystemWindows(false)
+
+                    // Disable enter/exit animations.
+                    create()
+                    window.setWindowAnimations(0)
+
+                    // Elevation/shadows is not deterministic when doing hardware rendering, so we
+                    // disable it for any view in the hierarchy.
+                    window.decorView.removeElevationRecursively()
+
+                    // Show the dialog.
                     show()
                 }
         }
 
-        // We call onActivity again because it will make sure that our Dialog is done measuring,
-        // laying out and drawing its content (that we set in the previous onActivity lambda).
-        activityRule.scenario.onActivity {
-            // Check that the content is what we expected.
-            val dialog = dialog ?: error("dialog is null")
-            screenshotRule.screenshotTest(goldenIdentifier, dialog.window.decorView)
+        try {
+            val bitmap = dialog?.toBitmap() ?: error("dialog is null")
+            screenshotRule.assertBitmapAgainstGolden(
+                bitmap,
+                goldenIdentifier,
+                matcher,
+            )
+        } finally {
+            dialog?.dismiss()
         }
     }
+
+    private fun View.removeElevationRecursively() {
+        this.elevation = 0f
+
+        if (this is ViewGroup) {
+            repeat(childCount) { i -> getChildAt(i).removeElevationRecursively() }
+        }
+    }
+
+    private fun Dialog.toBitmap(): Bitmap {
+        val window = window
+        return window.decorView.toBitmap(window)
+    }
+
+    private fun View.toBitmap(window: Window? = null): Bitmap {
+        if (Looper.getMainLooper() == Looper.myLooper()) {
+            error("toBitmap() can't be called from the main thread")
+        }
+
+        if (!HardwareRenderer.isDrawingEnabled()) {
+            error("Hardware rendering is not enabled")
+        }
+
+        // Make sure we are idle.
+        Espresso.onIdle()
+
+        val mainExecutor = context.mainExecutor
+        return runBlocking {
+            suspendCoroutine { continuation ->
+                Futures.addCallback(
+                    captureToBitmap(window),
+                    object : FutureCallback<Bitmap> {
+                        override fun onSuccess(result: Bitmap?) {
+                            continuation.resumeWith(Result.success(result!!))
+                        }
+
+                        override fun onFailure(t: Throwable) {
+                            continuation.resumeWith(Result.failure(t))
+                        }
+                    },
+                    // We know that we are not on the main thread, so we can block the current
+                    // thread and wait for the result in the main thread.
+                    mainExecutor,
+                )
+            }
+        }
+    }
+
+    enum class Mode(val layoutParams: LayoutParams) {
+        WrapContent(LayoutParams(WRAP_CONTENT, WRAP_CONTENT)),
+        MatchSize(LayoutParams(MATCH_PARENT, MATCH_PARENT)),
+        MatchWidth(LayoutParams(MATCH_PARENT, WRAP_CONTENT)),
+        MatchHeight(LayoutParams(WRAP_CONTENT, MATCH_PARENT)),
+    }
 }
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/WindowCapture.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/WindowCapture.kt
new file mode 100644
index 0000000..d34f46b
--- /dev/null
+++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/WindowCapture.kt
@@ -0,0 +1,37 @@
+package com.android.systemui.testing.screenshot
+
+import android.graphics.Bitmap
+import android.graphics.Rect
+import android.os.Handler
+import android.os.Looper
+import android.view.PixelCopy
+import android.view.Window
+import androidx.concurrent.futures.ResolvableFuture
+
+/*
+ * This file was forked from androidx/test/core/view/WindowCapture.kt.
+ * TODO(b/195673633): Remove this fork and use the AndroidX version instead.
+ */
+fun Window.generateBitmapFromPixelCopy(
+    boundsInWindow: Rect? = null,
+    destBitmap: Bitmap,
+    bitmapFuture: ResolvableFuture<Bitmap>
+) {
+    val onCopyFinished =
+        PixelCopy.OnPixelCopyFinishedListener { result ->
+            if (result == PixelCopy.SUCCESS) {
+                bitmapFuture.set(destBitmap)
+            } else {
+                bitmapFuture.setException(
+                    RuntimeException(String.format("PixelCopy failed: %d", result))
+                )
+            }
+        }
+    PixelCopy.request(
+        this,
+        boundsInWindow,
+        destBitmap,
+        onCopyFinished,
+        Handler(Looper.getMainLooper())
+    )
+}
diff --git a/packages/SystemUI/shared/Android.bp b/packages/SystemUI/shared/Android.bp
index 18bd6b4..f59a320 100644
--- a/packages/SystemUI/shared/Android.bp
+++ b/packages/SystemUI/shared/Android.bp
@@ -59,6 +59,9 @@
     resource_dirs: [
         "res",
     ],
+    optimize: {
+        proguard_flags_files: ["proguard.flags"],
+    },
     java_version: "1.8",
     min_sdk_version: "current",
     plugins: ["dagger2-compiler"],
diff --git a/packages/SystemUI/shared/proguard.flags b/packages/SystemUI/shared/proguard.flags
new file mode 100644
index 0000000..5eda045
--- /dev/null
+++ b/packages/SystemUI/shared/proguard.flags
@@ -0,0 +1,4 @@
+# Retain signatures of TypeToken and its subclasses for gson usage in ClockRegistry
+-keepattributes Signature
+-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
+-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken
\ No newline at end of file
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
index 1d8abe3..3d72f15 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
@@ -26,6 +26,7 @@
 import com.android.systemui.plugins.ClockId
 import com.android.systemui.plugins.ClockMetadata
 import com.android.systemui.plugins.ClockProvider
+import com.android.systemui.plugins.RegionDarkness
 import com.android.systemui.shared.R
 import java.io.PrintWriter
 import java.util.Locale
@@ -68,8 +69,8 @@
  * AnimatableClockView used by the existing lockscreen clock.
  */
 class DefaultClock(
-    private val layoutInflater: LayoutInflater,
-    private val resources: Resources
+        private val layoutInflater: LayoutInflater,
+        private val resources: Resources
 ) : Clock {
     override val smallClock =
         layoutInflater.inflate(R.layout.clock_default_small, null) as AnimatableClockView
@@ -83,6 +84,19 @@
         resources.getFloat(R.dimen.keyguard_clock_line_spacing_scale_burmese)
     private val defaultLineSpacing = resources.getFloat(R.dimen.keyguard_clock_line_spacing_scale)
 
+    private var smallRegionDarkness = RegionDarkness.DEFAULT
+    private var largeRegionDarkness = RegionDarkness.DEFAULT
+
+    private fun updateClockColor(clock: AnimatableClockView, isRegionDark: RegionDarkness) {
+        val color = if (isRegionDark.isDark) {
+            resources.getColor(android.R.color.system_accent2_100)
+        } else {
+            resources.getColor(android.R.color.system_accent1_600)
+        }
+        clock.setColors(DOZE_COLOR, color)
+        clock.animateAppearOnLockscreen()
+    }
+
     override val events = object : ClockEvents {
         override fun onTimeTick() = clocks.forEach { it.refreshTime() }
 
@@ -104,9 +118,19 @@
             recomputePadding()
         }
 
-        override fun onColorPaletteChanged(resources: Resources) {
-            val color = resources.getColor(android.R.color.system_accent1_100)
-            clocks.forEach { it.setColors(DOZE_COLOR, color) }
+        override fun onColorPaletteChanged(
+                resources: Resources,
+                smallClockIsDark: RegionDarkness,
+                largeClockIsDark: RegionDarkness
+        ) {
+            if (smallRegionDarkness != smallClockIsDark) {
+                smallRegionDarkness = smallClockIsDark
+                updateClockColor(smallClock, smallClockIsDark)
+            }
+            if (largeRegionDarkness != largeClockIsDark) {
+                largeRegionDarkness = largeClockIsDark
+                updateClockColor(largeClock, largeClockIsDark)
+            }
         }
 
         override fun onLocaleChanged(locale: Locale) {
@@ -184,10 +208,18 @@
         clocks.forEach { it.setColors(DOZE_COLOR, DOZE_COLOR) }
     }
 
-    override fun initialize(resources: Resources, dozeFraction: Float, foldFraction: Float) {
+    override fun initialize(
+            resources: Resources,
+            dozeFraction: Float,
+            foldFraction: Float
+    ) {
         recomputePadding()
         animations = DefaultClockAnimations(dozeFraction, foldFraction)
-        events.onColorPaletteChanged(resources)
+        events.onColorPaletteChanged(
+                resources,
+                RegionDarkness.DEFAULT,
+                RegionDarkness.DEFAULT
+        )
         events.onTimeTick()
     }
 
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
index e9c1acb..e3f5687 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
@@ -18,6 +18,9 @@
 
 import static android.view.Display.DEFAULT_DISPLAY;
 
+import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
+import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
+
 import android.app.ActivityManager;
 import android.app.ActivityManager.TaskDescription;
 import android.app.TaskInfo;
@@ -31,6 +34,8 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.internal.util.ArrayUtils;
+
 import java.io.PrintWriter;
 import java.util.Objects;
 
@@ -242,8 +247,10 @@
         ActivityManager.TaskDescription td = taskInfo.taskDescription;
         return new Task(taskKey,
                 td != null ? td.getPrimaryColor() : 0,
-                td != null ? td.getBackgroundColor() : 0,
-                taskInfo.supportsMultiWindow, isLocked, td, taskInfo.topActivity);
+                td != null ? td.getBackgroundColor() : 0, taskInfo.supportsMultiWindow
+                && ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType())
+                && ArrayUtils.contains(CONTROLLED_WINDOWING_MODES, taskInfo.getWindowingMode()),
+                isLocked, td, taskInfo.topActivity);
     }
 
     public Task(TaskKey key) {
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSamplingInstance.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSamplingInstance.kt
new file mode 100644
index 0000000..bc5003e
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSamplingInstance.kt
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.shared.regionsampling
+
+import android.graphics.Rect
+import android.view.View
+import com.android.systemui.plugins.RegionDarkness
+import com.android.systemui.shared.navigationbar.RegionSamplingHelper
+import com.android.systemui.shared.navigationbar.RegionSamplingHelper.SamplingCallback
+import java.io.PrintWriter
+import java.util.concurrent.Executor
+
+/**
+ * Class for instance of RegionSamplingHelper
+ */
+class RegionSamplingInstance(
+        sampledView: View?,
+        mainExecutor: Executor?,
+        bgExecutor: Executor?,
+        regionSamplingEnabled: Boolean,
+        updateFun: UpdateColorCallback
+) {
+    private var isDark = RegionDarkness.DEFAULT
+    private var samplingBounds = Rect()
+    private var regionSampler: RegionSamplingHelper? = null
+
+    /**
+     * Interface for method to be passed into RegionSamplingHelper
+     */
+    @FunctionalInterface
+    interface UpdateColorCallback {
+        /**
+         * Method to update the text colors after clock darkness changed.
+         */
+        fun updateColors()
+    }
+
+    private fun convertToClockDarkness(isRegionDark: Boolean): RegionDarkness {
+        return if (isRegionDark) {
+            RegionDarkness.DARK
+        } else {
+            RegionDarkness.LIGHT
+        }
+    }
+
+    fun currentRegionDarkness(): RegionDarkness {
+        return isDark
+    }
+
+    /**
+     * Start region sampler
+     */
+    fun startRegionSampler() {
+        regionSampler?.start(samplingBounds)
+    }
+
+    /**
+     * Stop region sampler
+     */
+    fun stopRegionSampler() {
+        regionSampler?.stop()
+    }
+
+    /**
+     * Dump region sampler
+     */
+    fun dump(pw: PrintWriter) {
+        regionSampler?.dump(pw)
+    }
+
+    /**
+     * Restart
+     */
+    fun restart(sampledView: View?) {
+        regionSampler?.onViewAttachedToWindow(sampledView)
+    }
+
+    init {
+        if (regionSamplingEnabled && sampledView != null) {
+            regionSampler = RegionSamplingHelper(sampledView,
+                    object : SamplingCallback {
+                        override fun onRegionDarknessChanged(isRegionDark: Boolean) {
+                            isDark = convertToClockDarkness(isRegionDark)
+                            updateFun.updateColors()
+                        }
+
+                        override fun getSampledRegion(sampledView: View): Rect {
+                            samplingBounds = Rect(sampledView.left, sampledView.top,
+                                    sampledView.right, sampledView.bottom)
+                            return samplingBounds
+                        }
+
+                        override fun isSamplingEnabled(): Boolean {
+                            return regionSamplingEnabled
+                        }
+                    }, mainExecutor, bgExecutor)
+        }
+        regionSampler?.setWindowVisible(true)
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerKt.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerKt.kt
new file mode 100644
index 0000000..c142933
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerKt.kt
@@ -0,0 +1,32 @@
+/*
+ * 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 com.android.systemui.shared.system
+
+import android.app.ActivityManager
+
+/** Kotlin extensions for [ActivityManager] */
+object ActivityManagerKt {
+
+    /**
+     * Returns `true` whether the app with the given package name has an activity at the top of the
+     * most recent task; `false` otherwise
+     */
+    fun ActivityManager.isInForeground(packageName: String): Boolean {
+        val tasks: List<ActivityManager.RunningTaskInfo> = getRunningTasks(1)
+        return tasks.isNotEmpty() && packageName == tasks[0].topActivity.packageName
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
index c5beaa7..916526d 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
@@ -130,13 +130,6 @@
     }
 
     /**
-     * @return a list of the recents tasks.
-     */
-    public List<RecentTaskInfo> getRecentTasks(int numTasks, int userId) {
-        return mAtm.getRecentTasks(numTasks, RECENT_IGNORE_UNAVAILABLE, userId);
-    }
-
-    /**
      * @return a {@link ThumbnailData} with {@link TaskSnapshot} for the given {@param taskId}.
      *         The snapshot will be triggered if no cached {@link TaskSnapshot} exists.
      */
@@ -247,25 +240,6 @@
     }
 
     /**
-     * Starts a task from Recents.
-     *
-     * @param resultCallback The result success callback
-     * @param resultCallbackHandler The handler to receive the result callback
-     */
-    public void startActivityFromRecentsAsync(Task.TaskKey taskKey, ActivityOptions options,
-            Consumer<Boolean> resultCallback, Handler resultCallbackHandler) {
-        final boolean result = startActivityFromRecents(taskKey, options);
-        if (resultCallback != null) {
-            resultCallbackHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    resultCallback.accept(result);
-                }
-            });
-        }
-    }
-
-    /**
      * Starts a task from Recents synchronously.
      */
     public boolean startActivityFromRecents(Task.TaskKey taskKey, ActivityOptions options) {
@@ -286,20 +260,6 @@
     }
 
     /**
-     * @deprecated use {@link TaskStackChangeListeners#registerTaskStackListener}
-     */
-    public void registerTaskStackListener(TaskStackChangeListener listener) {
-        TaskStackChangeListeners.getInstance().registerTaskStackListener(listener);
-    }
-
-    /**
-     * @deprecated use {@link TaskStackChangeListeners#unregisterTaskStackListener}
-     */
-    public void unregisterTaskStackListener(TaskStackChangeListener listener) {
-        TaskStackChangeListeners.getInstance().unregisterTaskStackListener(listener);
-    }
-
-    /**
      * Requests that the system close any open system windows (including other SystemUI).
      */
     public void closeSystemWindows(final String reason) {
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java
index add2d02..be99b27 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java
@@ -28,14 +28,6 @@
 public abstract class ActivityOptionsCompat {
 
     /**
-     * @Deprecated
-     * @return ActivityOptions for starting a task in split screen as the primary window.
-     */
-    public static ActivityOptions makeSplitScreenOptions(boolean dockTopLeft) {
-        return ActivityOptions.makeBasic();
-    }
-
-    /**
      * @return ActivityOptions for starting a task in freeform.
      */
     public static ActivityOptions makeFreeformOptions() {
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
index 630fb36..97e0242 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
@@ -204,28 +204,6 @@
     }
 
     /**
-     * Touch slopes and thresholds for quick step operations. Drag slop is the point where the
-     * home button press/long press over are ignored and will start to drag when exceeded and the
-     * touch slop is when the respected operation will occur when exceeded. Touch slop must be
-     * larger than the drag slop.
-     */
-    public static int getQuickStepDragSlopPx() {
-        return convertDpToPixel(10);
-    }
-
-    public static int getQuickStepTouchSlopPx() {
-        return convertDpToPixel(24);
-    }
-
-    public static int getQuickScrubTouchSlopPx() {
-        return convertDpToPixel(24);
-    }
-
-    private static int convertDpToPixel(float dp) {
-        return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
-    }
-
-    /**
      * Returns whether the specified sysui state is such that the assistant gesture should be
      * disabled.
      */
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
index 13f1db4a..0094820 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
@@ -65,14 +65,6 @@
         }
     }
 
-    public void hideCurrentInputMethod() {
-        try {
-            mAnimationController.hideCurrentInputMethod();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to set hide input method", e);
-        }
-    }
-
     /**
      * Sets the final surface transaction on a Task. This is used by Launcher to notify the system
      * that animating Activity to PiP has completed and the associated task surface should be
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
index db41601..609846e 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
@@ -224,6 +224,7 @@
         private WindowContainerToken mRecentsTask = null;
         private TransitionInfo mInfo = null;
         private ArrayList<SurfaceControl> mOpeningLeashes = null;
+        private boolean mOpeningHome = false;
         private ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = null;
         private PictureInPictureSurfaceTransaction mPipTransaction = null;
         private IBinder mTransition = null;
@@ -321,6 +322,7 @@
             }
             final int layer = mInfo.getChanges().size() * 3;
             mOpeningLeashes = new ArrayList<>();
+            mOpeningHome = cancelRecents;
             final RemoteAnimationTargetCompat[] targets =
                     new RemoteAnimationTargetCompat[openingTasks.size()];
             for (int i = 0; i < openingTasks.size(); ++i) {
@@ -367,10 +369,6 @@
             if (mWrapped != null) mWrapped.setAnimationTargetsBehindSystemBars(behindSystemBars);
         }
 
-        @Override public void hideCurrentInputMethod() {
-            mWrapped.hideCurrentInputMethod();
-        }
-
         @Override public void setFinishTaskTransaction(int taskId,
                 PictureInPictureSurfaceTransaction finishTransaction, SurfaceControl overlay) {
             mPipTransaction = finishTransaction;
@@ -406,6 +404,26 @@
                 if (!mKeyguardLocked && mRecentsTask != null) {
                     wct.restoreTransientOrder(mRecentsTask);
                 }
+            } else if (toHome && mOpeningHome && mPausingTasks != null) {
+                // Special situaition where 3p launcher was changed during recents (this happens
+                // during tapltests...). Here we get both "return to home" AND "home opening".
+                // This is basically going home, but we have to restore recents order and also
+                // treat the home "pausing" task properly.
+                for (int i = mPausingTasks.size() - 1; i >= 0; --i) {
+                    final TransitionInfo.Change change = mInfo.getChange(mPausingTasks.get(i));
+                    final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
+                    if (taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
+                        // Treat as opening (see above)
+                        wct.reorder(mPausingTasks.get(i), true /* onTop */);
+                        t.show(mInfo.getChange(mPausingTasks.get(i)).getLeash());
+                    } else {
+                        // Treat as hiding (see below)
+                        t.hide(mInfo.getChange(mPausingTasks.get(i)).getLeash());
+                    }
+                }
+                if (!mKeyguardLocked && mRecentsTask != null) {
+                    wct.restoreTransientOrder(mRecentsTask);
+                }
             } else {
                 for (int i = 0; i < mPausingTasks.size(); ++i) {
                     if (!sendUserLeaveHint) {
@@ -427,18 +445,14 @@
                     mPipTransaction = null;
                 }
             }
-            // Release surface references now. This is apparently to free GPU
-            // memory while doing quick operations (eg. during CTS).
-            for (int i = 0; i < mLeashMap.size(); ++i) {
-                if (mLeashMap.keyAt(i) == mLeashMap.valueAt(i)) continue;
-                t.remove(mLeashMap.valueAt(i));
-            }
             try {
                 mFinishCB.onTransitionFinished(wct.isEmpty() ? null : wct, t);
             } catch (RemoteException e) {
                 Log.e("RemoteTransitionCompat", "Failed to call animation finish callback", e);
                 t.apply();
             }
+            // Only release the non-local created surface references. The animator is responsible
+            // for releasing the leashes created by local.
             for (int i = 0; i < mInfo.getChanges().size(); ++i) {
                 mInfo.getChanges().get(i).getLeash().release();
             }
@@ -448,6 +462,7 @@
             mPausingTasks = null;
             mInfo = null;
             mOpeningLeashes = null;
+            mOpeningHome = false;
             mLeashMap = null;
             mTransition = null;
         }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java
deleted file mode 100644
index 359d369..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.shared.system;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.SurfaceView;
-
-/** Utility class that is shared between SysUI and Launcher for Universal Smartspace features. */
-public final class UniversalSmartspaceUtils {
-    public static final String ACTION_REQUEST_SMARTSPACE_VIEW =
-            "com.android.systemui.REQUEST_SMARTSPACE_VIEW";
-    public static final String INTENT_BUNDLE_KEY = "bundle_key";
-
-    private static final String SYSUI_PACKAGE = "com.android.systemui";
-
-    /** Creates an intent to request that sysui draws the Smartspace to the SurfaceView. */
-    public static Intent createRequestSmartspaceIntent(SurfaceView surfaceView) {
-        Intent intent = new Intent(ACTION_REQUEST_SMARTSPACE_VIEW);
-
-        Bundle bundle = SurfaceViewRequestUtils.createSurfaceBundle(surfaceView);
-        return intent
-                .putExtra(INTENT_BUNDLE_KEY, bundle)
-                .setPackage(SYSUI_PACKAGE)
-                .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
-                        | Intent.FLAG_RECEIVER_FOREGROUND);
-    }
-
-    private UniversalSmartspaceUtils() {}
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
index b894b10..5577513 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
@@ -114,30 +114,6 @@
     }
 
     /**
-     *  Sets if app requested fixed orientation should be ignored for given displayId.
-     */
-    public void setIgnoreOrientationRequest(int displayId, boolean ignoreOrientationRequest) {
-        try {
-            WindowManagerGlobal.getWindowManagerService().setIgnoreOrientationRequest(
-                    displayId, ignoreOrientationRequest);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to setIgnoreOrientationRequest()", e);
-        }
-    }
-
-    /**
-     * @return the stable insets for the primary display.
-     */
-    public void getStableInsets(Rect outStableInsets) {
-        try {
-            WindowManagerGlobal.getWindowManagerService().getStableInsets(DEFAULT_DISPLAY,
-                    outStableInsets);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to get stable insets", e);
-        }
-    }
-
-    /**
      * Overrides a pending app transition.
      */
     public void overridePendingAppTransitionMultiThumbFuture(
@@ -153,16 +129,6 @@
         }
     }
 
-    public void overridePendingAppTransitionRemote(
-            RemoteAnimationAdapterCompat remoteAnimationAdapter, int displayId) {
-        try {
-            WindowManagerGlobal.getWindowManagerService().overridePendingAppTransitionRemote(
-                    remoteAnimationAdapter.getWrapped(), displayId);
-        } catch (RemoteException e) {
-            Log.w(TAG, "Failed to override pending app transition (remote): ", e);
-        }
-    }
-
     /**
      * Enable or disable haptic feedback on the navigation bar buttons.
      */
@@ -175,19 +141,6 @@
         }
     }
 
-    public void setRecentsVisibility(boolean visible) {
-        try {
-            WindowManagerGlobal.getWindowManagerService().setRecentsVisibility(visible);
-        } catch (RemoteException e) {
-            Log.w(TAG, "Failed to set recents visibility");
-        }
-    }
-
-    @Deprecated
-    public void setPipVisibility(final boolean visible) {
-        // To be removed
-    }
-
     /**
      * @param displayId the id of display to check if there is a software navigation bar.
      *
@@ -202,22 +155,6 @@
     }
 
     /**
-     * @return The side of the screen where navigation bar is positioned.
-     * @see #NAV_BAR_POS_RIGHT
-     * @see #NAV_BAR_POS_LEFT
-     * @see #NAV_BAR_POS_BOTTOM
-     * @see #NAV_BAR_POS_INVALID
-     */
-    public int getNavBarPosition(int displayId) {
-        try {
-            return WindowManagerGlobal.getWindowManagerService().getNavBarPosition(displayId);
-        } catch (RemoteException e) {
-            Log.w(TAG, "Failed to get nav bar position");
-        }
-        return NAV_BAR_POS_INVALID;
-    }
-
-    /**
      * Mirrors a specified display. The SurfaceControl returned is the root of the mirrored
      * hierarchy.
      *
diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
index efd7bcf..0d1158c 100644
--- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
@@ -22,15 +22,19 @@
 import android.content.res.Resources
 import android.text.format.DateFormat
 import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.plugins.Clock
 import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.shared.regionsampling.RegionSamplingInstance
 import com.android.systemui.statusbar.policy.BatteryController
 import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback
 import com.android.systemui.statusbar.policy.ConfigurationController
 import java.io.PrintWriter
 import java.util.Locale
 import java.util.TimeZone
+import java.util.concurrent.Executor
 import javax.inject.Inject
 
 /**
@@ -38,19 +42,23 @@
  * [KeyguardClockSwitchController]. Functionality is forked from [AnimatableClockController].
  */
 class ClockEventController @Inject constructor(
-    private val statusBarStateController: StatusBarStateController,
-    private val broadcastDispatcher: BroadcastDispatcher,
-    private val batteryController: BatteryController,
-    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
-    private val configurationController: ConfigurationController,
-    @Main private val resources: Resources,
-    private val context: Context
+        private val statusBarStateController: StatusBarStateController,
+        private val broadcastDispatcher: BroadcastDispatcher,
+        private val batteryController: BatteryController,
+        private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
+        private val configurationController: ConfigurationController,
+        @Main private val resources: Resources,
+        private val context: Context,
+        @Main private val mainExecutor: Executor,
+        @Background private val bgExecutor: Executor,
+        private val featureFlags: FeatureFlags
 ) {
     var clock: Clock? = null
         set(value) {
             field = value
             if (value != null) {
                 value.initialize(resources, dozeAmount, 0f)
+                updateRegionSamplers(value)
             }
         }
 
@@ -61,9 +69,66 @@
     private var dozeAmount = 0f
     private var isKeyguardShowing = false
 
+    private val regionSamplingEnabled =
+            featureFlags.isEnabled(com.android.systemui.flags.Flags.REGION_SAMPLING)
+
+    private val updateFun = object : RegionSamplingInstance.UpdateColorCallback {
+        override fun updateColors() {
+            smallClockIsDark = smallRegionSamplingInstance.currentRegionDarkness()
+            largeClockIsDark = largeRegionSamplingInstance.currentRegionDarkness()
+
+            clock?.events?.onColorPaletteChanged(resources, smallClockIsDark, largeClockIsDark)
+        }
+    }
+
+    fun updateRegionSamplers(currentClock: Clock?) {
+        smallRegionSamplingInstance.stopRegionSampler()
+        largeRegionSamplingInstance.stopRegionSampler()
+
+        smallRegionSamplingInstance = RegionSamplingInstance(
+                currentClock?.smallClock,
+                mainExecutor,
+                bgExecutor,
+                regionSamplingEnabled,
+                updateFun
+        )
+
+        largeRegionSamplingInstance = RegionSamplingInstance(
+                currentClock?.largeClock,
+                mainExecutor,
+                bgExecutor,
+                regionSamplingEnabled,
+                updateFun
+        )
+
+        smallRegionSamplingInstance.startRegionSampler()
+        largeRegionSamplingInstance.startRegionSampler()
+
+        updateFun.updateColors()
+    }
+
+    var smallRegionSamplingInstance: RegionSamplingInstance = RegionSamplingInstance(
+            clock?.smallClock,
+            mainExecutor,
+            bgExecutor,
+            regionSamplingEnabled,
+            updateFun
+    )
+
+    var largeRegionSamplingInstance: RegionSamplingInstance = RegionSamplingInstance(
+            clock?.largeClock,
+            mainExecutor,
+            bgExecutor,
+            regionSamplingEnabled,
+            updateFun
+    )
+
+    private var smallClockIsDark = smallRegionSamplingInstance.currentRegionDarkness()
+    private var largeClockIsDark = largeRegionSamplingInstance.currentRegionDarkness()
+
     private val configListener = object : ConfigurationController.ConfigurationListener {
         override fun onThemeChanged() {
-            clock?.events?.onColorPaletteChanged(resources)
+            updateFun.updateColors()
         }
     }
 
@@ -114,6 +179,7 @@
 
     init {
         isDozing = statusBarStateController.isDozing
+        clock?.events?.onColorPaletteChanged(resources, smallClockIsDark, largeClockIsDark)
     }
 
     fun registerListeners() {
@@ -128,6 +194,8 @@
         batteryController.addCallback(batteryCallback)
         keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
         statusBarStateController.addCallback(statusBarStateListener)
+        smallRegionSamplingInstance.startRegionSampler()
+        largeRegionSamplingInstance.startRegionSampler()
     }
 
     fun unregisterListeners() {
@@ -136,6 +204,8 @@
         batteryController.removeCallback(batteryCallback)
         keyguardUpdateMonitor.removeCallback(keyguardUpdateMonitorCallback)
         statusBarStateController.removeCallback(statusBarStateListener)
+        smallRegionSamplingInstance.stopRegionSampler()
+        largeRegionSamplingInstance.stopRegionSampler()
     }
 
     /**
@@ -144,6 +214,8 @@
     fun dump(pw: PrintWriter) {
         pw.println(this)
         clock?.dump(pw)
+        smallRegionSamplingInstance.dump(pw)
+        largeRegionSamplingInstance.dump(pw)
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
index 12fa401..d32219a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
@@ -336,6 +336,11 @@
         mKeyguardSecurityContainerController.onStartingToHide();
     }
 
+    /** Called when bouncer visibility changes. */
+    public void onBouncerVisibilityChanged(@View.Visibility int visibility) {
+        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(visibility);
+    }
+
     public boolean hasDismissActions() {
         return mDismissAction != null || mCancelAction != null;
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
index db2b4ac..58e0fb96 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
@@ -58,7 +58,6 @@
     val keyguardAwake: Boolean,
     val keyguardGoingAway: Boolean,
     val listeningForFaceAssistant: Boolean,
-    val lockIconPressed: Boolean,
     val occludingAppRequestingFaceAuth: Boolean,
     val primaryUser: Boolean,
     val scanningAllowedByStrongAuth: Boolean,
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index 61e2624..5ee659b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -17,6 +17,7 @@
 package com.android.keyguard;
 
 import static android.app.StatusBarManager.SESSION_KEYGUARD;
+import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
 
 import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_BIOMETRIC;
 import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_EXTENDED_ACCESS;
@@ -32,11 +33,13 @@
 import android.content.Intent;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
+import android.hardware.biometrics.BiometricSourceType;
 import android.metrics.LogMaker;
 import android.os.UserHandle;
 import android.util.Log;
 import android.util.Slog;
 import android.view.MotionEvent;
+import android.view.View;
 
 import androidx.annotation.Nullable;
 
@@ -55,6 +58,7 @@
 import com.android.settingslib.utils.ThreadUtils;
 import com.android.systemui.Gefingerpoken;
 import com.android.systemui.R;
+import com.android.systemui.biometrics.SidefpsController;
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
@@ -67,6 +71,8 @@
 import com.android.systemui.util.ViewController;
 import com.android.systemui.util.settings.GlobalSettings;
 
+import java.util.Optional;
+
 import javax.inject.Inject;
 
 /** Controller for {@link KeyguardSecurityContainer} */
@@ -93,6 +99,7 @@
     private final GlobalSettings mGlobalSettings;
     private final FeatureFlags mFeatureFlags;
     private final SessionTracker mSessionTracker;
+    private final Optional<SidefpsController> mSidefpsController;
 
     private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED;
 
@@ -236,13 +243,27 @@
                     reloadColors();
                 }
             };
+    private boolean mBouncerVisible = false;
     private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback =
             new KeyguardUpdateMonitorCallback() {
-        @Override
-        public void onDevicePolicyManagerStateChanged() {
-            showPrimarySecurityScreen(false);
-        }
-    };
+                @Override
+                public void onDevicePolicyManagerStateChanged() {
+                    showPrimarySecurityScreen(false);
+                }
+
+                @Override
+                public void onBiometricRunningStateChanged(boolean running,
+                        BiometricSourceType biometricSourceType) {
+                    if (biometricSourceType == FINGERPRINT) {
+                        updateSideFpsVisibility();
+                    }
+                }
+
+                @Override
+                public void onStrongAuthStateChanged(int userId) {
+                    updateSideFpsVisibility();
+                }
+            };
 
     private KeyguardSecurityContainerController(KeyguardSecurityContainer view,
             AdminSecondaryLockScreenController.Factory adminSecondaryLockScreenControllerFactory,
@@ -260,7 +281,8 @@
             UserSwitcherController userSwitcherController,
             FeatureFlags featureFlags,
             GlobalSettings globalSettings,
-            SessionTracker sessionTracker) {
+            SessionTracker sessionTracker,
+            Optional<SidefpsController> sidefpsController) {
         super(view);
         mLockPatternUtils = lockPatternUtils;
         mUpdateMonitor = keyguardUpdateMonitor;
@@ -280,6 +302,7 @@
         mFeatureFlags = featureFlags;
         mGlobalSettings = globalSettings;
         mSessionTracker = sessionTracker;
+        mSidefpsController = sidefpsController;
     }
 
     @Override
@@ -311,8 +334,23 @@
             getCurrentSecurityController().onPause();
         }
         mView.onPause();
+        // It might happen that onStartingToHide is not called when the device is locked while on
+        // bouncer.
+        setBouncerVisible(false);
     }
 
+    private void updateSideFpsVisibility() {
+        if (!mSidefpsController.isPresent()) {
+            return;
+        }
+        if (mBouncerVisible && mView.isSidedSecurityMode()
+                && mUpdateMonitor.isFingerprintDetectionRunning()
+                && !mUpdateMonitor.userNeedsStrongAuth()) {
+            mSidefpsController.get().show();
+        } else {
+            mSidefpsController.get().hide();
+        }
+    }
 
     /**
      * Shows the primary security screen for the user. This will be either the multi-selector
@@ -397,6 +435,17 @@
         if (mCurrentSecurityMode != SecurityMode.None) {
             getCurrentSecurityController().onStartingToHide();
         }
+        setBouncerVisible(false);
+    }
+
+    /** Called when the bouncer changes visibility. */
+    public void onBouncerVisibilityChanged(@View.Visibility int visibility) {
+        setBouncerVisible(visibility == View.VISIBLE);
+    }
+
+    private void setBouncerVisible(boolean visible) {
+        mBouncerVisible = visible;
+        updateSideFpsVisibility();
     }
 
     /**
@@ -655,6 +704,7 @@
         private final FeatureFlags mFeatureFlags;
         private final UserSwitcherController mUserSwitcherController;
         private final SessionTracker mSessionTracker;
+        private final Optional<SidefpsController> mSidefpsController;
 
         @Inject
         Factory(KeyguardSecurityContainer view,
@@ -673,7 +723,8 @@
                 UserSwitcherController userSwitcherController,
                 FeatureFlags featureFlags,
                 GlobalSettings globalSettings,
-                SessionTracker sessionTracker) {
+                SessionTracker sessionTracker,
+                Optional<SidefpsController> sidefpsController) {
             mView = view;
             mAdminSecondaryLockScreenControllerFactory = adminSecondaryLockScreenControllerFactory;
             mLockPatternUtils = lockPatternUtils;
@@ -690,6 +741,7 @@
             mGlobalSettings = globalSettings;
             mUserSwitcherController = userSwitcherController;
             mSessionTracker = sessionTracker;
+            mSidefpsController = sidefpsController;
         }
 
         public KeyguardSecurityContainerController create(
@@ -699,7 +751,8 @@
                     mKeyguardUpdateMonitor, mKeyguardSecurityModel, mMetricsLogger, mUiEventLogger,
                     mKeyguardStateController, securityCallback, mSecurityViewFlipperController,
                     mConfigurationController, mFalsingCollector, mFalsingManager,
-                    mUserSwitcherController, mFeatureFlags, mGlobalSettings, mSessionTracker);
+                    mUserSwitcherController, mFeatureFlags, mGlobalSettings, mSessionTracker,
+                    mSidefpsController);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index de5de32..758ec54 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -41,7 +41,6 @@
 import android.app.ActivityTaskManager;
 import android.app.ActivityTaskManager.RootTaskInfo;
 import android.app.AlarmManager;
-import android.app.PendingIntent;
 import android.app.UserSwitchObserver;
 import android.app.admin.DevicePolicyManager;
 import android.app.trust.TrustManager;
@@ -149,11 +148,6 @@
     private static final boolean DEBUG_SPEW = false;
     private static final int BIOMETRIC_LOCKOUT_RESET_DELAY_MS = 600;
 
-    private static final String ACTION_FACE_UNLOCK_STARTED
-            = "com.android.facelock.FACE_UNLOCK_STARTED";
-    private static final String ACTION_FACE_UNLOCK_STOPPED
-            = "com.android.facelock.FACE_UNLOCK_STOPPED";
-
     // Callback messages
     private static final int MSG_TIME_UPDATE = 301;
     private static final int MSG_BATTERY_UPDATE = 302;
@@ -164,13 +158,11 @@
     private static final int MSG_USER_SWITCHING = 310;
     private static final int MSG_KEYGUARD_RESET = 312;
     private static final int MSG_USER_SWITCH_COMPLETE = 314;
-    private static final int MSG_USER_INFO_CHANGED = 317;
     private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
     private static final int MSG_STARTED_WAKING_UP = 319;
     private static final int MSG_FINISHED_GOING_TO_SLEEP = 320;
     private static final int MSG_STARTED_GOING_TO_SLEEP = 321;
     private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
-    private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327;
     private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328;
     private static final int MSG_AIRPLANE_MODE_CHANGED = 329;
     private static final int MSG_SERVICE_STATE_CHANGE = 330;
@@ -234,7 +226,6 @@
 
     private final Context mContext;
     private final boolean mIsPrimaryUser;
-    private final boolean mIsAutomotive;
     private final AuthController mAuthController;
     private final StatusBarStateController mStatusBarStateController;
     private int mStatusBarState;
@@ -312,8 +303,6 @@
     private final LatencyTracker mLatencyTracker;
     private boolean mLogoutEnabled;
     private boolean mIsFaceEnrolled;
-    // If the user long pressed the lock icon, disabling face auth for the current session.
-    private boolean mLockIconPressed;
     private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
     private final Executor mBackgroundExecutor;
     private SensorPrivacyManager mSensorPrivacyManager;
@@ -392,7 +381,6 @@
     private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
     private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
     private SparseBooleanArray mUserTrustIsUsuallyManaged = new SparseBooleanArray();
-    private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
     private Map<Integer, Intent> mSecondaryLockscreenRequirement = new HashMap<Integer, Intent>();
 
     @VisibleForTesting
@@ -801,8 +789,8 @@
     private Runnable mRetryFingerprintAuthentication = new Runnable() {
         @Override
         public void run() {
-            Log.w(TAG, "Retrying fingerprint after HW unavailable, attempt " +
-                    mHardwareFingerprintUnavailableRetryCount);
+            Log.w(TAG,
+                    "Retrying fingerprint attempt: " + mHardwareFingerprintUnavailableRetryCount);
             if (mFpm.isHardwareDetected()) {
                 updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
             } else if (mHardwareFingerprintUnavailableRetryCount < HAL_ERROR_RETRY_MAX) {
@@ -829,7 +817,9 @@
             setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
         }
 
-        if (msgId == FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE) {
+        if (msgId == FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE
+                || msgId == FingerprintManager.BIOMETRIC_ERROR_POWER_PRESSED) {
+            Log.d(TAG, "Fingerprint retrying auth due to(" + msgId + ") -> " + errString);
             mHandler.postDelayed(mRetryFingerprintAuthentication, HAL_ERROR_RETRY_TIMEOUT);
         }
 
@@ -1119,21 +1109,6 @@
         }
     }
 
-    private void handleFaceUnlockStateChanged(boolean running, int userId) {
-        Assert.isMainThread();
-        mUserFaceUnlockRunning.put(userId, running);
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-            if (cb != null) {
-                cb.onFaceUnlockStateChanged(running, userId);
-            }
-        }
-    }
-
-    public boolean isFaceUnlockRunning(int userId) {
-        return mUserFaceUnlockRunning.get(userId);
-    }
-
     public boolean isFingerprintDetectionRunning() {
         return mFingerprintRunningState == BIOMETRIC_STATE_RUNNING;
     }
@@ -1357,16 +1332,6 @@
         }
     }
 
-    static class DisplayClientState {
-        public int clientGeneration;
-        public boolean clearing;
-        public PendingIntent intent;
-        public int playbackState;
-        public long playbackEventTime;
-    }
-
-    private DisplayClientState mDisplayClientState = new DisplayClientState();
-
     @VisibleForTesting
     protected final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
 
@@ -1440,19 +1405,6 @@
             final String action = intent.getAction();
             if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
                 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
-            } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
-                mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
-                        intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
-            } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
-                Trace.beginSection(
-                        "KeyguardUpdateMonitor.mBroadcastAllReceiver#onReceive "
-                                + "ACTION_FACE_UNLOCK_STARTED");
-                mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
-                        getSendingUserId()));
-                Trace.endSection();
-            } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
-                mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
-                        getSendingUserId()));
             } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
                     .equals(action)) {
                 mHandler.sendMessage(mHandler.obtainMessage(MSG_DPM_STATE_CHANGED,
@@ -1751,7 +1703,6 @@
 
     protected void handleStartedGoingToSleep(int arg1) {
         Assert.isMainThread();
-        mLockIconPressed = false;
         clearBiometricRecognized();
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -1799,16 +1750,6 @@
         }
     }
 
-    private void handleUserInfoChanged(int userId) {
-        Assert.isMainThread();
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-            if (cb != null) {
-                cb.onUserInfoChanged(userId);
-            }
-        }
-    }
-
     private void handleUserUnlocked(int userId) {
         Assert.isMainThread();
         mUserIsUnlocked.put(userId, true);
@@ -1926,9 +1867,6 @@
                     case MSG_KEYGUARD_BOUNCER_CHANGED:
                         handleKeyguardBouncerChanged(msg.arg1, msg.arg2);
                         break;
-                    case MSG_USER_INFO_CHANGED:
-                        handleUserInfoChanged(msg.arg1);
-                        break;
                     case MSG_REPORT_EMERGENCY_CALL_ACTION:
                         handleReportEmergencyCallAction();
                         break;
@@ -1943,12 +1881,6 @@
                         handleStartedWakingUp();
                         Trace.endSection();
                         break;
-                    case MSG_FACE_UNLOCK_STATE_CHANGED:
-                        Trace.beginSection(
-                                "KeyguardUpdateMonitor#handler MSG_FACE_UNLOCK_STATE_CHANGED");
-                        handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
-                        Trace.endSection();
-                        break;
                     case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
                         handleSimSubscriptionInfoChanged();
                         break;
@@ -2036,24 +1968,10 @@
                     .getServiceStateForSubscriber(subId);
             mHandler.sendMessage(
                     mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
-
-            // Get initial state. Relying on Sticky behavior until API for getting info.
-            if (mBatteryStatus == null) {
-                Intent intent = mContext.registerReceiver(
-                        null,
-                        new IntentFilter(Intent.ACTION_BATTERY_CHANGED)
-                );
-                if (intent != null && mBatteryStatus == null) {
-                    mBroadcastReceiver.onReceive(mContext, intent);
-                }
-            }
         });
 
         final IntentFilter allUserFilter = new IntentFilter();
-        allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
         allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
-        allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
-        allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
         allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
         allUserFilter.addAction(ACTION_USER_UNLOCKED);
         allUserFilter.addAction(ACTION_USER_STOPPED);
@@ -2111,8 +2029,6 @@
             mFaceManager.addLockoutResetCallback(mFaceLockoutResetCallback);
         }
 
-        mIsAutomotive = isAutomotive();
-
         TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
         mUserManager = context.getSystemService(UserManager.class);
         mIsPrimaryUser = mUserManager.isPrimaryUser();
@@ -2613,7 +2529,7 @@
                         || mAuthController.isUdfpsFingerDown()
                         || mUdfpsBouncerShowing)
                 && !mSwitchingUser && !faceDisabledForUser && becauseCannotSkipBouncer
-                && !mKeyguardGoingAway && biometricEnabledForUser && !mLockIconPressed
+                && !mKeyguardGoingAway && biometricEnabledForUser
                 && strongAuthAllowsScanning && mIsPrimaryUser
                 && (!mSecureCameraLaunched || mOccludingAppRequestingFace)
                 && !faceAuthenticated
@@ -2636,7 +2552,6 @@
                         awakeKeyguard,
                         mKeyguardGoingAway,
                         shouldListenForFaceAssistant,
-                        mLockIconPressed,
                         mOccludingAppRequestingFace,
                         mIsPrimaryUser,
                         strongAuthAllowsScanning,
@@ -2681,18 +2596,6 @@
         }
     }
 
-    /**
-     * Whenever the lock icon is long pressed, disabling trust agents.
-     * This means that we cannot auth passively (face) until the user presses power.
-     */
-    public void onLockIconPressed() {
-        mLockIconPressed = true;
-        final int userId = getCurrentUser();
-        mUserFaceAuthenticated.put(userId, null);
-        updateFaceListeningState(BIOMETRIC_ACTION_UPDATE);
-        mStrongAuthTracker.onStrongAuthRequiredChanged(userId);
-    }
-
     private void startListeningForFingerprint() {
         final int userId = getCurrentUser();
         final boolean unlockPossible = isUnlockWithFingerprintPossible(userId);
@@ -3163,20 +3066,6 @@
         updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
     }
 
-    /** Notifies that the occluded state changed. */
-    public void onKeyguardOccludedChanged(boolean occluded) {
-        Assert.isMainThread();
-        if (DEBUG) {
-            Log.d(TAG, "onKeyguardOccludedChanged(" + occluded + ")");
-        }
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-            if (cb != null) {
-                cb.onKeyguardOccludedChanged(occluded);
-            }
-        }
-    }
-
     /**
      * Handle {@link #MSG_KEYGUARD_RESET}
      */
@@ -3331,10 +3220,6 @@
         return false;
     }
 
-    private boolean isAutomotive() {
-        return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
-    }
-
     /**
      * Remove the given observer's callback.
      *
@@ -3397,8 +3282,6 @@
         callback.onTimeChanged();
         callback.onPhoneStateChanged(mPhoneState);
         callback.onRefreshCarrierInfo();
-        callback.onClockVisibilityChanged();
-        callback.onKeyguardOccludedChanged(mKeyguardOccluded);
         callback.onKeyguardVisibilityChangedRaw(mKeyguardIsVisible);
         callback.onTelephonyCapable(mTelephonyCapable);
 
@@ -3575,10 +3458,6 @@
                 || state == TelephonyManager.SIM_STATE_PERM_DISABLED);
     }
 
-    public DisplayClientState getCachedDisplayClientState() {
-        return mDisplayClientState;
-    }
-
     // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
     // (KeyguardViewMediator, KeyguardHostView)
     public void dispatchStartedWakingUp() {
@@ -3807,9 +3686,5 @@
             pw.println("    mNeedsSlowUnlockTransition=" + mNeedsSlowUnlockTransition);
         }
         mListenModels.print(pw);
-
-        if (mIsAutomotive) {
-            pw.println("  Running on Automotive build");
-        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 051b81e..99e0ce2 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -80,12 +80,6 @@
      */
     public void onKeyguardVisibilityChanged(boolean showing) { }
 
-    /**
-     * Called when the keyguard occluded state changes.
-     * @param occluded Indicates if the keyguard is now occluded.
-     */
-    public void onKeyguardOccludedChanged(boolean occluded) { }
-
     public void onKeyguardVisibilityChangedRaw(boolean showing) {
         final long now = SystemClock.elapsedRealtime();
         if (showing == mShowing
@@ -117,12 +111,6 @@
     public void onKeyguardDismissAnimationFinished() { }
 
     /**
-     * Called when visibility of lockscreen clock changes, such as when
-     * obscured by a widget.
-     */
-    public void onClockVisibilityChanged() { }
-
-    /**
      * Called when the device becomes provisioned
      */
     public void onDeviceProvisioned() { }
@@ -151,11 +139,6 @@
     public void onSimStateChanged(int subId, int slotId, int simState) { }
 
     /**
-     * Called when the user's info changed.
-     */
-    public void onUserInfoChanged(int userId) { }
-
-    /**
      * Called when a user got unlocked.
      */
     public void onUserUnlocked() { }
@@ -260,11 +243,6 @@
             BiometricSourceType biometricSourceType) { }
 
     /**
-     * Called when the state of face unlock changed.
-     */
-    public void onFaceUnlockStateChanged(boolean running, int userId) { }
-
-    /**
      * Called when biometric running state changed.
      */
     public void onBiometricRunningStateChanged(boolean running,
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java
index ca8728a..8293c74 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java
@@ -23,10 +23,10 @@
 import androidx.annotation.Nullable;
 
 import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.phone.NotificationPanelViewController;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
 
 /**
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index c1b2aba..06e1828 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -23,7 +23,6 @@
 import static com.android.keyguard.LockIconView.ICON_UNLOCK;
 import static com.android.systemui.classifier.Classifier.LOCK_ICON;
 import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
-import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInProgressOffset;
 
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -403,7 +402,6 @@
         float offsetY = MathUtils.lerp(0f,
                 getBurnInOffset(mMaxBurnInOffsetY * 2, false /* xAxis */)
                         - mMaxBurnInOffsetY, mInterpolatedDarkAmount);
-        float progress = MathUtils.lerp(0f, getBurnInProgressOffset(), mInterpolatedDarkAmount);
 
         mView.setTranslationX(offsetX);
         mView.setTranslationY(offsetY);
@@ -652,7 +650,7 @@
                 Process.myUid(),
                 getContext().getOpPackageName(),
                 UdfpsController.EFFECT_CLICK,
-                "lock-icon-device-entry",
+                "lock-screen-lock-icon-longpress",
                 TOUCH_VIBRATION_ATTRIBUTES);
 
         mKeyguardViewController.showBouncer(/* scrim */ true);
@@ -677,6 +675,12 @@
     }
 
     private boolean isActionable() {
+        if (mIsBouncerShowing) {
+            Log.v(TAG, "lock icon long-press ignored, bouncer already showing.");
+            // a long press gestures from AOD may have already triggered the bouncer to show,
+            // so this touch is no longer actionable
+            return false;
+        }
         return mUdfpsSupported || mShowUnlockIcon;
     }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java
index b3c1158..49e9783 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java
@@ -16,6 +16,10 @@
 
 package com.android.keyguard.dagger;
 
+import static com.android.systemui.biometrics.SidefpsControllerKt.hasSideFpsSensor;
+
+import android.annotation.Nullable;
+import android.hardware.fingerprint.FingerprintManager;
 import android.view.LayoutInflater;
 import android.view.ViewGroup;
 
@@ -23,9 +27,14 @@
 import com.android.keyguard.KeyguardSecurityContainer;
 import com.android.keyguard.KeyguardSecurityViewFlipper;
 import com.android.systemui.R;
+import com.android.systemui.biometrics.SidefpsController;
 import com.android.systemui.dagger.qualifiers.RootView;
 import com.android.systemui.statusbar.phone.KeyguardBouncer;
 
+import java.util.Optional;
+
+import javax.inject.Provider;
+
 import dagger.Module;
 import dagger.Provides;
 
@@ -60,4 +69,16 @@
             KeyguardSecurityContainer containerView) {
         return containerView.findViewById(R.id.view_flipper);
     }
+
+    /** Provides {@link SidefpsController} if the device has the side fingerprint sensor. */
+    @Provides
+    @KeyguardBouncerScope
+    static Optional<SidefpsController> providesOptionalSidefpsController(
+            @Nullable FingerprintManager fingerprintManager,
+            Provider<SidefpsController> sidefpsControllerProvider) {
+        if (!hasSideFpsSensor(fingerprintManager)) {
+            return Optional.empty();
+        }
+        return Optional.of(sidefpsControllerProvider.get());
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java
index 153da4b..d01c98a 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java
@@ -17,9 +17,9 @@
 package com.android.keyguard.dagger;
 
 import com.android.keyguard.KeyguardStatusViewController;
+import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
 import com.android.systemui.statusbar.phone.KeyguardStatusBarViewController;
-import com.android.systemui.statusbar.phone.NotificationPanelViewController;
 
 import dagger.BindsInstance;
 import dagger.Subcomponent;
diff --git a/packages/SystemUI/src/com/android/systemui/Gefingerpoken.java b/packages/SystemUI/src/com/android/systemui/Gefingerpoken.java
index b2d5c21..74d7a8b 100644
--- a/packages/SystemUI/src/com/android/systemui/Gefingerpoken.java
+++ b/packages/SystemUI/src/com/android/systemui/Gefingerpoken.java
@@ -20,6 +20,13 @@
 
 // ACHTUNG!
 public interface Gefingerpoken {
-    boolean onInterceptTouchEvent(MotionEvent ev);
-    boolean onTouchEvent(MotionEvent ev);
+    /** Called when a touch is being intercepted in a ViewGroup. */
+    default boolean onInterceptTouchEvent(MotionEvent ev) {
+        return false;
+    }
+
+    /** Called when a touch is being handled by a view. */
+    default boolean onTouchEvent(MotionEvent ev) {
+        return false;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 9fab2ea..4c400a8 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -43,7 +43,6 @@
 import android.hardware.display.DisplayManager;
 import android.hardware.graphics.common.AlphaInterpretation;
 import android.hardware.graphics.common.DisplayDecorationSupport;
-import android.os.Build;
 import android.os.Handler;
 import android.os.SystemProperties;
 import android.os.Trace;
@@ -73,7 +72,6 @@
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.decor.CutoutDecorProviderFactory;
 import com.android.systemui.decor.DecorProvider;
 import com.android.systemui.decor.DecorProviderFactory;
 import com.android.systemui.decor.DecorProviderKt;
@@ -141,11 +139,13 @@
     protected RoundedCornerResDelegate mRoundedCornerResDelegate;
     @VisibleForTesting
     protected DecorProviderFactory mRoundedCornerFactory;
-    private CutoutDecorProviderFactory mCutoutFactory;
     private int mProviderRefreshToken = 0;
     @VisibleForTesting
     protected OverlayWindow[] mOverlays = null;
     @VisibleForTesting
+    @Nullable
+    DisplayCutoutView[] mCutoutViews;
+    @VisibleForTesting
     ViewGroup mScreenDecorHwcWindow;
     @VisibleForTesting
     ScreenDecorHwcLayer mScreenDecorHwcLayer;
@@ -187,28 +187,17 @@
             return;
         }
 
-        final int[] ids = {
-                R.id.display_cutout,
-                R.id.display_cutout_left,
-                R.id.display_cutout_right,
-                R.id.display_cutout_bottom
-        };
-        int setProtectionCnt = 0;
-        for (int id: ids) {
-            final View view = getOverlayView(id);
-            if (!(view instanceof DisplayCutoutView)) {
-                continue;
-            }
-            ++setProtectionCnt;
-            final DisplayCutoutView dcv = (DisplayCutoutView) view;
-            dcv.setProtection(protectionPath, bounds);
-            dcv.enableShowProtection(true);
+        if (mCutoutViews == null) {
+            Log.w(TAG, "DisplayCutoutView not initialized onApplyCameraProtection");
+            return;
         }
-        if (setProtectionCnt == 0) {
-            if (Build.isDebuggable()) {
-                throw new RuntimeException("CutoutView not initialized showCameraProtection");
-            } else {
-                Log.e(TAG, "CutoutView not initialized showCameraProtection");
+
+        // Show the extra protection around the front facing camera if necessary
+        for (DisplayCutoutView dcv : mCutoutViews) {
+            // Check Null since not all mCutoutViews[pos] be inflated at the meanwhile
+            if (dcv != null) {
+                dcv.setProtection(protectionPath, bounds);
+                dcv.enableShowProtection(true);
             }
         }
     }
@@ -230,26 +219,15 @@
             return;
         }
 
-        final int[] ids = {
-                R.id.display_cutout,
-                R.id.display_cutout_left,
-                R.id.display_cutout_right,
-                R.id.display_cutout_bottom
-        };
-        int setProtectionCnt = 0;
-        for (int id: ids) {
-            final View view = getOverlayView(id);
-            if (!(view instanceof DisplayCutoutView)) {
-                continue;
-            }
-            ++setProtectionCnt;
-            ((DisplayCutoutView) view).enableShowProtection(false);
+        if (mCutoutViews == null) {
+            Log.w(TAG, "DisplayCutoutView not initialized onHideCameraProtection");
+            return;
         }
-        if (setProtectionCnt == 0) {
-            if (Build.isDebuggable()) {
-                throw new RuntimeException("CutoutView not initialized hideCameraProtection");
-            } else {
-                Log.e(TAG, "CutoutView not initialized hideCameraProtection");
+        // Go back to the regular anti-aliasing
+        for (DisplayCutoutView dcv : mCutoutViews) {
+            // Check Null since not all mCutoutViews[pos] be inflated at the meanwhile
+            if (dcv != null) {
+                dcv.enableShowProtection(false);
             }
         }
     }
@@ -357,7 +335,6 @@
         decorProviders.addAll(mFaceScanningFactory.getProviders());
         if (!hasHwLayer) {
             decorProviders.addAll(mRoundedCornerFactory.getProviders());
-            decorProviders.addAll(mCutoutFactory.getProviders());
         }
         return decorProviders;
     }
@@ -402,7 +379,6 @@
         mRoundedCornerResDelegate.setPhysicalPixelDisplaySizeRatio(
                 getPhysicalPixelDisplaySizeRatio());
         mRoundedCornerFactory = new RoundedCornerDecorProviderFactory(mRoundedCornerResDelegate);
-        mCutoutFactory = getCutoutFactory();
         mHwcScreenDecorationSupport = mContext.getDisplay().getDisplayDecorationSupport();
         updateHwLayerRoundedCornerDrawable();
         setupDecorations();
@@ -507,13 +483,18 @@
                 if (needToUpdateProviderViews) {
                     updateOverlayProviderViews(null);
                 } else {
-                    updateOverlayProviderViews(new Integer[] {
-                            mFaceScanningViewId,
-                            R.id.display_cutout,
-                            R.id.display_cutout_left,
-                            R.id.display_cutout_right,
-                            R.id.display_cutout_bottom,
-                    });
+                    updateOverlayProviderViews(new Integer[] { mFaceScanningViewId });
+                }
+
+                if (mCutoutViews != null) {
+                    final int size = mCutoutViews.length;
+                    for (int i = 0; i < size; i++) {
+                        final DisplayCutoutView cutoutView = mCutoutViews[i];
+                        if (cutoutView == null) {
+                            continue;
+                        }
+                        cutoutView.onDisplayChanged(newUniqueId);
+                    }
                 }
 
                 if (mScreenDecorHwcLayer != null) {
@@ -526,9 +507,8 @@
         updateConfiguration();
     }
 
-    @VisibleForTesting
     @Nullable
-    View getOverlayView(@IdRes int id) {
+    private View getOverlayView(@IdRes int id) {
         if (mOverlays == null) {
             return null;
         }
@@ -585,18 +565,18 @@
                 removeHwcOverlay();
             }
 
-            boolean[] hasCreatedOverlay = new boolean[BOUNDS_POSITION_LENGTH];
+            final DisplayCutout cutout = getCutout();
             final boolean shouldOptimizeVisibility = shouldOptimizeVisibility();
-            Integer bound;
-            while ((bound = DecorProviderKt.getProperBound(decorProviders)) != null) {
-                hasCreatedOverlay[bound] = true;
-                Pair<List<DecorProvider>, List<DecorProvider>> pair =
-                        DecorProviderKt.partitionAlignedBound(decorProviders, bound);
-                decorProviders = pair.getSecond();
-                createOverlay(bound, pair.getFirst(), shouldOptimizeVisibility);
-            }
             for (int i = 0; i < BOUNDS_POSITION_LENGTH; i++) {
-                if (!hasCreatedOverlay[i]) {
+                if (shouldShowSwLayerCutout(i, cutout)
+                        || shouldShowSwLayerFaceScan(i, cutout)
+                        || shouldShowSwLayerRoundedCorner(i, cutout)
+                        || shouldShowSwLayerPrivacyDot(i, cutout)) {
+                    Pair<List<DecorProvider>, List<DecorProvider>> pair =
+                            DecorProviderKt.partitionAlignedBound(decorProviders, i);
+                    decorProviders = pair.getSecond();
+                    createOverlay(i, pair.getFirst(), shouldOptimizeVisibility);
+                } else {
                     removeOverlay(i);
                 }
             }
@@ -659,10 +639,9 @@
         }
     }
 
-    // For unit test to override
-    protected CutoutDecorProviderFactory getCutoutFactory() {
-        return new CutoutDecorProviderFactory(mContext.getResources(),
-                mContext.getDisplay());
+    @VisibleForTesting
+    DisplayCutout getCutout() {
+        return mContext.getDisplay().getCutout();
     }
 
     @VisibleForTesting
@@ -752,6 +731,16 @@
         overlayView.setAlpha(0);
         overlayView.setForceDarkAllowed(false);
 
+        // Only show cutout in mOverlays when hwc doesn't support screen decoration
+        if (mHwcScreenDecorationSupport == null) {
+            if (mCutoutViews == null) {
+                mCutoutViews = new DisplayCutoutView[BOUNDS_POSITION_LENGTH];
+            }
+            mCutoutViews[pos] = new DisplayCutoutView(mContext, pos);
+            overlayView.addView(mCutoutViews[pos]);
+            mCutoutViews[pos].updateRotation(mRotation);
+        }
+
         mWindowManager.addView(overlayView, getWindowLayoutParams(pos));
 
         overlayView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
@@ -850,7 +839,8 @@
                         | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                         | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
                         | WindowManager.LayoutParams.FLAG_SLIPPERY
-                        | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
+                        | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
                 PixelFormat.TRANSLUCENT);
         lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS
                 | WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
@@ -958,12 +948,27 @@
             mTintColor = Color.RED;
         }
 
+        if (mOverlays == null) {
+            return;
+        }
+
+        for (int i = 0; i < BOUNDS_POSITION_LENGTH; i++) {
+            if (mOverlays[i] == null) {
+                continue;
+            }
+            final ViewGroup overlayView = mOverlays[i].getRootView();
+            final int size = overlayView.getChildCount();
+            View child;
+            for (int j = 0; j < size; j++) {
+                child = overlayView.getChildAt(j);
+                if (child instanceof DisplayCutoutView && child.getId() == R.id.display_cutout) {
+                    ((DisplayCutoutView) child).setColor(mTintColor);
+                }
+            }
+        }
+
         updateOverlayProviderViews(new Integer[] {
                 mFaceScanningViewId,
-                R.id.display_cutout,
-                R.id.display_cutout_left,
-                R.id.display_cutout_right,
-                R.id.display_cutout_bottom,
                 R.id.rounded_corner_top_left,
                 R.id.rounded_corner_top_right,
                 R.id.rounded_corner_bottom_left,
@@ -1088,6 +1093,15 @@
                 updateHwLayerRoundedCornerDrawable();
             }
             updateLayoutParams();
+            // update cutout view rotation
+            if (mCutoutViews != null) {
+                for (final DisplayCutoutView cutoutView: mCutoutViews) {
+                    if (cutoutView == null) {
+                        continue;
+                    }
+                    cutoutView.updateRotation(mRotation);
+                }
+            }
 
             // update all provider views inside overlay
             updateOverlayProviderViews(null);
@@ -1106,6 +1120,46 @@
         return mRoundedCornerFactory.getHasProviders();
     }
 
+    private boolean isDefaultShownOverlayPos(@BoundsPosition int pos,
+            @Nullable DisplayCutout cutout) {
+        // for cutout is null or cutout with only waterfall.
+        final boolean emptyBoundsOrWaterfall = cutout == null || cutout.isBoundsEmpty();
+        // Shows rounded corner on left and right overlays only when there is no top or bottom
+        // cutout.
+        final int rotatedTop = getBoundPositionFromRotation(BOUNDS_POSITION_TOP, mRotation);
+        final int rotatedBottom = getBoundPositionFromRotation(BOUNDS_POSITION_BOTTOM, mRotation);
+        if (emptyBoundsOrWaterfall || !cutout.getBoundingRectsAll()[rotatedTop].isEmpty()
+                || !cutout.getBoundingRectsAll()[rotatedBottom].isEmpty()) {
+            return pos == BOUNDS_POSITION_TOP || pos == BOUNDS_POSITION_BOTTOM;
+        } else {
+            return pos == BOUNDS_POSITION_LEFT || pos == BOUNDS_POSITION_RIGHT;
+        }
+    }
+
+    private boolean shouldShowSwLayerRoundedCorner(@BoundsPosition int pos,
+            @Nullable DisplayCutout cutout) {
+        return hasRoundedCorners() && isDefaultShownOverlayPos(pos, cutout)
+                && mHwcScreenDecorationSupport == null;
+    }
+
+    private boolean shouldShowSwLayerPrivacyDot(@BoundsPosition int pos,
+            @Nullable DisplayCutout cutout) {
+        return isPrivacyDotEnabled() && isDefaultShownOverlayPos(pos, cutout);
+    }
+
+    private boolean shouldShowSwLayerFaceScan(@BoundsPosition int pos,
+            @Nullable DisplayCutout cutout) {
+        return mFaceScanningFactory.getHasProviders() && isDefaultShownOverlayPos(pos, cutout);
+    }
+
+    private boolean shouldShowSwLayerCutout(@BoundsPosition int pos,
+            @Nullable DisplayCutout cutout) {
+        final Rect[] bounds = cutout == null ? null : cutout.getBoundingRectsAll();
+        final int rotatedPos = getBoundPositionFromRotation(pos, mRotation);
+        return (bounds != null && !bounds[rotatedPos].isEmpty()
+                && mHwcScreenDecorationSupport == null);
+    }
+
     private boolean shouldOptimizeVisibility() {
         return (isPrivacyDotEnabled() || mFaceScanningFactory.getHasProviders())
                 && (mHwcScreenDecorationSupport != null
@@ -1114,7 +1168,7 @@
     }
 
     private boolean shouldDrawCutout() {
-        return mCutoutFactory.getHasProviders();
+        return shouldDrawCutout(mContext);
     }
 
     static boolean shouldDrawCutout(Context context) {
@@ -1230,6 +1284,7 @@
 
             paint.setColor(mColor);
             paint.setStyle(Paint.Style.FILL);
+            setId(R.id.display_cutout);
             if (DEBUG) {
                 getViewTreeObserver().addOnDrawListener(() -> Log.i(TAG,
                         getWindowTitleByPos(pos) + " drawn in rot " + mRotation));
@@ -1237,9 +1292,6 @@
         }
 
         public void setColor(int color) {
-            if (color == mColor) {
-                return;
-            }
             mColor = color;
             paint.setColor(mColor);
             invalidate();
diff --git a/packages/SystemUI/src/com/android/systemui/Somnambulator.java b/packages/SystemUI/src/com/android/systemui/Somnambulator.java
index 0dd6d92..25801cf 100644
--- a/packages/SystemUI/src/com/android/systemui/Somnambulator.java
+++ b/packages/SystemUI/src/com/android/systemui/Somnambulator.java
@@ -17,12 +17,15 @@
 package com.android.systemui;
 
 import android.app.Activity;
-import android.content.Intent;
 import android.service.dreams.Sandman;
 
 /**
  * A simple activity that launches a dream.
  * <p>
+ *
+ * This activity has been deprecated and no longer used. The system uses its presence to determine
+ * whether a dock app should be started on dock through intent resolution.
+ *
  * Note: This Activity is special.  If this class is moved to another package or
  * renamed, be sure to update the component name in {@link Sandman}.
  * </p>
@@ -34,27 +37,6 @@
     @Override
     public void onStart() {
         super.onStart();
-
-        final Intent launchIntent = getIntent();
-        final String action = launchIntent.getAction();
-        if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) {
-            Intent shortcutIntent = new Intent(this, Somnambulator.class);
-            shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
-                    | Intent.FLAG_ACTIVITY_NEW_TASK);
-            Intent resultIntent = new Intent();
-            resultIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
-                    Intent.ShortcutIconResource.fromContext(this, R.mipmap.ic_launcher_dreams));
-            resultIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
-            resultIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(R.string.start_dreams));
-            setResult(RESULT_OK, resultIntent);
-        } else {
-            boolean docked = launchIntent.hasCategory(Intent.CATEGORY_DESK_DOCK);
-            if (docked) {
-                Sandman.startDreamWhenDockedIfAppropriate(this);
-            } else {
-                Sandman.startDreamByUserRequest(this);
-            }
-        }
         finish();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java
index 714d267bb..527ce12 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java
@@ -16,160 +16,22 @@
 
 package com.android.systemui;
 
-import android.app.Activity;
-import android.app.Application;
-import android.app.Service;
-import android.content.BroadcastReceiver;
-import android.content.ContentProvider;
 import android.content.Context;
-import android.content.Intent;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.app.AppComponentFactory;
-
-import com.android.systemui.dagger.ContextComponentHelper;
-import com.android.systemui.dagger.SysUIComponent;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import javax.inject.Inject;
 
 /**
- * Implementation of AppComponentFactory that injects into constructors.
+ * Starts up SystemUI using the AOSP {@link SystemUIInitializerImpl}.
  *
- * This class sets up dependency injection when creating our application.
+ * This initializer relies on reflection to start everything up and should be considered deprecated.
+ * Instead, create your own {@link SystemUIAppComponentFactoryBase}, specify it in your
+ * AndroidManifest.xml and construct your own {@link SystemUIInitializer} directly.
  *
- * Services support dependency injection into their constructors.
- *
- * ContentProviders support injection into member variables - _not_ constructors.
+ * @deprecated Define your own SystemUIAppComponentFactoryBase implementation and use that. This
+ *             implementation may be changed or removed in future releases.
  */
-public class SystemUIAppComponentFactory extends AppComponentFactory {
-
-    private static final String TAG = "AppComponentFactory";
-    @Inject
-    public ContextComponentHelper mComponentHelper;
-
-    public SystemUIAppComponentFactory() {
-        super();
-    }
-
-    @NonNull
+@Deprecated
+public class SystemUIAppComponentFactory extends SystemUIAppComponentFactoryBase {
     @Override
-    public Application instantiateApplicationCompat(
-            @NonNull ClassLoader cl, @NonNull String className)
-            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
-        Application app = super.instantiateApplicationCompat(cl, className);
-        if (app instanceof ContextInitializer) {
-            ((ContextInitializer) app).setContextAvailableCallback(
-                    context -> {
-                        SystemUIFactory.createFromConfig(context);
-                        SystemUIFactory.getInstance().getSysUIComponent().inject(
-                                SystemUIAppComponentFactory.this);
-                    }
-            );
-        }
-
-        return app;
-    }
-
-    @NonNull
-    @Override
-    public ContentProvider instantiateProviderCompat(
-            @NonNull ClassLoader cl, @NonNull String className)
-            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
-
-        ContentProvider contentProvider = super.instantiateProviderCompat(cl, className);
-        if (contentProvider instanceof ContextInitializer) {
-            ((ContextInitializer) contentProvider).setContextAvailableCallback(
-                    context -> {
-                        SystemUIFactory.createFromConfig(context);
-                        SysUIComponent rootComponent =
-                                SystemUIFactory.getInstance().getSysUIComponent();
-                        try {
-                            Method injectMethod = rootComponent.getClass()
-                                    .getMethod("inject", contentProvider.getClass());
-                            injectMethod.invoke(rootComponent, contentProvider);
-                        } catch (NoSuchMethodException
-                                | IllegalAccessException
-                                | InvocationTargetException e) {
-                            Log.w(TAG, "No injector for class: " + contentProvider.getClass(), e);
-                        }
-                    }
-            );
-        }
-
-        return contentProvider;
-    }
-
-    @NonNull
-    @Override
-    public Activity instantiateActivityCompat(@NonNull ClassLoader cl, @NonNull String className,
-            @Nullable Intent intent)
-            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
-        if (mComponentHelper == null) {
-            // This shouldn't happen, but is seen on occasion.
-            // Bug filed against framework to take a look: http://b/141008541
-            SystemUIFactory.getInstance().getSysUIComponent().inject(
-                    SystemUIAppComponentFactory.this);
-        }
-        Activity activity = mComponentHelper.resolveActivity(className);
-        if (activity != null) {
-            return activity;
-        }
-        return super.instantiateActivityCompat(cl, className, intent);
-    }
-
-    @NonNull
-    @Override
-    public Service instantiateServiceCompat(
-            @NonNull ClassLoader cl, @NonNull String className, Intent intent)
-            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
-        if (mComponentHelper == null) {
-            // This shouldn't happen, but does when a device is freshly formatted.
-            // Bug filed against framework to take a look: http://b/141008541
-            SystemUIFactory.getInstance().getSysUIComponent().inject(
-                    SystemUIAppComponentFactory.this);
-        }
-        Service service = mComponentHelper.resolveService(className);
-        if (service != null) {
-            return service;
-        }
-        return super.instantiateServiceCompat(cl, className, intent);
-    }
-
-    @NonNull
-    @Override
-    public BroadcastReceiver instantiateReceiverCompat(@NonNull ClassLoader cl,
-            @NonNull String className, @Nullable Intent intent)
-            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
-        if (mComponentHelper == null) {
-            // This shouldn't happen, but does when a device is freshly formatted.
-            // Bug filed against framework to take a look: http://b/141008541
-            SystemUIFactory.getInstance().getSysUIComponent().inject(
-                    SystemUIAppComponentFactory.this);
-        }
-        BroadcastReceiver receiver = mComponentHelper.resolveBroadcastReceiver(className);
-        if (receiver != null) {
-            return receiver;
-        }
-
-        return super.instantiateReceiverCompat(cl, className, intent);
-    }
-
-    /**
-     * A callback that receives a Context when one is ready.
-     */
-    public interface ContextAvailableCallback {
-        void onContextAvailable(Context context);
-    }
-
-    /**
-     * Implemented in classes that get started by the system before a context is available.
-     */
-    public interface ContextInitializer {
-        void setContextAvailableCallback(ContextAvailableCallback callback);
+    protected SystemUIInitializer createSystemUIInitializer(Context context) {
+        return SystemUIInitializerFactory.createWithContext(context);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt
new file mode 100644
index 0000000..12108b0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui
+
+import android.app.Activity
+import android.app.Application
+import android.app.Service
+import android.content.BroadcastReceiver
+import android.content.ContentProvider
+import android.content.Context
+import android.content.Intent
+import android.util.Log
+import androidx.core.app.AppComponentFactory
+import com.android.systemui.dagger.ContextComponentHelper
+import java.lang.reflect.InvocationTargetException
+import java.util.concurrent.ExecutionException
+import javax.inject.Inject
+
+/**
+ * Implementation of AppComponentFactory that injects into constructors.
+ *
+ * This class sets up dependency injection when creating our application.
+ *
+ * Activities, Services, and BroadcastReceivers support dependency injection into
+ * their constructors.
+ *
+ * ContentProviders support injection into member variables - _not_ constructors.
+ */
+abstract class SystemUIAppComponentFactoryBase : AppComponentFactory() {
+    companion object {
+        private const val TAG = "AppComponentFactory"
+        // Must be static due to http://b/141008541.
+        var systemUIInitializer: SystemUIInitializer? = null
+    }
+
+    @set:Inject
+    lateinit var componentHelper: ContextComponentHelper
+
+    /**
+     * Returns a new [SystemUIInitializer].
+     *
+     * The returned implementation should be specific to your build.
+     */
+    protected abstract fun createSystemUIInitializer(context: Context): SystemUIInitializer
+
+    private fun createSystemUIInitializerInternal(context: Context): SystemUIInitializer {
+        return systemUIInitializer ?: run {
+            val initializer = createSystemUIInitializer(context.applicationContext)
+            try {
+                initializer.init(false)
+            } catch (exception: ExecutionException) {
+                throw RuntimeException("Failed to initialize SysUI", exception)
+            } catch (exception: InterruptedException) {
+                throw RuntimeException("Failed to initialize SysUI", exception)
+            }
+            initializer.sysUIComponent.inject(
+                this@SystemUIAppComponentFactoryBase
+            )
+
+            systemUIInitializer = initializer
+            return initializer
+        }
+    }
+
+    override fun instantiateApplicationCompat(cl: ClassLoader, className: String): Application {
+        val app = super.instantiateApplicationCompat(cl, className)
+        if (app !is ContextInitializer) {
+            throw RuntimeException("App must implement ContextInitializer")
+        } else {
+            app.setContextAvailableCallback { context ->
+                createSystemUIInitializerInternal(context)
+            }
+        }
+
+        return app
+    }
+
+    override fun instantiateProviderCompat(cl: ClassLoader, className: String): ContentProvider {
+        val contentProvider = super.instantiateProviderCompat(cl, className)
+        if (contentProvider is ContextInitializer) {
+            contentProvider.setContextAvailableCallback { context ->
+                val initializer = createSystemUIInitializerInternal(context)
+                val rootComponent = initializer.sysUIComponent
+                try {
+                    val injectMethod = rootComponent.javaClass
+                        .getMethod("inject", contentProvider.javaClass)
+                    injectMethod.invoke(rootComponent, contentProvider)
+                } catch (e: NoSuchMethodException) {
+                    Log.w(TAG, "No injector for class: " + contentProvider.javaClass, e)
+                } catch (e: IllegalAccessException) {
+                    Log.w(TAG, "No injector for class: " + contentProvider.javaClass, e)
+                } catch (e: InvocationTargetException) {
+                    Log.w(TAG, "No injector for class: " + contentProvider.javaClass, e)
+                }
+                initializer
+            }
+        }
+        return contentProvider
+    }
+
+    override fun instantiateActivityCompat(
+        cl: ClassLoader,
+        className: String,
+        intent: Intent?
+    ): Activity {
+        if (!this::componentHelper.isInitialized) {
+            // This shouldn't happen, but is seen on occasion.
+            // Bug filed against framework to take a look: http://b/141008541
+            systemUIInitializer?.sysUIComponent?.inject(this@SystemUIAppComponentFactoryBase)
+        }
+        return componentHelper.resolveActivity(className)
+            ?: super.instantiateActivityCompat(cl, className, intent)
+    }
+
+    override fun instantiateServiceCompat(
+        cl: ClassLoader,
+        className: String,
+        intent: Intent?
+    ): Service {
+        if (!this::componentHelper.isInitialized) {
+            // This shouldn't happen, but does when a device is freshly formatted.
+            // Bug filed against framework to take a look: http://b/141008541
+            systemUIInitializer?.sysUIComponent?.inject(this@SystemUIAppComponentFactoryBase)
+        }
+        return componentHelper.resolveService(className)
+            ?: super.instantiateServiceCompat(cl, className, intent)
+    }
+
+    override fun instantiateReceiverCompat(
+        cl: ClassLoader,
+        className: String,
+        intent: Intent?
+    ): BroadcastReceiver {
+        if (!this::componentHelper.isInitialized) {
+            // This shouldn't happen, but does when a device is freshly formatted.
+            // Bug filed against framework to take a look: http://b/141008541
+            systemUIInitializer?.sysUIComponent?.inject(this@SystemUIAppComponentFactoryBase)
+        }
+        return componentHelper.resolveBroadcastReceiver(className)
+            ?: super.instantiateReceiverCompat(cl, className, intent)
+    }
+
+    /**
+     * An Interface for classes that can be notified when an Application Context becomes available.
+     *
+     * An instance of this will be passed to implementers of [ContextInitializer].
+     */
+    fun interface ContextAvailableCallback {
+        /** Notifies when the Application Context is available.  */
+        fun onContextAvailable(context: Context): SystemUIInitializer
+    }
+
+    /**
+     * Interface for classes that can be constructed by the system before a context is available.
+     *
+     * This is intended for [Application] and [ContentProvider] implementations that
+     * either may not have a Context until some point after construction or are themselves
+     * a [Context].
+     *
+     * Implementers will be passed a [ContextAvailableCallback] that they should call as soon
+     * as an Application Context is ready.
+     */
+    interface ContextInitializer {
+        /**
+         * Called to supply the [ContextAvailableCallback] that should be called when an
+         * Application [Context] is available.
+         */
+        fun setContextAvailableCallback(callback: ContextAvailableCallback)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 6d3fd50..9138b23 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -42,7 +42,6 @@
 import android.view.ThreadedRenderer;
 
 import com.android.internal.protolog.common.ProtoLog;
-import com.android.systemui.dagger.ContextComponentHelper;
 import com.android.systemui.dagger.GlobalRootComponent;
 import com.android.systemui.dagger.SysUIComponent;
 import com.android.systemui.dump.DumpManager;
@@ -65,7 +64,6 @@
     public static final String TAG = "SystemUIService";
     private static final boolean DEBUG = false;
 
-    private ContextComponentHelper mComponentHelper;
     private BootCompleteCacheImpl mBootCompleteCache;
     private DumpManager mDumpManager;
 
@@ -80,8 +78,8 @@
     private CoreStartable[] mServices;
     private boolean mServicesStarted;
     private SystemUIAppComponentFactory.ContextAvailableCallback mContextAvailableCallback;
-    private GlobalRootComponent mRootComponent;
     private SysUIComponent mSysUIComponent;
+    private SystemUIInitializer mInitializer;
 
     public SystemUIApplication() {
         super();
@@ -90,6 +88,10 @@
         ProtoLog.REQUIRE_PROTOLOGTOOL = false;
     }
 
+    protected GlobalRootComponent getRootComponent() {
+        return mInitializer.getRootComponent();
+    }
+
     @Override
     public void onCreate() {
         super.onCreate();
@@ -99,10 +101,8 @@
         TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming",
                 Trace.TRACE_TAG_APP);
         log.traceBegin("DependencyInjection");
-        mContextAvailableCallback.onContextAvailable(this);
-        mRootComponent = SystemUIFactory.getInstance().getRootComponent();
-        mSysUIComponent = SystemUIFactory.getInstance().getSysUIComponent();
-        mComponentHelper = mSysUIComponent.getContextComponentHelper();
+        mInitializer = mContextAvailableCallback.onContextAvailable(this);
+        mSysUIComponent = mInitializer.getSysUIComponent();
         mBootCompleteCache = mSysUIComponent.provideBootCacheImpl();
         log.traceEnd();
 
@@ -189,15 +189,14 @@
      */
 
     public void startServicesIfNeeded() {
-        final String vendorComponent = SystemUIFactory.getInstance()
-                .getVendorComponent(getResources());
+        final String vendorComponent = mInitializer.getVendorComponent(getResources());
 
         // Sort the startables so that we get a deterministic ordering.
         // TODO: make #start idempotent and require users of CoreStartable to call it.
         Map<Class<?>, Provider<CoreStartable>> sortedStartables = new TreeMap<>(
                 Comparator.comparing(Class::getName));
-        sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponents());
-        sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponentsPerUser());
+        sortedStartables.putAll(mSysUIComponent.getStartables());
+        sortedStartables.putAll(mSysUIComponent.getPerUserStartables());
         startServicesIfNeeded(
                 sortedStartables, "StartServices", vendorComponent);
     }
@@ -212,7 +211,7 @@
         // Sort the startables so that we get a deterministic ordering.
         Map<Class<?>, Provider<CoreStartable>> sortedStartables = new TreeMap<>(
                 Comparator.comparing(Class::getName));
-        sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponentsPerUser());
+        sortedStartables.putAll(mSysUIComponent.getPerUserStartables());
         startServicesIfNeeded(
                 sortedStartables, "StartSecondaryServices", null);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
similarity index 70%
rename from packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
rename to packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
index ca94b8c..24fcf15 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -11,7 +11,7 @@
  * 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
+ * limitations under the License.
  */
 
 package com.android.systemui;
@@ -22,75 +22,55 @@
 import android.os.HandlerThread;
 import android.util.Log;
 
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.dagger.DaggerGlobalRootComponent;
 import com.android.systemui.dagger.GlobalRootComponent;
 import com.android.systemui.dagger.SysUIComponent;
 import com.android.systemui.dagger.WMComponent;
 import com.android.systemui.util.InitializationChecker;
 import com.android.wm.shell.dagger.WMShellConcurrencyModule;
+import com.android.wm.shell.sysui.ShellInterface;
 import com.android.wm.shell.transition.ShellTransitions;
 
-import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.ExecutionException;
 
-import javax.inject.Provider;
-
 /**
- * Class factory to provide customizable SystemUI components.
+ * Initializer that stands up SystemUI.
+ *
+ * Implementations should override {@link #getGlobalRootComponentBuilder()} to fill in their own
+ * Dagger root component.
  */
-public class SystemUIFactory {
+public abstract class SystemUIInitializer {
     private static final String TAG = "SystemUIFactory";
 
-    static SystemUIFactory mFactory;
+    private final Context mContext;
+
     private GlobalRootComponent mRootComponent;
     private WMComponent mWMComponent;
     private SysUIComponent mSysUIComponent;
     private InitializationChecker mInitializationChecker;
 
-    public static <T extends SystemUIFactory> T getInstance() {
-        return (T) mFactory;
+    public SystemUIInitializer(Context context) {
+        mContext = context;
     }
 
-    public static void createFromConfig(Context context) {
-        createFromConfig(context, false);
+    protected abstract GlobalRootComponent.Builder getGlobalRootComponentBuilder();
+
+    /**
+     * Prepares the SysUIComponent builder before it is built.
+     * @param sysUIBuilder the builder provided by the root component's getSysUIComponent() method
+     * @param wm the built WMComponent from the root component's getWMComponent() method
+     */
+    protected SysUIComponent.Builder prepareSysUIComponentBuilder(
+            SysUIComponent.Builder sysUIBuilder, WMComponent wm) {
+        return sysUIBuilder;
     }
 
-    @VisibleForTesting
-    public static void createFromConfig(Context context, boolean fromTest) {
-        if (mFactory != null) {
-            return;
-        }
-
-        final String clsName = context.getString(R.string.config_systemUIFactoryComponent);
-        if (clsName == null || clsName.length() == 0) {
-            throw new RuntimeException("No SystemUIFactory component configured");
-        }
-
-        try {
-            Class<?> cls = null;
-            cls = context.getClassLoader().loadClass(clsName);
-            mFactory = (SystemUIFactory) cls.newInstance();
-            mFactory.init(context, fromTest);
-        } catch (Throwable t) {
-            Log.w(TAG, "Error creating SystemUIFactory component: " + clsName, t);
-            throw new RuntimeException(t);
-        }
-    }
-
-    @VisibleForTesting
-    static void cleanup() {
-        mFactory = null;
-    }
-
-    public SystemUIFactory() {}
-
-    @VisibleForTesting
-    public void init(Context context, boolean fromTest)
-            throws ExecutionException, InterruptedException {
+    /**
+     * Starts the initialization process. This stands up the Dagger graph.
+     */
+    public void init(boolean fromTest) throws ExecutionException, InterruptedException {
         mRootComponent = getGlobalRootComponentBuilder()
-                .context(context)
+                .context(mContext)
                 .instrumentationTest(fromTest)
                 .build();
 
@@ -98,7 +78,7 @@
         boolean initializeComponents = mInitializationChecker.initializeComponents();
 
         // Stand up WMComponent
-        setupWmComponent(context);
+        setupWmComponent(mContext);
         if (initializeComponents) {
             // Only initialize when not starting from tests since this currently initializes some
             // components that shouldn't be run in the test environment
@@ -111,39 +91,33 @@
             // Only initialize when not starting from tests since this currently initializes some
             // components that shouldn't be run in the test environment
             builder = prepareSysUIComponentBuilder(builder, mWMComponent)
+                    .setShell(mWMComponent.getShell())
                     .setPip(mWMComponent.getPip())
                     .setSplitScreen(mWMComponent.getSplitScreen())
                     .setOneHanded(mWMComponent.getOneHanded())
                     .setBubbles(mWMComponent.getBubbles())
-                    .setHideDisplayCutout(mWMComponent.getHideDisplayCutout())
                     .setShellCommandHandler(mWMComponent.getShellCommandHandler())
                     .setTaskViewFactory(mWMComponent.getTaskViewFactory())
                     .setTransitions(mWMComponent.getTransitions())
                     .setStartingSurface(mWMComponent.getStartingSurface())
                     .setDisplayAreaHelper(mWMComponent.getDisplayAreaHelper())
-                    .setTaskSurfaceHelper(mWMComponent.getTaskSurfaceHelper())
                     .setRecentTasks(mWMComponent.getRecentTasks())
-                    .setCompatUI(mWMComponent.getCompatUI())
-                    .setDragAndDrop(mWMComponent.getDragAndDrop())
                     .setBackAnimation(mWMComponent.getBackAnimation());
         } else {
             // TODO: Call on prepareSysUIComponentBuilder but not with real components. Other option
             // is separating this logic into newly creating SystemUITestsFactory.
             builder = prepareSysUIComponentBuilder(builder, mWMComponent)
+                    .setShell(new ShellInterface() {})
                     .setPip(Optional.ofNullable(null))
                     .setSplitScreen(Optional.ofNullable(null))
                     .setOneHanded(Optional.ofNullable(null))
                     .setBubbles(Optional.ofNullable(null))
-                    .setHideDisplayCutout(Optional.ofNullable(null))
                     .setShellCommandHandler(Optional.ofNullable(null))
                     .setTaskViewFactory(Optional.ofNullable(null))
                     .setTransitions(new ShellTransitions() {})
                     .setDisplayAreaHelper(Optional.ofNullable(null))
                     .setStartingSurface(Optional.ofNullable(null))
-                    .setTaskSurfaceHelper(Optional.ofNullable(null))
                     .setRecentTasks(Optional.ofNullable(null))
-                    .setCompatUI(Optional.ofNullable(null))
-                    .setDragAndDrop(Optional.ofNullable(null))
                     .setBackAnimation(Optional.ofNullable(null));
         }
         mSysUIComponent = builder.build();
@@ -188,20 +162,6 @@
         }
     }
 
-    /**
-     * Prepares the SysUIComponent builder before it is built.
-     * @param sysUIBuilder the builder provided by the root component's getSysUIComponent() method
-     * @param wm the built WMComponent from the root component's getWMComponent() method
-     */
-    protected SysUIComponent.Builder prepareSysUIComponentBuilder(
-            SysUIComponent.Builder sysUIBuilder, WMComponent wm) {
-        return sysUIBuilder;
-    }
-
-    protected GlobalRootComponent.Builder getGlobalRootComponentBuilder() {
-        return DaggerGlobalRootComponent.builder();
-    }
-
     public GlobalRootComponent getRootComponent() {
         return mRootComponent;
     }
@@ -215,23 +175,9 @@
     }
 
     /**
-     * Returns the list of {@link CoreStartable} components that should be started at startup.
-     */
-    public Map<Class<?>, Provider<CoreStartable>> getStartableComponents() {
-        return mSysUIComponent.getStartables();
-    }
-
-    /**
      * Returns the list of additional system UI components that should be started.
      */
     public String getVendorComponent(Resources resources) {
         return resources.getString(R.string.config_systemUIVendorServiceComponent);
     }
-
-    /**
-     * Returns the list of {@link CoreStartable} components that should be started per user.
-     */
-    public Map<Class<?>, Provider<CoreStartable>> getStartableComponentsPerUser() {
-        return mSysUIComponent.getPerUserStartables();
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIInitializerFactory.kt b/packages/SystemUI/src/com/android/systemui/SystemUIInitializerFactory.kt
new file mode 100644
index 0000000..b9454e8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIInitializerFactory.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.util.Log
+import com.android.internal.annotations.VisibleForTesting
+import com.android.systemui.util.Assert
+
+/**
+ * Factory to reflectively lookup a [SystemUIInitializer] to start SystemUI with.
+ */
+@Deprecated("Provide your own {@link SystemUIAppComponentFactoryBase} that doesn't need this.")
+object SystemUIInitializerFactory {
+    private const val TAG = "SysUIInitializerFactory"
+    @SuppressLint("StaticFieldLeak")
+    private var initializer: SystemUIInitializer? = null
+
+    /**
+     * Instantiate a [SystemUIInitializer] reflectively.
+     */
+    @JvmStatic
+    fun createWithContext(context: Context): SystemUIInitializer {
+        return createFromConfig(context)
+    }
+
+    /**
+     * Instantiate a [SystemUIInitializer] reflectively.
+     */
+    @JvmStatic
+    private fun createFromConfig(context: Context): SystemUIInitializer {
+        Assert.isMainThread()
+
+        return createFromConfigNoAssert(context)
+    }
+
+    @JvmStatic
+    @VisibleForTesting
+    fun createFromConfigNoAssert(context: Context): SystemUIInitializer {
+
+        return initializer ?: run {
+            val className = context.getString(R.string.config_systemUIFactoryComponent)
+            if (className.isEmpty()) {
+                throw RuntimeException("No SystemUIFactory component configured")
+            }
+            try {
+                val cls = context.classLoader.loadClass(className)
+                val constructor = cls.getConstructor(Context::class.java)
+                (constructor.newInstance(context) as SystemUIInitializer).apply {
+                    initializer = this
+                }
+            } catch (t: Throwable) {
+                Log.w(TAG, "Error creating SystemUIInitializer component: $className", t)
+                throw t
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt b/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt
new file mode 100644
index 0000000..8920c92
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui
+
+import android.content.Context
+import com.android.systemui.dagger.DaggerGlobalRootComponent
+import com.android.systemui.dagger.GlobalRootComponent
+
+/**
+ * {@link SystemUIInitializer} that stands up AOSP SystemUI.
+ */
+class SystemUIInitializerImpl(context: Context) : SystemUIInitializer(context) {
+    override fun getGlobalRootComponentBuilder(): GlobalRootComponent.Builder {
+        return DaggerGlobalRootComponent.builder()
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
index d2703f5..aff0b1f 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
@@ -353,6 +353,7 @@
         }
 
         mIsShowing = false;
+        mDragAnimator.cancel();
         mWindowManager.removeView(this);
 
         setOnApplyWindowInsetsListener(null);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index bc1c5f4..84e1c3d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -90,6 +90,8 @@
     private static final int STATE_ANIMATING_OUT = 4;
     private static final int STATE_GONE = 5;
 
+    private static final float BACKGROUND_DIM_AMOUNT = 0.5f;
+
     /** Shows biometric prompt dialog animation. */
     private static final String SHOW = "show";
     /** Dismiss biometric prompt dialog animation.  */
@@ -247,13 +249,13 @@
                     break;
                 case AuthBiometricView.Callback.ACTION_BUTTON_TRY_AGAIN:
                     mFailedModalities.clear();
-                    mConfig.mCallback.onTryAgainPressed();
+                    mConfig.mCallback.onTryAgainPressed(getRequestId());
                     break;
                 case AuthBiometricView.Callback.ACTION_ERROR:
                     animateAway(AuthDialogCallback.DISMISSED_ERROR);
                     break;
                 case AuthBiometricView.Callback.ACTION_USE_DEVICE_CREDENTIAL:
-                    mConfig.mCallback.onDeviceCredentialPressed();
+                    mConfig.mCallback.onDeviceCredentialPressed(getRequestId());
                     mHandler.postDelayed(() -> {
                         addCredentialView(false /* animatePanel */, true /* animateContents */);
                     }, mConfig.mSkipAnimation ? 0 : AuthDialog.ANIMATE_CREDENTIAL_START_DELAY_MS);
@@ -371,7 +373,7 @@
 
     void sendEarlyUserCanceled() {
         mConfig.mCallback.onSystemEvent(
-                BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL);
+                BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL, getRequestId());
     }
 
     @Override
@@ -754,6 +756,16 @@
                     .setDuration(animateDuration)
                     .setInterpolator(mLinearOutSlowIn)
                     .setListener(getJankListener(this, DISMISS, animateDuration))
+                    .setUpdateListener(animation -> {
+                        if (mWindowManager == null || getViewRootImpl() == null) {
+                            Log.w(TAG, "skip updateViewLayout() for dim animation.");
+                            return;
+                        }
+                        final WindowManager.LayoutParams lp = getViewRootImpl().mWindowAttributes;
+                        lp.dimAmount = (1.0f - (Float) animation.getAnimatedValue())
+                                * BACKGROUND_DIM_AMOUNT;
+                        mWindowManager.updateViewLayout(this, lp);
+                    })
                     .withLayer()
                     .start();
         });
@@ -762,7 +774,8 @@
     private void sendPendingCallbackIfNotNull() {
         Log.d(TAG, "pendingCallback: " + mPendingCallbackReason);
         if (mPendingCallbackReason != null) {
-            mConfig.mCallback.onDismissed(mPendingCallbackReason, mCredentialAttestation);
+            mConfig.mCallback.onDismissed(mPendingCallbackReason,
+                    mCredentialAttestation, getRequestId());
             mPendingCallbackReason = null;
         }
     }
@@ -792,7 +805,7 @@
         }
         mContainerState = STATE_SHOWING;
         if (mBiometricView != null) {
-            mConfig.mCallback.onDialogAnimatedIn();
+            mConfig.mCallback.onDialogAnimatedIn(getRequestId());
             mBiometricView.onDialogAnimatedIn();
         }
     }
@@ -800,7 +813,8 @@
     @VisibleForTesting
     static WindowManager.LayoutParams getLayoutParams(IBinder windowToken, CharSequence title) {
         final int windowFlags = WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
-                | WindowManager.LayoutParams.FLAG_SECURE;
+                | WindowManager.LayoutParams.FLAG_SECURE
+                | WindowManager.LayoutParams.FLAG_DIM_BEHIND;
         final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                 ViewGroup.LayoutParams.MATCH_PARENT,
                 ViewGroup.LayoutParams.MATCH_PARENT,
@@ -811,6 +825,7 @@
         lp.setFitInsetsTypes(lp.getFitInsetsTypes() & ~WindowInsets.Type.ime());
         lp.setTitle("BiometricPrompt");
         lp.accessibilityTitle = title;
+        lp.dimAmount = BACKGROUND_DIM_AMOUNT;
         lp.token = windowToken;
         return lp;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index a097c5e..47ff59c 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -340,11 +340,17 @@
     }
 
     @Override
-    public void onTryAgainPressed() {
+    public void onTryAgainPressed(long requestId) {
         if (mReceiver == null) {
             Log.e(TAG, "onTryAgainPressed: Receiver is null");
             return;
         }
+
+        if (requestId != mCurrentDialog.getRequestId()) {
+            Log.w(TAG, "requestId doesn't match, skip onTryAgainPressed");
+            return;
+        }
+
         try {
             mReceiver.onTryAgainPressed();
         } catch (RemoteException e) {
@@ -353,11 +359,17 @@
     }
 
     @Override
-    public void onDeviceCredentialPressed() {
+    public void onDeviceCredentialPressed(long requestId) {
         if (mReceiver == null) {
             Log.e(TAG, "onDeviceCredentialPressed: Receiver is null");
             return;
         }
+
+        if (requestId != mCurrentDialog.getRequestId()) {
+            Log.w(TAG, "requestId doesn't match, skip onDeviceCredentialPressed");
+            return;
+        }
+
         try {
             mReceiver.onDeviceCredentialPressed();
         } catch (RemoteException e) {
@@ -366,11 +378,17 @@
     }
 
     @Override
-    public void onSystemEvent(int event) {
+    public void onSystemEvent(int event, long requestId) {
         if (mReceiver == null) {
             Log.e(TAG, "onSystemEvent(" + event + "): Receiver is null");
             return;
         }
+
+        if (requestId != mCurrentDialog.getRequestId()) {
+            Log.w(TAG, "requestId doesn't match, skip onSystemEvent");
+            return;
+        }
+
         try {
             mReceiver.onSystemEvent(event);
         } catch (RemoteException e) {
@@ -379,12 +397,17 @@
     }
 
     @Override
-    public void onDialogAnimatedIn() {
+    public void onDialogAnimatedIn(long requestId) {
         if (mReceiver == null) {
             Log.e(TAG, "onDialogAnimatedIn: Receiver is null");
             return;
         }
 
+        if (requestId != mCurrentDialog.getRequestId()) {
+            Log.w(TAG, "requestId doesn't match, skip onDialogAnimatedIn");
+            return;
+        }
+
         try {
             mReceiver.onDialogAnimatedIn();
         } catch (RemoteException e) {
@@ -393,7 +416,14 @@
     }
 
     @Override
-    public void onDismissed(@DismissedReason int reason, @Nullable byte[] credentialAttestation) {
+    public void onDismissed(@DismissedReason int reason,
+                            @Nullable byte[] credentialAttestation, long requestId) {
+
+        if (mCurrentDialog != null && requestId != mCurrentDialog.getRequestId()) {
+            Log.w(TAG, "requestId doesn't match, skip onDismissed");
+            return;
+        }
+
         switch (reason) {
             case AuthDialogCallback.DISMISSED_USER_CANCELED:
                 sendResultAndCleanUp(BiometricPrompt.DISMISSED_REASON_USER_CANCEL,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java
index a7d2901..bbe461a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java
@@ -47,27 +47,28 @@
      * @param reason
      * @param credentialAttestation the HAT received from LockSettingsService upon verification
      */
-    void onDismissed(@DismissedReason int reason, @Nullable byte[] credentialAttestation);
+    void onDismissed(@DismissedReason int reason,
+                     @Nullable byte[] credentialAttestation, long requestId);
 
     /**
      * Invoked when the "try again" button is clicked
      */
-    void onTryAgainPressed();
+    void onTryAgainPressed(long requestId);
 
     /**
      * Invoked when the "use password" button is clicked
      */
-    void onDeviceCredentialPressed();
+    void onDeviceCredentialPressed(long requestId);
 
     /**
      * See {@link android.hardware.biometrics.BiometricPrompt.Builder
      * #setReceiveSystemEvents(boolean)}
      * @param event
      */
-    void onSystemEvent(int event);
+    void onSystemEvent(int event, long requestId);
 
     /**
      * Notifies when the dialog has finished animating.
      */
-    void onDialogAnimatedIn();
+    void onDialogAnimatedIn(long requestId);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt
index 04e2dccd..bbffb73 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt
@@ -34,16 +34,16 @@
 import android.os.Handler
 import android.util.Log
 import android.util.RotationUtils
-import android.view.View.AccessibilityDelegate
-import android.view.accessibility.AccessibilityEvent
 import android.view.Display
 import android.view.Gravity
 import android.view.LayoutInflater
 import android.view.Surface
 import android.view.View
+import android.view.View.AccessibilityDelegate
 import android.view.ViewPropertyAnimator
 import android.view.WindowInsets
 import android.view.WindowManager
+import android.view.accessibility.AccessibilityEvent
 import androidx.annotation.RawRes
 import com.airbnb.lottie.LottieAnimationView
 import com.airbnb.lottie.LottieProperty
@@ -70,13 +70,12 @@
     private val activityTaskManager: ActivityTaskManager,
     overviewProxyService: OverviewProxyService,
     displayManager: DisplayManager,
-    @Main mainExecutor: DelayableExecutor,
+    @Main private val mainExecutor: DelayableExecutor,
     @Main private val handler: Handler
 ) {
     @VisibleForTesting
     val sensorProps: FingerprintSensorPropertiesInternal = fingerprintManager
-        ?.sensorPropertiesInternal
-        ?.firstOrNull { it.isAnySidefpsType }
+        ?.sideFpsSensorProperties
         ?: throw IllegalStateException("no side fingerprint sensor")
 
     @VisibleForTesting
@@ -135,25 +134,34 @@
     }
 
     init {
-        fingerprintManager?.setSidefpsController(object : ISidefpsController.Stub() {
-            override fun show(
-                sensorId: Int,
-                @BiometricOverlayConstants.ShowReason reason: Int
-            ) = if (reason.isReasonToShow(activityTaskManager)) doShow() else hide(sensorId)
+        fingerprintManager?.setSidefpsController(
+            object : ISidefpsController.Stub() {
+                override fun show(
+                    sensorId: Int,
+                    @BiometricOverlayConstants.ShowReason reason: Int
+                ) = if (reason.isReasonToShow(activityTaskManager)) show() else hide()
 
-            private fun doShow() = mainExecutor.execute {
-                if (overlayView == null) {
-                    createOverlayForDisplay()
-                } else {
-                    Log.v(TAG, "overlay already shown")
-                }
-            }
-
-            override fun hide(sensorId: Int) = mainExecutor.execute { overlayView = null }
-        })
+                override fun hide(sensorId: Int) = hide()
+            })
         overviewProxyService.addCallback(overviewProxyListener)
     }
 
+    /** Shows the side fps overlay if not already shown. */
+    fun show() {
+        mainExecutor.execute {
+            if (overlayView == null) {
+                createOverlayForDisplay()
+            } else {
+                Log.v(TAG, "overlay already shown")
+            }
+        }
+    }
+
+    /** Hides the fps overlay if shown. */
+    fun hide() {
+        mainExecutor.execute { overlayView = null }
+    }
+
     private fun onOrientationChanged() {
         if (overlayView != null) {
             createOverlayForDisplay()
@@ -266,6 +274,12 @@
     }
 }
 
+private val FingerprintManager?.sideFpsSensorProperties: FingerprintSensorPropertiesInternal?
+    get() = this?.sensorPropertiesInternal?.firstOrNull { it.isAnySidefpsType }
+
+/** Returns [True] when the device has a side fingerprint sensor. */
+fun FingerprintManager?.hasSideFpsSensor(): Boolean = this?.sideFpsSensorProperties != null
+
 @BiometricOverlayConstants.ShowReason
 private fun Int.isReasonToShow(activityTaskManager: ActivityTaskManager): Boolean = when (this) {
     REASON_AUTH_KEYGUARD -> false
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index e5564b7..cf50f7f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -20,6 +20,7 @@
 import static android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD;
 
 import static com.android.internal.util.Preconditions.checkNotNull;
+import static com.android.systemui.classifier.Classifier.LOCK_ICON;
 import static com.android.systemui.classifier.Classifier.UDFPS_AUTHENTICATION;
 
 import android.annotation.NonNull;
@@ -167,11 +168,16 @@
     private final Set<Callback> mCallbacks = new HashSet<>();
 
     @VisibleForTesting
-    public static final VibrationAttributes VIBRATION_ATTRIBUTES =
+    public static final VibrationAttributes UDFPS_VIBRATION_ATTRIBUTES =
             new VibrationAttributes.Builder()
                     // vibration will bypass battery saver mode:
                     .setUsage(VibrationAttributes.USAGE_COMMUNICATION_REQUEST)
                     .build();
+    @VisibleForTesting
+    public static final VibrationAttributes LOCK_ICON_VIBRATION_ATTRIBUTES =
+            new VibrationAttributes.Builder()
+                    .setUsage(VibrationAttributes.USAGE_TOUCH)
+                    .build();
 
     // haptic to use for successful device entry
     public static final VibrationEffect EFFECT_CLICK =
@@ -603,7 +609,7 @@
             @NonNull SystemUIDialogManager dialogManager,
             @NonNull LatencyTracker latencyTracker,
             @NonNull ActivityLaunchAnimator activityLaunchAnimator,
-            @NonNull Optional<AlternateUdfpsTouchProvider> aternateTouchProvider,
+            @NonNull Optional<AlternateUdfpsTouchProvider> alternateTouchProvider,
             @BiometricsBackground Executor biometricsExecutor) {
         mContext = context;
         mExecution = execution;
@@ -633,7 +639,7 @@
         mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
         mLatencyTracker = latencyTracker;
         mActivityLaunchAnimator = activityLaunchAnimator;
-        mAlternateTouchProvider = aternateTouchProvider.orElse(null);
+        mAlternateTouchProvider = alternateTouchProvider.orElse(null);
         mBiometricExecutor = biometricsExecutor;
 
         mOrientationListener = new BiometricDisplayListener(
@@ -671,7 +677,7 @@
                     mContext.getOpPackageName(),
                     EFFECT_CLICK,
                     "udfps-onStart-click",
-                    VIBRATION_ATTRIBUTES);
+                    UDFPS_VIBRATION_ATTRIBUTES);
         }
     }
 
@@ -748,7 +754,19 @@
         }
 
         if (!mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
+            if (mFalsingManager.isFalseTouch(LOCK_ICON)) {
+                Log.v(TAG, "aod lock icon long-press rejected by the falsing manager.");
+                return;
+            }
             mKeyguardViewManager.showBouncer(true);
+
+            // play the same haptic as the LockIconViewController longpress
+            mVibrator.vibrate(
+                    Process.myUid(),
+                    mContext.getOpPackageName(),
+                    UdfpsController.EFFECT_CLICK,
+                    "aod-lock-icon-longpress",
+                    LOCK_ICON_VIBRATION_ATTRIBUTES);
             return;
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt b/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
index 4986fe8..cccd3a4 100644
--- a/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
@@ -17,27 +17,28 @@
 package com.android.systemui.camera
 
 import android.app.ActivityManager
-import android.app.ActivityManager.RunningTaskInfo
 import android.app.ActivityOptions
-import android.app.ActivityTaskManager
+import android.app.IActivityTaskManager
 import android.content.ContentResolver
 import android.content.Context
 import android.content.Intent
 import android.content.pm.PackageManager
 import android.content.pm.ResolveInfo
-import android.os.AsyncTask
 import android.os.RemoteException
 import android.os.UserHandle
 import android.util.Log
 import android.view.WindowManager
+import androidx.annotation.VisibleForTesting
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.ActivityIntentHelper
-import com.android.systemui.camera.CameraIntents.Companion.isSecureCameraIntent
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.shared.system.ActivityManagerKt.isInForeground
 import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.phone.CentralSurfaces
 import com.android.systemui.statusbar.phone.PanelViewController
 import com.android.systemui.statusbar.policy.KeyguardStateController
+import java.util.concurrent.Executor
 import javax.inject.Inject
 
 /**
@@ -52,8 +53,10 @@
     private val activityManager: ActivityManager,
     private val activityStarter: ActivityStarter,
     private val activityIntentHelper: ActivityIntentHelper,
+    private val activityTaskManager: IActivityTaskManager,
     private val cameraIntents: CameraIntentsWrapper,
     private val contentResolver: ContentResolver,
+    @Main private val uiExecutor: Executor,
 ) {
     /**
      * Whether the camera application can be launched for the camera launch gesture.
@@ -63,15 +66,15 @@
             return false
         }
 
-        val resolveInfo: ResolveInfo = packageManager.resolveActivityAsUser(
+        val resolveInfo: ResolveInfo? = packageManager.resolveActivityAsUser(
             getStartCameraIntent(),
             PackageManager.MATCH_DEFAULT_ONLY,
             KeyguardUpdateMonitor.getCurrentUser()
         )
-        val resolvedPackage = resolveInfo.activityInfo?.packageName
+        val resolvedPackage = resolveInfo?.activityInfo?.packageName
         return (resolvedPackage != null &&
                 (statusBarState != StatusBarState.SHADE ||
-                !isForegroundApp(resolvedPackage)))
+                !activityManager.isInForeground(resolvedPackage)))
     }
 
     /**
@@ -85,8 +88,8 @@
         val wouldLaunchResolverActivity = activityIntentHelper.wouldLaunchResolverActivity(
             intent, KeyguardUpdateMonitor.getCurrentUser()
         )
-        if (isSecureCameraIntent(intent) && !wouldLaunchResolverActivity) {
-            AsyncTask.execute {
+        if (CameraIntents.isSecureCameraIntent(intent) && !wouldLaunchResolverActivity) {
+            uiExecutor.execute {
                 // Normally an activity will set its requested rotation animation on its window.
                 // However when launching an activity causes the orientation to change this is too
                 // late. In these cases, the default animation is used. This doesn't look good for
@@ -98,7 +101,7 @@
                 activityOptions.rotationAnimationHint =
                     WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS
                 try {
-                    ActivityTaskManager.getService().startActivityAsUser(
+                    activityTaskManager.startActivityAsUser(
                         null,
                         context.basePackageName,
                         context.attributionTag,
@@ -125,6 +128,13 @@
             // launched from behind the lock-screen.
             activityStarter.startActivity(intent, false /* dismissShade */)
         }
+
+        // Call this to make sure that the keyguard returns if the app that is being launched
+        // crashes after a timeout.
+        centralSurfaces.startLaunchTransitionTimeout()
+        // Call this to make sure the keyguard is ready to be dismissed once the next intent is
+        // handled by the OS (in our case it is the activity we started right above)
+        centralSurfaces.readyForKeyguardDone()
     }
 
     /**
@@ -141,16 +151,8 @@
         }
     }
 
-    /**
-     * Returns `true` if the application with the given package name is running in the foreground;
-     * `false` otherwise
-     */
-    private fun isForegroundApp(packageName: String): Boolean {
-        val tasks: List<RunningTaskInfo> = activityManager.getRunningTasks(1)
-        return tasks.isNotEmpty() && packageName == tasks[0].topActivity.packageName
-    }
-
     companion object {
-        private const val EXTRA_CAMERA_LAUNCH_SOURCE = "com.android.systemui.camera_launch_source"
+        @VisibleForTesting
+        const val EXTRA_CAMERA_LAUNCH_SOURCE = "com.android.systemui.camera_launch_source"
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
index 3f78f97..1fa9ac5 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
@@ -74,6 +74,7 @@
         }
         mEditText.setText(clip.getItemAt(0).getText());
         mEditText.requestFocus();
+        mEditText.setSelection(0);
         mSensitive = clip.getDescription().getExtras() != null
                 && clip.getDescription().getExtras()
                 .getBoolean(ClipDescription.EXTRA_IS_SENSITIVE);
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
index 2ea5967..9e20b46 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
@@ -20,13 +20,11 @@
 import android.app.backup.BackupManager
 import android.content.BroadcastReceiver
 import android.content.ComponentName
-import android.content.ContentResolver
 import android.content.Context
 import android.content.Intent
 import android.content.IntentFilter
 import android.database.ContentObserver
 import android.net.Uri
-import android.os.Environment
 import android.os.UserHandle
 import android.service.controls.Control
 import android.service.controls.actions.ControlAction
@@ -45,6 +43,7 @@
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.people.widget.PeopleSpaceWidgetProvider.EXTRA_USER_HANDLE
+import com.android.systemui.settings.UserFileManager
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl.Companion.PREFS_CONTROLS_FILE
 import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl.Companion.PREFS_CONTROLS_SEEDING_COMPLETED
@@ -63,6 +62,7 @@
     private val bindingController: ControlsBindingController,
     private val listingController: ControlsListingController,
     private val broadcastDispatcher: BroadcastDispatcher,
+    private val userFileManager: UserFileManager,
     optionalWrapper: Optional<ControlsFavoritePersistenceWrapper>,
     dumpManager: DumpManager,
     userTracker: UserTracker
@@ -86,15 +86,12 @@
     override val currentUserId
         get() = currentUser.identifier
 
-    private val contentResolver: ContentResolver
-        get() = context.contentResolver
-
     private val persistenceWrapper: ControlsFavoritePersistenceWrapper
     @VisibleForTesting
     internal var auxiliaryPersistenceWrapper: AuxiliaryPersistenceWrapper
 
     init {
-        userStructure = UserStructure(context, currentUser)
+        userStructure = UserStructure(context, currentUser, userFileManager)
 
         persistenceWrapper = optionalWrapper.orElseGet {
             ControlsFavoritePersistenceWrapper(
@@ -113,7 +110,7 @@
     private fun setValuesForUser(newUser: UserHandle) {
         Log.d(TAG, "Changing to user: $newUser")
         currentUser = newUser
-        userStructure = UserStructure(context, currentUser)
+        userStructure = UserStructure(context, currentUser, userFileManager)
         persistenceWrapper.changeFileAndBackupManager(
                 userStructure.file,
                 BackupManager(userStructure.userContext)
@@ -189,8 +186,11 @@
 
                 // When a component is uninstalled, allow seeding to happen again if the user
                 // reinstalls the app
-                val prefs = userStructure.userContext.getSharedPreferences(
-                    PREFS_CONTROLS_FILE, Context.MODE_PRIVATE)
+                val prefs = userFileManager.getSharedPreferences(
+                    PREFS_CONTROLS_FILE,
+                    Context.MODE_PRIVATE,
+                    userTracker.userId
+                )
                 val completedSeedingPackageSet = prefs.getStringSet(
                     PREFS_CONTROLS_SEEDING_COMPLETED, mutableSetOf<String>())
                 val servicePackageSet = serviceInfoSet.map { it.packageName }
@@ -577,18 +577,12 @@
     }
 }
 
-class UserStructure(context: Context, user: UserHandle) {
+class UserStructure(context: Context, user: UserHandle, userFileManager: UserFileManager) {
     val userContext = context.createContextAsUser(user, 0)
-
-    val file = Environment.buildPath(
-            userContext.filesDir,
-            ControlsFavoritePersistenceWrapper.FILE_NAME
-    )
-
-    val auxiliaryFile = Environment.buildPath(
-            userContext.filesDir,
-            AuxiliaryPersistenceWrapper.AUXILIARY_FILE_NAME
-    )
+    val file = userFileManager.getFile(ControlsFavoritePersistenceWrapper.FILE_NAME,
+        user.identifier)
+    val auxiliaryFile = userFileManager.getFile(AuxiliaryPersistenceWrapper.AUXILIARY_FILE_NAME,
+        user.identifier)
 }
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
index 3a1b129..fd7680f 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
@@ -21,7 +21,7 @@
 import com.android.systemui.CoreStartable;
 import com.android.systemui.Dependency;
 import com.android.systemui.InitController;
-import com.android.systemui.SystemUIAppComponentFactory;
+import com.android.systemui.SystemUIAppComponentFactoryBase;
 import com.android.systemui.dagger.qualifiers.PerUser;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.keyguard.KeyguardSliceProvider;
@@ -41,16 +41,13 @@
 import com.android.wm.shell.TaskViewFactory;
 import com.android.wm.shell.back.BackAnimation;
 import com.android.wm.shell.bubbles.Bubbles;
-import com.android.wm.shell.compatui.CompatUI;
 import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
-import com.android.wm.shell.draganddrop.DragAndDrop;
-import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
 import com.android.wm.shell.onehanded.OneHanded;
 import com.android.wm.shell.pip.Pip;
 import com.android.wm.shell.recents.RecentTasks;
 import com.android.wm.shell.splitscreen.SplitScreen;
 import com.android.wm.shell.startingsurface.StartingSurface;
-import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelper;
+import com.android.wm.shell.sysui.ShellInterface;
 import com.android.wm.shell.transition.ShellTransitions;
 
 import java.util.Map;
@@ -81,6 +78,9 @@
     @Subcomponent.Builder
     interface Builder {
         @BindsInstance
+        Builder setShell(ShellInterface s);
+
+        @BindsInstance
         Builder setPip(Optional<Pip> p);
 
         @BindsInstance
@@ -96,9 +96,6 @@
         Builder setTaskViewFactory(Optional<TaskViewFactory> t);
 
         @BindsInstance
-        Builder setHideDisplayCutout(Optional<HideDisplayCutout> h);
-
-        @BindsInstance
         Builder setShellCommandHandler(Optional<ShellCommandHandler> shellDump);
 
         @BindsInstance
@@ -111,18 +108,9 @@
         Builder setDisplayAreaHelper(Optional<DisplayAreaHelper> h);
 
         @BindsInstance
-        Builder setTaskSurfaceHelper(Optional<TaskSurfaceHelper> t);
-
-        @BindsInstance
         Builder setRecentTasks(Optional<RecentTasks> r);
 
         @BindsInstance
-        Builder setCompatUI(Optional<CompatUI> s);
-
-        @BindsInstance
-        Builder setDragAndDrop(Optional<DragAndDrop> d);
-
-        @BindsInstance
         Builder setBackAnimation(Optional<BackAnimation> b);
 
         SysUIComponent build();
@@ -241,7 +229,7 @@
     /**
      * Member injection into the supplied argument.
      */
-    void inject(SystemUIAppComponentFactory factory);
+    void inject(SystemUIAppComponentFactoryBase factory);
 
     /**
      * Member injection into the supplied argument.
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
index a9f34085..6db3e82 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
@@ -33,6 +33,7 @@
 import com.android.systemui.media.RingtonePlayer
 import com.android.systemui.power.PowerUI
 import com.android.systemui.recents.Recents
+import com.android.systemui.settings.dagger.MultiUserUtilsModule
 import com.android.systemui.shortcut.ShortcutKeyDispatcher
 import com.android.systemui.statusbar.notification.InstantAppNotifier
 import com.android.systemui.statusbar.phone.KeyguardLiftController
@@ -51,7 +52,7 @@
 /**
  * Collection of {@link CoreStartable}s that should be run on AOSP.
  */
-@Module
+@Module(includes = [MultiUserUtilsModule::class])
 abstract class SystemUICoreStartableModule {
     /** Inject into AuthController.  */
     @Binds
@@ -205,4 +206,4 @@
     @IntoMap
     @ClassKey(KeyguardLiftController::class)
     abstract fun bindKeyguardLiftController(sysui: KeyguardLiftController): CoreStartable
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index ba1e057..fe96222 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -26,7 +26,6 @@
 import com.android.keyguard.dagger.KeyguardBouncerComponent;
 import com.android.systemui.BootCompleteCache;
 import com.android.systemui.BootCompleteCacheImpl;
-import com.android.systemui.SystemUIFactory;
 import com.android.systemui.appops.dagger.AppOpsModule;
 import com.android.systemui.assist.AssistModule;
 import com.android.systemui.biometrics.AlternateUdfpsTouchProvider;
@@ -43,13 +42,15 @@
 import com.android.systemui.fragments.FragmentService;
 import com.android.systemui.log.dagger.LogModule;
 import com.android.systemui.lowlightclock.LowLightClockController;
+import com.android.systemui.media.dagger.MediaProjectionModule;
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.navigationbar.NavigationBarComponent;
+import com.android.systemui.people.PeopleModule;
 import com.android.systemui.plugins.BcSmartspaceDataPlugin;
 import com.android.systemui.privacy.PrivacyModule;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.screenshot.dagger.ScreenshotModule;
-import com.android.systemui.settings.dagger.SettingsModule;
+import com.android.systemui.settings.dagger.MultiUserUtilsModule;
 import com.android.systemui.smartspace.dagger.SmartspaceModule;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -81,6 +82,7 @@
 import com.android.systemui.user.UserModule;
 import com.android.systemui.util.concurrency.SysUIConcurrencyModule;
 import com.android.systemui.util.dagger.UtilModule;
+import com.android.systemui.util.kotlin.CoroutinesModule;
 import com.android.systemui.util.sensors.SensorModule;
 import com.android.systemui.util.settings.SettingsUtilModule;
 import com.android.systemui.util.time.SystemClock;
@@ -89,6 +91,7 @@
 import com.android.systemui.wmshell.BubblesManager;
 import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.dagger.DynamicOverride;
+import com.android.wm.shell.sysui.ShellController;
 
 import java.util.Optional;
 import java.util.concurrent.Executor;
@@ -113,19 +116,22 @@
             AssistModule.class,
             BiometricsModule.class,
             ClockModule.class,
+            CoroutinesModule.class,
             DreamModule.class,
             ControlsModule.class,
             DemoModeModule.class,
             FalsingModule.class,
             FlagsModule.class,
             LogModule.class,
+            MediaProjectionModule.class,
             PeopleHubModule.class,
+            PeopleModule.class,
             PluginModule.class,
             PrivacyModule.class,
             QsFrameTranslateModule.class,
             ScreenshotModule.class,
             SensorModule.class,
-            SettingsModule.class,
+            MultiUserUtilsModule.class,
             SettingsUtilModule.class,
             SmartRepliesInflationModule.class,
             SmartspaceModule.class,
@@ -196,11 +202,6 @@
     @Binds
     abstract SystemClock bindSystemClock(SystemClockImpl systemClock);
 
-    @Provides
-    static SystemUIFactory getSystemUIFactory() {
-        return SystemUIFactory.getInstance();
-    }
-
     // TODO: This should provided by the WM component
     /** Provides Optional of BubbleManager */
     @SysUISingleton
@@ -210,7 +211,6 @@
             NotificationShadeWindowController notificationShadeWindowController,
             KeyguardStateController keyguardStateController,
             ShadeController shadeController,
-            ConfigurationController configurationController,
             @Nullable IStatusBarService statusBarService,
             INotificationManager notificationManager,
             NotificationVisibilityProvider visibilityProvider,
@@ -228,7 +228,6 @@
                 notificationShadeWindowController,
                 keyguardStateController,
                 shadeController,
-                configurationController,
                 statusBarService,
                 notificationManager,
                 visibilityProvider,
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
index 1570a7e..e4c0325 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
@@ -21,7 +21,7 @@
 
 import androidx.annotation.Nullable;
 
-import com.android.systemui.SystemUIFactory;
+import com.android.systemui.SystemUIInitializerFactory;
 import com.android.systemui.tv.TvWMComponent;
 import com.android.wm.shell.ShellCommandHandler;
 import com.android.wm.shell.ShellInit;
@@ -29,19 +29,16 @@
 import com.android.wm.shell.back.BackAnimation;
 import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.common.annotations.ShellMainThread;
-import com.android.wm.shell.compatui.CompatUI;
 import com.android.wm.shell.dagger.TvWMShellModule;
 import com.android.wm.shell.dagger.WMShellModule;
 import com.android.wm.shell.dagger.WMSingleton;
 import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
-import com.android.wm.shell.draganddrop.DragAndDrop;
-import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
 import com.android.wm.shell.onehanded.OneHanded;
 import com.android.wm.shell.pip.Pip;
 import com.android.wm.shell.recents.RecentTasks;
 import com.android.wm.shell.splitscreen.SplitScreen;
 import com.android.wm.shell.startingsurface.StartingSurface;
-import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelper;
+import com.android.wm.shell.sysui.ShellInterface;
 import com.android.wm.shell.transition.ShellTransitions;
 
 import java.util.Optional;
@@ -52,7 +49,7 @@
 /**
  * Dagger Subcomponent for WindowManager.  This class explicitly describes the interfaces exported
  * from the WM component into the SysUI component (in
- * {@link SystemUIFactory#init(Context, boolean)}), and references the specific dependencies
+ * {@link SystemUIInitializerFactory#init(Context, boolean)}), and references the specific dependencies
  * provided by its particular device/form-factor SystemUI implementation.
  *
  * ie. {@link WMComponent} includes {@link WMShellModule}
@@ -88,6 +85,9 @@
     Optional<ShellCommandHandler> getShellCommandHandler();
 
     @WMSingleton
+    ShellInterface getShell();
+
+    @WMSingleton
     Optional<OneHanded> getOneHanded();
 
     @WMSingleton
@@ -100,9 +100,6 @@
     Optional<Bubbles> getBubbles();
 
     @WMSingleton
-    Optional<HideDisplayCutout> getHideDisplayCutout();
-
-    @WMSingleton
     Optional<TaskViewFactory> getTaskViewFactory();
 
     @WMSingleton
@@ -115,17 +112,8 @@
     Optional<DisplayAreaHelper> getDisplayAreaHelper();
 
     @WMSingleton
-    Optional<TaskSurfaceHelper> getTaskSurfaceHelper();
-
-    @WMSingleton
     Optional<RecentTasks> getRecentTasks();
 
     @WMSingleton
-    Optional<CompatUI> getCompatUI();
-
-    @WMSingleton
-    Optional<DragAndDrop> getDragAndDrop();
-
-    @WMSingleton
     Optional<BackAnimation> getBackAnimation();
 }
diff --git a/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderFactory.kt b/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderFactory.kt
deleted file mode 100644
index cbed21c..0000000
--- a/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderFactory.kt
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.decor
-
-import android.content.res.Resources
-import android.util.Log
-import android.view.Display
-import android.view.DisplayCutout
-import android.view.DisplayInfo
-
-class CutoutDecorProviderFactory constructor(
-    private val res: Resources,
-    private val display: Display?,
-) : DecorProviderFactory() {
-
-    val displayInfo = DisplayInfo()
-
-    override val hasProviders: Boolean
-        get() {
-            display?.getDisplayInfo(displayInfo) ?: run {
-                Log.w(TAG, "display is null, can't update displayInfo")
-            }
-            return DisplayCutout.getFillBuiltInDisplayCutout(res, displayInfo.uniqueId)
-        }
-
-    override val providers: List<DecorProvider>
-        get() {
-            if (!hasProviders) {
-                return emptyList()
-            }
-
-            return ArrayList<DecorProvider>().also { list ->
-                // We need to update displayInfo before using it, but it has already updated during
-                // accessing hasProviders field
-                displayInfo.displayCutout?.getBoundBaseOnCurrentRotation()?.let { bounds ->
-                    for (bound in bounds) {
-                        list.add(
-                            CutoutDecorProviderImpl(bound.baseOnRotation0(displayInfo.rotation))
-                        )
-                    }
-                }
-            }
-        }
-}
-
-private const val TAG = "CutoutDecorProviderFactory"
diff --git a/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderImpl.kt
deleted file mode 100644
index 991b54e..0000000
--- a/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderImpl.kt
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.decor
-
-import android.content.Context
-import android.view.DisplayCutout
-import android.view.Surface
-import android.view.View
-import android.view.ViewGroup
-import com.android.systemui.R
-import com.android.systemui.ScreenDecorations.DisplayCutoutView
-
-class CutoutDecorProviderImpl(
-    @DisplayCutout.BoundsPosition override val alignedBound: Int
-) : BoundDecorProvider() {
-
-    override val viewId: Int = when (alignedBound) {
-        DisplayCutout.BOUNDS_POSITION_TOP -> R.id.display_cutout
-        DisplayCutout.BOUNDS_POSITION_LEFT -> R.id.display_cutout_left
-        DisplayCutout.BOUNDS_POSITION_RIGHT -> R.id.display_cutout_right
-        else -> R.id.display_cutout_bottom
-    }
-
-    override fun inflateView(
-        context: Context,
-        parent: ViewGroup,
-        @Surface.Rotation rotation: Int,
-        tintColor: Int
-    ): View {
-        return DisplayCutoutView(context, alignedBound).also { view ->
-            view.id = viewId
-            view.setColor(tintColor)
-            parent.addView(view)
-            view.updateRotation(rotation)
-        }
-    }
-
-    override fun onReloadResAndMeasure(
-        view: View,
-        reloadToken: Int,
-        @Surface.Rotation rotation: Int,
-        tintColor: Int,
-        displayUniqueId: String?
-    ) {
-        (view as? DisplayCutoutView)?.let { cutoutView ->
-            cutoutView.setColor(tintColor)
-            cutoutView.updateRotation(rotation)
-            cutoutView.onDisplayChanged(displayUniqueId)
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/decor/DecorProvider.kt b/packages/SystemUI/src/com/android/systemui/decor/DecorProvider.kt
index 260c4b5..de6d727 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/DecorProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/DecorProvider.kt
@@ -32,7 +32,7 @@
     abstract val viewId: Int
 
     /** The number of total aligned bounds */
-    val numOfAlignedBound: Int
+    val numOfAlignedEdge: Int
         get() = alignedBounds.size
 
     /** The aligned bounds for the view which is created through inflateView() */
@@ -57,8 +57,16 @@
         @Surface.Rotation rotation: Int,
         tintColor: Int
     ): View
+}
 
-    override fun toString() = "${javaClass.simpleName}{alignedBounds=$alignedBounds}"
+/**
+ * Split list to 2 list, and return it back as Pair<>. The providers on the first list contains this
+ * alignedBound element. The providers on the second list do not contain this alignedBound element
+ */
+fun List<DecorProvider>.partitionAlignedBound(
+    @DisplayCutout.BoundsPosition alignedBound: Int
+): Pair<List<DecorProvider>, List<DecorProvider>> {
+    return partition { it.alignedBounds.contains(alignedBound) }
 }
 
 /**
@@ -86,60 +94,3 @@
         listOf(alignedBound)
     }
 }
-
-/**
- * Split list to 2 list, and return it back as Pair<>. The providers on the first list contains this
- * alignedBound element. The providers on the second list do not contain this alignedBound element
- */
-fun List<DecorProvider>.partitionAlignedBound(
-    @DisplayCutout.BoundsPosition alignedBound: Int
-): Pair<List<DecorProvider>, List<DecorProvider>> {
-    return partition { it.alignedBounds.contains(alignedBound) }
-}
-
-/**
- * Get the proper bound from DecorProvider list
- * Time complexity: O(N), N is the number of providers
- *
- * Choose order
- * 1. Return null if list is empty
- * 2. If list contains BoundDecorProvider, return its alignedBound[0] because it is a must-have
- *    bound
- * 3. Return the bound with most DecorProviders
- */
-fun List<DecorProvider>.getProperBound(): Int? {
-    // Return null if list is empty
-    if (isEmpty()) {
-        return null
-    }
-
-    // Choose alignedBounds[0] of BoundDecorProvider if any
-    val singleBoundProvider = firstOrNull { it.numOfAlignedBound == 1 }
-    if (singleBoundProvider != null) {
-        return singleBoundProvider.alignedBounds[0]
-    }
-
-    // Return the bound with most DecorProviders
-    val boundCount = intArrayOf(0, 0, 0, 0)
-    for (provider in this) {
-        for (bound in provider.alignedBounds) {
-            boundCount[bound]++
-        }
-    }
-    var maxCount = 0
-    var maxCountBound: Int? = null
-    val bounds = arrayOf(
-        // Put top and bottom at first to get the highest priority to be chosen
-        DisplayCutout.BOUNDS_POSITION_TOP,
-        DisplayCutout.BOUNDS_POSITION_BOTTOM,
-        DisplayCutout.BOUNDS_POSITION_LEFT,
-        DisplayCutout.BOUNDS_POSITION_RIGHT
-    )
-    for (bound in bounds) {
-        if (boundCount[bound] > maxCount) {
-            maxCountBound = bound
-            maxCount = boundCount[bound]
-        }
-    }
-    return maxCountBound
-}
diff --git a/packages/SystemUI/src/com/android/systemui/decor/OverlayWindow.kt b/packages/SystemUI/src/com/android/systemui/decor/OverlayWindow.kt
index 45b8a08..dfb0b5a 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/OverlayWindow.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/OverlayWindow.kt
@@ -114,8 +114,7 @@
         pw.println("    rootView=$rootView")
         for (i in 0 until rootView.childCount) {
             val child = rootView.getChildAt(i)
-            val provider = viewProviderMap[child.id]?.second
-            pw.println("    child[$i]=$child $provider")
+            pw.println("    child[$i]=$child")
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 70e4fa3..7c816ce 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -26,8 +26,6 @@
 import android.text.format.Formatter;
 import android.util.Log;
 
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.doze.dagger.DozeScope;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -44,8 +42,6 @@
  */
 @DozeScope
 public class DozeUi implements DozeMachine.Part {
-    // if enabled, calls dozeTimeTick() whenever the time changes:
-    private static final boolean BURN_IN_TESTING_ENABLED = false;
     private static final long TIME_TICK_DEADLINE_MILLIS = 90 * 1000; // 1.5min
     private final Context mContext;
     private final DozeHost mHost;
@@ -57,26 +53,13 @@
     private final DozeParameters mDozeParameters;
     private final DozeLog mDozeLog;
     private final StatusBarStateController mStatusBarStateController;
-    private final KeyguardUpdateMonitorCallback mKeyguardVisibilityCallback =
-            new KeyguardUpdateMonitorCallback() {
-                @Override
-                public void onTimeChanged() {
-                    if (BURN_IN_TESTING_ENABLED && mStatusBarStateController.isDozing()) {
-                        // update whenever the time changes for manual burn in testing
-                        mHost.dozeTimeTick();
-
-                        // Keep wakelock until a frame has been pushed.
-                        mHandler.post(mWakeLock.wrap(() -> {}));
-                    }
-                }
-            };
 
     private long mLastTimeTickElapsed = 0;
 
     @Inject
     public DozeUi(Context context, AlarmManager alarmManager,
             WakeLock wakeLock, DozeHost host, @Main Handler handler,
-            DozeParameters params, KeyguardUpdateMonitor keyguardUpdateMonitor,
+            DozeParameters params,
             StatusBarStateController statusBarStateController,
             DozeLog dozeLog) {
         mContext = context;
@@ -86,7 +69,6 @@
         mCanAnimateTransition = !params.getDisplayNeedsBlanking();
         mDozeParameters = params;
         mTimeTicker = new AlarmTimeout(alarmManager, this::onTimeTick, "doze_time_tick", handler);
-        keyguardUpdateMonitor.registerCallback(mKeyguardVisibilityCallback);
         mDozeLog = dozeLog;
         mStatusBarStateController = statusBarStateController;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
index 59a17ba..a25257d 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
@@ -43,6 +43,8 @@
             STATUS_ICON_NOTIFICATIONS,
             STATUS_ICON_WIFI_UNAVAILABLE,
             STATUS_ICON_ALARM_SET,
+            STATUS_ICON_CAMERA_DISABLED,
+            STATUS_ICON_MIC_DISABLED,
             STATUS_ICON_MIC_CAMERA_DISABLED,
             STATUS_ICON_PRIORITY_MODE_ON
     })
@@ -50,8 +52,10 @@
     public static final int STATUS_ICON_NOTIFICATIONS = 0;
     public static final int STATUS_ICON_WIFI_UNAVAILABLE = 1;
     public static final int STATUS_ICON_ALARM_SET = 2;
-    public static final int STATUS_ICON_MIC_CAMERA_DISABLED = 3;
-    public static final int STATUS_ICON_PRIORITY_MODE_ON = 4;
+    public static final int STATUS_ICON_CAMERA_DISABLED = 3;
+    public static final int STATUS_ICON_MIC_DISABLED = 4;
+    public static final int STATUS_ICON_MIC_CAMERA_DISABLED = 5;
+    public static final int STATUS_ICON_PRIORITY_MODE_ON = 6;
 
     private final Map<Integer, View> mStatusIcons = new HashMap<>();
 
@@ -80,6 +84,10 @@
                 fetchStatusIconForResId(R.id.dream_overlay_wifi_status));
         mStatusIcons.put(STATUS_ICON_ALARM_SET,
                 fetchStatusIconForResId(R.id.dream_overlay_alarm_set));
+        mStatusIcons.put(STATUS_ICON_CAMERA_DISABLED,
+                fetchStatusIconForResId(R.id.dream_overlay_camera_off));
+        mStatusIcons.put(STATUS_ICON_MIC_DISABLED,
+                fetchStatusIconForResId(R.id.dream_overlay_mic_off));
         mStatusIcons.put(STATUS_ICON_MIC_CAMERA_DISABLED,
                 fetchStatusIconForResId(R.id.dream_overlay_camera_mic_off));
         mStatusIcons.put(STATUS_ICON_NOTIFICATIONS,
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
index 250313d..de7bf28 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
@@ -214,9 +214,17 @@
                 .isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE);
         final boolean cameraBlocked = mSensorPrivacyController
                 .isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA);
-        showIcon(
-                DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED,
-                micBlocked && cameraBlocked);
+        @DreamOverlayStatusBarView.StatusIconType int iconType = Resources.ID_NULL;
+        if (micBlocked && cameraBlocked) {
+            iconType = DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED;
+        } else if (!micBlocked && cameraBlocked) {
+            iconType = DreamOverlayStatusBarView.STATUS_ICON_CAMERA_DISABLED;
+        } else if (micBlocked && !cameraBlocked) {
+            iconType = DreamOverlayStatusBarView.STATUS_ICON_MIC_DISABLED;
+        }
+        if (iconType != Resources.ID_NULL) {
+            showIcon(iconType, true);
+        }
     }
 
     private String buildNotificationsContentDescription(int notificationCount) {
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/AirQualityColorPicker.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/AirQualityColorPicker.java
deleted file mode 100644
index 328753f..0000000
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/AirQualityColorPicker.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.dreams.complication;
-
-import static com.android.systemui.dreams.complication.dagger.DreamAirQualityComplicationComponent.DreamAirQualityComplicationModule.DREAM_AQI_COLOR_DEFAULT;
-import static com.android.systemui.dreams.complication.dagger.DreamAirQualityComplicationComponent.DreamAirQualityComplicationModule.DREAM_AQI_COLOR_THRESHOLDS;
-import static com.android.systemui.dreams.complication.dagger.DreamAirQualityComplicationComponent.DreamAirQualityComplicationModule.DREAM_AQI_COLOR_VALUES;
-
-import android.util.Log;
-
-import androidx.annotation.ColorInt;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-
-final class AirQualityColorPicker {
-    private static final String TAG = "AirQualityColorPicker";
-    private final int[] mThresholds;
-    private final int[] mColorValues;
-    private final int mDefaultColor;
-
-    @Inject
-    AirQualityColorPicker(@Named(DREAM_AQI_COLOR_THRESHOLDS) int[] thresholds,
-            @Named(DREAM_AQI_COLOR_VALUES) int[] colorValues,
-            @Named(DREAM_AQI_COLOR_DEFAULT) @ColorInt int defaultColor) {
-        mThresholds = thresholds;
-        mColorValues = colorValues;
-        mDefaultColor = defaultColor;
-    }
-
-    @ColorInt
-    int getColorForValue(String aqiString) {
-        int size = mThresholds.length;
-        if (mThresholds.length != mColorValues.length) {
-            size = Math.min(mThresholds.length, mColorValues.length);
-            Log.e(TAG,
-                    "Threshold size ("
-                            + mThresholds.length + ") does not match color value size ("
-                            + mColorValues.length
-                            + "). Taking the minimum, some values may be ignored.");
-
-        }
-        try {
-            final int value = Integer.parseInt(aqiString.replaceAll("[^0-9]", ""));
-            for (int i = size - 1; i >= 0; i--) {
-                if (value > mThresholds[i]) {
-                    return mColorValues[i];
-                }
-            }
-            Log.e(TAG, "No matching AQI color for value: " + value);
-        } catch (NumberFormatException e) {
-            Log.e(TAG, "Could not read AQI value from:" + aqiString);
-        }
-        return mDefaultColor;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamAirQualityComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamAirQualityComplication.java
deleted file mode 100644
index ba63303..0000000
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamAirQualityComplication.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.dreams.complication;
-
-import static com.android.systemui.dreams.complication.dagger.DreamAirQualityComplicationComponent.DreamAirQualityComplicationModule.DREAM_AQI_COMPLICATION_LAYOUT_PARAMS;
-import static com.android.systemui.dreams.complication.dagger.DreamAirQualityComplicationComponent.DreamAirQualityComplicationModule.DREAM_AQI_COMPLICATION_VIEW;
-import static com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule.SMARTSPACE_TRAMPOLINE_ACTIVITY_COMPONENT;
-
-import android.app.smartspace.SmartspaceAction;
-import android.app.smartspace.SmartspaceTarget;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.GradientDrawable;
-import android.graphics.drawable.ShapeDrawable;
-import android.text.TextUtils;
-import android.view.View;
-import android.widget.TextView;
-
-import androidx.annotation.Nullable;
-
-import com.android.systemui.CoreStartable;
-import com.android.systemui.dreams.DreamOverlayStateController;
-import com.android.systemui.dreams.complication.dagger.DreamAirQualityComplicationComponent;
-import com.android.systemui.dreams.smartspace.DreamSmartspaceController;
-import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceTargetListener;
-import com.android.systemui.util.ViewController;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-
-/**
- * Air quality complication which produces view holder responsible for showing AQI over dreams.
- */
-public class DreamAirQualityComplication implements Complication {
-    // TODO(b/236024839): Move to SmartspaceTarget
-    public static final int FEATURE_AIR_QUALITY = 46;
-
-    private final DreamAirQualityComplicationComponent.Factory mComponentFactory;
-
-    @Inject
-    public DreamAirQualityComplication(
-            DreamAirQualityComplicationComponent.Factory componentFactory) {
-        mComponentFactory = componentFactory;
-    }
-
-    @Override
-    public int getRequiredTypeAvailability() {
-        return COMPLICATION_TYPE_AIR_QUALITY;
-    }
-
-    @Override
-    public ViewHolder createView(ComplicationViewModel model) {
-        return mComponentFactory.create().getViewHolder();
-    }
-
-    /**
-     * {@link CoreStartable} for registering {@link DreamAirQualityComplication} with SystemUI.
-     */
-    public static class Registrant extends CoreStartable {
-        private final DreamOverlayStateController mDreamOverlayStateController;
-        private final DreamAirQualityComplication mComplication;
-
-        /**
-         * Default constructor to register {@link DreamAirQualityComplication}.
-         */
-        @Inject
-        public Registrant(Context context,
-                DreamOverlayStateController dreamOverlayStateController,
-                DreamAirQualityComplication complication) {
-            super(context);
-            mDreamOverlayStateController = dreamOverlayStateController;
-            mComplication = complication;
-        }
-
-        @Override
-        public void start() {
-            // TODO(b/221500478): Only add complication once we have data to show.
-            mDreamOverlayStateController.addComplication(mComplication);
-        }
-    }
-
-    /**
-     * ViewHolder to contain value/logic associated with the AQI complication view.
-     */
-    public static class DreamAirQualityViewHolder implements ViewHolder {
-        private final TextView mView;
-        private final DreamAirQualityViewController mController;
-        private final ComplicationLayoutParams mLayoutParams;
-
-        @Inject
-        DreamAirQualityViewHolder(@Named(DREAM_AQI_COMPLICATION_VIEW) TextView view,
-                DreamAirQualityViewController controller,
-                @Named(DREAM_AQI_COMPLICATION_LAYOUT_PARAMS)
-                        ComplicationLayoutParams layoutParams) {
-            mView = view;
-            mLayoutParams = layoutParams;
-            mController = controller;
-            mController.init();
-        }
-
-        @Override
-        public View getView() {
-            return mView;
-        }
-
-        @Override
-        public ComplicationLayoutParams getLayoutParams() {
-            return mLayoutParams;
-        }
-    }
-
-    static class DreamAirQualityViewController extends ViewController<TextView> {
-        private final DreamSmartspaceController mSmartspaceController;
-        private final String mSmartspaceTrampolineComponent;
-        private final ActivityStarter mActivityStarter;
-        private final AirQualityColorPicker mAirQualityColorPicker;
-
-        private final SmartspaceTargetListener mSmartspaceTargetListener = targets -> {
-            final SmartspaceTarget target = targets.stream()
-                    .filter(t -> t instanceof SmartspaceTarget)
-                    .map(t -> (SmartspaceTarget) t)
-                    .filter(t -> t.getFeatureType() == FEATURE_AIR_QUALITY)
-                    .findFirst()
-                    .orElse(null);
-            updateView(target);
-        };
-
-        @Inject
-        DreamAirQualityViewController(@Named(DREAM_AQI_COMPLICATION_VIEW) TextView view,
-                DreamSmartspaceController smartspaceController,
-                @Named(SMARTSPACE_TRAMPOLINE_ACTIVITY_COMPONENT)
-                        String smartspaceTrampolineComponent,
-                ActivityStarter activityStarter,
-                AirQualityColorPicker airQualityColorPicker) {
-            super(view);
-            mSmartspaceController = smartspaceController;
-            mSmartspaceTrampolineComponent = smartspaceTrampolineComponent;
-            mActivityStarter = activityStarter;
-            mAirQualityColorPicker = airQualityColorPicker;
-        }
-
-        @Override
-        protected void onViewAttached() {
-            mSmartspaceController.addUnfilteredListener(mSmartspaceTargetListener);
-        }
-
-        @Override
-        protected void onViewDetached() {
-            mSmartspaceController.removeUnfilteredListener(mSmartspaceTargetListener);
-        }
-
-        private void updateView(@Nullable SmartspaceTarget target) {
-            final SmartspaceAction headerAction = target == null ? null : target.getHeaderAction();
-            if (headerAction == null || TextUtils.isEmpty(headerAction.getTitle())) {
-                mView.setVisibility(View.GONE);
-                return;
-            }
-            mView.setVisibility(View.VISIBLE);
-
-            final String airQuality = headerAction.getTitle().toString();
-            mView.setText(airQuality);
-
-            final Drawable background = mView.getBackground().mutate();
-            final int color = mAirQualityColorPicker.getColorForValue(airQuality);
-
-            if (background instanceof ShapeDrawable) {
-                ((ShapeDrawable) background).getPaint().setColor(color);
-            } else if (background instanceof GradientDrawable) {
-                ((GradientDrawable) background).setColor(color);
-            }
-            mView.setBackground(background);
-
-            final Intent intent = headerAction.getIntent();
-            if (intent != null && intent.getComponent() != null
-                    && intent.getComponent().getClassName().equals(
-                    mSmartspaceTrampolineComponent)) {
-                mView.setOnClickListener(v -> {
-                    mActivityStarter.postStartActivityDismissingKeyguard(intent, /* delay= */ 0);
-                });
-            }
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java
deleted file mode 100644
index 4eae3b92..0000000
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.dreams.complication;
-
-import static com.android.systemui.dreams.complication.dagger.DreamWeatherComplicationComponent.DreamWeatherComplicationModule.DREAM_WEATHER_COMPLICATION_LAYOUT_PARAMS;
-import static com.android.systemui.dreams.complication.dagger.DreamWeatherComplicationComponent.DreamWeatherComplicationModule.DREAM_WEATHER_COMPLICATION_VIEW;
-import static com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule.SMARTSPACE_TRAMPOLINE_ACTIVITY_COMPONENT;
-
-import android.app.smartspace.SmartspaceAction;
-import android.app.smartspace.SmartspaceTarget;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.Icon;
-import android.text.TextUtils;
-import android.widget.TextView;
-
-import com.android.systemui.CoreStartable;
-import com.android.systemui.R;
-import com.android.systemui.dreams.DreamOverlayStateController;
-import com.android.systemui.dreams.complication.dagger.DreamWeatherComplicationComponent;
-import com.android.systemui.dreams.smartspace.DreamSmartspaceController;
-import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceTargetListener;
-import com.android.systemui.util.ViewController;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-
-/**
- * Weather Complication that produce Weather view holder.
- */
-public class DreamWeatherComplication implements Complication {
-    DreamWeatherComplicationComponent.Factory mComponentFactory;
-
-    /**
-     * Default constructor for {@link DreamWeatherComplication}.
-     */
-    @Inject
-    public DreamWeatherComplication(
-            DreamWeatherComplicationComponent.Factory componentFactory) {
-        mComponentFactory = componentFactory;
-    }
-
-    @Override
-    public int getRequiredTypeAvailability() {
-        return COMPLICATION_TYPE_WEATHER;
-    }
-
-    /**
-     * Create {@link DreamWeatherViewHolder}.
-     */
-    @Override
-    public ViewHolder createView(ComplicationViewModel model) {
-        return mComponentFactory.create().getViewHolder();
-    }
-
-    /**
-     * {@link CoreStartable} for registering {@link DreamWeatherComplication} with SystemUI.
-     */
-    public static class Registrant extends CoreStartable {
-        private final DreamOverlayStateController mDreamOverlayStateController;
-        private final DreamWeatherComplication mComplication;
-
-        /**
-         * Default constructor to register {@link DreamWeatherComplication}.
-         */
-        @Inject
-        public Registrant(Context context,
-                DreamOverlayStateController dreamOverlayStateController,
-                DreamWeatherComplication dreamWeatherComplication) {
-            super(context);
-            mDreamOverlayStateController = dreamOverlayStateController;
-            mComplication = dreamWeatherComplication;
-        }
-
-        @Override
-        public void start() {
-            mDreamOverlayStateController.addComplication(mComplication);
-        }
-    }
-
-    /**
-     * ViewHolder to contain value/logic associated with a Weather Complication View.
-     */
-    public static class DreamWeatherViewHolder implements ViewHolder {
-        private final TextView mView;
-        private final ComplicationLayoutParams mLayoutParams;
-        private final DreamWeatherViewController mViewController;
-
-        @Inject
-        DreamWeatherViewHolder(
-                @Named(DREAM_WEATHER_COMPLICATION_VIEW) TextView view,
-                DreamWeatherViewController controller,
-                @Named(DREAM_WEATHER_COMPLICATION_LAYOUT_PARAMS)
-                        ComplicationLayoutParams layoutParams) {
-            mView = view;
-            mLayoutParams = layoutParams;
-            mViewController = controller;
-            mViewController.init();
-        }
-
-        @Override
-        public TextView getView() {
-            return mView;
-        }
-
-        @Override
-        public ComplicationLayoutParams getLayoutParams() {
-            return mLayoutParams;
-        }
-    }
-
-    /**
-     * ViewController to contain value/logic associated with a Weather Complication View.
-     */
-    static class DreamWeatherViewController extends ViewController<TextView> {
-        private final DreamSmartspaceController mSmartSpaceController;
-        private final ActivityStarter mActivityStarter;
-        private final String mSmartspaceTrampolineActivityComponent;
-        private SmartspaceTargetListener mSmartspaceTargetListener;
-
-        @Inject
-        DreamWeatherViewController(
-                @Named(DREAM_WEATHER_COMPLICATION_VIEW) TextView view,
-                @Named(SMARTSPACE_TRAMPOLINE_ACTIVITY_COMPONENT) String smartspaceTrampoline,
-                ActivityStarter activityStarter,
-                DreamSmartspaceController smartspaceController
-        ) {
-            super(view);
-            mActivityStarter = activityStarter;
-            mSmartSpaceController = smartspaceController;
-            mSmartspaceTrampolineActivityComponent = smartspaceTrampoline;
-        }
-
-        @Override
-        protected void onViewAttached() {
-            mSmartspaceTargetListener = targets -> targets.forEach(
-                    t -> {
-                        if (t instanceof SmartspaceTarget
-                                && ((SmartspaceTarget) t).getFeatureType()
-                                == SmartspaceTarget.FEATURE_WEATHER) {
-                            final SmartspaceTarget target = (SmartspaceTarget) t;
-                            final SmartspaceAction headerAction = target.getHeaderAction();
-                            if (headerAction == null || TextUtils.isEmpty(
-                                    headerAction.getTitle())) {
-                                return;
-                            }
-
-                            String temperature = headerAction.getTitle().toString();
-                            mView.setText(temperature);
-                            final Icon icon = headerAction.getIcon();
-                            if (icon != null) {
-                                final int iconSize =
-                                        getResources().getDimensionPixelSize(
-                                                R.dimen.smart_action_button_icon_size);
-                                final Drawable iconDrawable = icon.loadDrawable(getContext());
-                                iconDrawable.setBounds(0, 0, iconSize, iconSize);
-                                mView.setCompoundDrawables(iconDrawable, null, null, null);
-                                mView.setCompoundDrawablePadding(
-                                        getResources().getDimensionPixelSize(
-                                                R.dimen.smart_action_button_icon_padding));
-
-                            }
-                            mView.setOnClickListener(v -> {
-                                final Intent intent = headerAction.getIntent();
-                                if (intent != null && intent.getComponent() != null
-                                        && intent.getComponent().getClassName()
-                                        .equals(mSmartspaceTrampolineActivityComponent)) {
-                                    mActivityStarter.postStartActivityDismissingKeyguard(
-                                            intent, 0 /*delay*/);
-                                }
-                            });
-                        }
-                    });
-            // We need to use an unfiltered listener here since weather is filtered from showing
-            // in the dream smartspace.
-            mSmartSpaceController.addUnfilteredListener(mSmartspaceTargetListener);
-        }
-
-        @Override
-        protected void onViewDetached() {
-            mSmartSpaceController.removeUnfilteredListener(mSmartspaceTargetListener);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamAirQualityComplicationComponent.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamAirQualityComplicationComponent.java
deleted file mode 100644
index 112a1ce..0000000
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamAirQualityComplicationComponent.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.dreams.complication.dagger;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.view.LayoutInflater;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import androidx.annotation.ColorInt;
-
-import com.android.systemui.R;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.dreams.complication.ComplicationLayoutParams;
-import com.android.systemui.dreams.complication.DreamAirQualityComplication;
-import com.android.systemui.dreams.complication.DreamAirQualityComplication.DreamAirQualityViewHolder;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-import javax.inject.Named;
-import javax.inject.Scope;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-
-/**
- * Component responsible for generating dependencies for the {@link DreamAirQualityComplication},
- * such as the layout details.
- */
-@Subcomponent(modules = {
-        DreamAirQualityComplicationComponent.DreamAirQualityComplicationModule.class,
-})
-@DreamAirQualityComplicationComponent.DreamAirQualityComplicationScope
-public interface DreamAirQualityComplicationComponent {
-
-    @Documented
-    @Retention(RetentionPolicy.RUNTIME)
-    @Scope
-    @interface DreamAirQualityComplicationScope {
-    }
-
-    /**
-     * Generates {@link DreamAirQualityComplicationComponent}.
-     */
-    @Subcomponent.Factory
-    interface Factory {
-        DreamAirQualityComplicationComponent create();
-    }
-
-    /**
-     * Creates {@link DreamAirQualityViewHolder}.
-     */
-    DreamAirQualityViewHolder getViewHolder();
-
-    /**
-     * Scoped values for {@link DreamAirQualityComplicationComponent}.
-     */
-    @Module
-    interface DreamAirQualityComplicationModule {
-        String DREAM_AQI_COMPLICATION_VIEW = "aqi_complication_view";
-        String DREAM_AQI_COMPLICATION_LAYOUT_PARAMS = "aqi_complication_layout_params";
-        String DREAM_AQI_COLOR_THRESHOLDS = "aqi_color_thresholds";
-        String DREAM_AQI_COLOR_VALUES = "aqi_color_values";
-        String DREAM_AQI_COLOR_DEFAULT = "aqi_color_default";
-        // Order weight of insert into parent container
-        int INSERT_ORDER_WEIGHT = 1;
-
-        /**
-         * Provides the complication view.
-         */
-        @Provides
-        @DreamAirQualityComplicationScope
-        @Named(DREAM_AQI_COMPLICATION_VIEW)
-        static TextView provideComplicationView(LayoutInflater layoutInflater) {
-            return Objects.requireNonNull((TextView)
-                            layoutInflater.inflate(R.layout.dream_overlay_complication_aqi,
-                                    null, false),
-                    "R.layout.dream_overlay_complication_aqi did not properly inflated");
-        }
-
-        /**
-         * Provides the layout parameters for the complication view.
-         */
-        @Provides
-        @DreamAirQualityComplicationScope
-        @Named(DREAM_AQI_COMPLICATION_LAYOUT_PARAMS)
-        static ComplicationLayoutParams provideLayoutParams() {
-            return new ComplicationLayoutParams(0,
-                    ViewGroup.LayoutParams.WRAP_CONTENT,
-                    ComplicationLayoutParams.POSITION_BOTTOM
-                            | ComplicationLayoutParams.POSITION_START,
-                    ComplicationLayoutParams.DIRECTION_END,
-                    INSERT_ORDER_WEIGHT, /* snapToGuide= */ true);
-        }
-
-        @Provides
-        @DreamAirQualityComplicationScope
-        @Named(DREAM_AQI_COLOR_THRESHOLDS)
-        static int[] provideAqiColorThresholds(@Main Resources resources) {
-            return resources.getIntArray(R.array.config_dreamAqiThresholds);
-        }
-
-        @Provides
-        @DreamAirQualityComplicationScope
-        @Named(DREAM_AQI_COLOR_VALUES)
-        static int[] provideAqiColorValues(@Main Resources resources) {
-            return resources.getIntArray(R.array.config_dreamAqiColorValues);
-        }
-
-        @Provides
-        @DreamAirQualityComplicationScope
-        @Named(DREAM_AQI_COLOR_DEFAULT)
-        @ColorInt
-        static int provideDefaultAqiColor(Context context) {
-            return context.getColor(R.color.dream_overlay_aqi_unknown);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamWeatherComplicationComponent.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamWeatherComplicationComponent.java
deleted file mode 100644
index 7ab3ad1..0000000
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamWeatherComplicationComponent.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.dreams.complication.dagger;
-
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import android.view.LayoutInflater;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import com.android.internal.util.Preconditions;
-import com.android.systemui.R;
-import com.android.systemui.dreams.complication.ComplicationLayoutParams;
-import com.android.systemui.dreams.complication.DreamWeatherComplication.DreamWeatherViewHolder;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import javax.inject.Named;
-import javax.inject.Scope;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-
-/**
- * {@link DreamWeatherComplicationComponent} is responsible for generating dependencies surrounding
- * the
- * Clock Date {@link com.android.systemui.dreams.complication.Complication}, such as the layout
- * details.
- */
-@Subcomponent(modules = {
-        DreamWeatherComplicationComponent.DreamWeatherComplicationModule.class,
-})
-@DreamWeatherComplicationComponent.DreamWeatherComplicationScope
-public interface DreamWeatherComplicationComponent {
-    /**
-     * Creates {@link DreamWeatherViewHolder}.
-     */
-    DreamWeatherViewHolder getViewHolder();
-
-    @Documented
-    @Retention(RUNTIME)
-    @Scope
-    @interface DreamWeatherComplicationScope {
-    }
-
-    /**
-     * Generates {@link DreamWeatherComplicationComponent}.
-     */
-    @Subcomponent.Factory
-    interface Factory {
-        DreamWeatherComplicationComponent create();
-    }
-
-    /**
-     * Scoped values for {@link DreamWeatherComplicationComponent}.
-     */
-    @Module
-    interface DreamWeatherComplicationModule {
-        String DREAM_WEATHER_COMPLICATION_VIEW = "weather_complication_view";
-        String DREAM_WEATHER_COMPLICATION_LAYOUT_PARAMS =
-                "weather_complication_layout_params";
-        // Order weight of insert into parent container
-        int INSERT_ORDER_WEIGHT = 2;
-
-        /**
-         * Provides the complication view.
-         */
-        @Provides
-        @DreamWeatherComplicationScope
-        @Named(DREAM_WEATHER_COMPLICATION_VIEW)
-        static TextView provideComplicationView(LayoutInflater layoutInflater) {
-            return Preconditions.checkNotNull((TextView)
-                            layoutInflater.inflate(R.layout.dream_overlay_complication_weather,
-                                    null, false),
-                    "R.layout.dream_overlay_complication_weather did not properly inflated");
-        }
-
-        /**
-         * Provides the layout parameters for the complication view.
-         */
-        @Provides
-        @DreamWeatherComplicationScope
-        @Named(DREAM_WEATHER_COMPLICATION_LAYOUT_PARAMS)
-        static ComplicationLayoutParams provideLayoutParams() {
-            return new ComplicationLayoutParams(0,
-                    ViewGroup.LayoutParams.WRAP_CONTENT,
-                    ComplicationLayoutParams.POSITION_BOTTOM
-                            | ComplicationLayoutParams.POSITION_START,
-                    ComplicationLayoutParams.DIRECTION_END,
-                    INSERT_ORDER_WEIGHT, /* snapToGuide= */ true);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/RegisteredComplicationsModule.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/RegisteredComplicationsModule.java
index 98344aa..e45437d 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/RegisteredComplicationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/RegisteredComplicationsModule.java
@@ -16,15 +16,9 @@
 
 package com.android.systemui.dreams.complication.dagger;
 
-import android.content.Context;
-
-import com.android.systemui.R;
 import com.android.systemui.dagger.SystemUIBinder;
 
-import javax.inject.Named;
-
 import dagger.Module;
-import dagger.Provides;
 
 /**
  * Module for all components with corresponding dream layer complications registered in
@@ -33,20 +27,6 @@
 @Module(includes = {
                 DreamClockDateComplicationModule.class,
                 DreamClockTimeComplicationModule.class,
-        },
-        subcomponents = {
-                DreamWeatherComplicationComponent.class,
-                DreamAirQualityComplicationComponent.class,
         })
 public interface RegisteredComplicationsModule {
-    String SMARTSPACE_TRAMPOLINE_ACTIVITY_COMPONENT = "smartspace_trampoline_activity";
-
-    /**
-     * Provides the smartspace trampoline activity component.
-     */
-    @Provides
-    @Named(SMARTSPACE_TRAMPOLINE_ACTIVITY_COMPONENT)
-    static String provideSmartspaceTrampolineActivityComponent(Context context) {
-        return context.getString(R.string.config_smartspaceTrampolineActivityComponent);
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
index 2fa104a..a553e19 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
@@ -145,6 +145,9 @@
     public static final ResourceBooleanFlag STATUS_BAR_USER_SWITCHER =
             new ResourceBooleanFlag(602, R.bool.flag_user_switcher_chip);
 
+    public static final BooleanFlag STATUS_BAR_LETTERBOX_APPEARANCE =
+            new BooleanFlag(603, false);
+
     /***************************************/
     // 700 - dialer/calls
     public static final BooleanFlag ONGOING_CALL_STATUS_BAR_CHIP =
@@ -176,7 +179,7 @@
     // 1000 - dock
     public static final BooleanFlag SIMULATE_DOCK_THROUGH_CHARGING =
             new BooleanFlag(1000, true);
-    public static final BooleanFlag DOCK_SETUP_ENABLED = new BooleanFlag(1001, false);
+    public static final BooleanFlag DOCK_SETUP_ENABLED = new BooleanFlag(1001, true);
 
 
     // 1100 - windowing
@@ -207,7 +210,8 @@
     public static final SysPropBooleanFlag WM_ALWAYS_ENFORCE_PREDICTIVE_BACK =
             new SysPropBooleanFlag(1202, "persist.wm.debug.predictive_back_always_enforce", false);
 
-    public static final BooleanFlag NEW_BACK_AFFORDANCE = new BooleanFlag(1203, true);
+    public static final BooleanFlag NEW_BACK_AFFORDANCE =
+            new BooleanFlag(1203, false /* default */, true /* teamfood */);
 
     // Pay no attention to the reflection behind the curtain.
     // ========================== Curtain ==========================
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index c6da7d9..7ddce62 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -122,6 +122,7 @@
 import com.android.systemui.keyguard.dagger.KeyguardModule;
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationShadeDepthController;
@@ -131,7 +132,6 @@
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.phone.NotificationPanelViewController;
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -556,15 +556,6 @@
         }
 
         @Override
-        public void onUserInfoChanged(int userId) {
-        }
-
-        @Override
-        public void onClockVisibilityChanged() {
-            adjustStatusBarLocked();
-        }
-
-        @Override
         public void onDeviceProvisioned() {
             sendUserPresentBroadcast();
             synchronized (KeyguardViewMediator.this) {
@@ -1197,6 +1188,7 @@
             mSystemReady = true;
             doKeyguardLocked(null);
             mUpdateMonitor.registerCallback(mUpdateCallback);
+            adjustStatusBarLocked();
             mDreamOverlayStateController.addCallback(mDreamOverlayStateCallback);
         }
         // Most services aren't available until the system reaches the ready state, so we
@@ -2701,7 +2693,7 @@
     /** Hides the surface behind the keyguard by re-showing the keyguard/activity lock screen. */
     public void hideSurfaceBehindKeyguard() {
         mSurfaceBehindRemoteAnimationRequested = false;
-
+        mKeyguardStateController.notifyKeyguardGoingAway(false);
         if (mShowing) {
             setShowingLocked(true, true);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/lifecycle/WindowAddedViewLifecycleOwner.kt b/packages/SystemUI/src/com/android/systemui/lifecycle/WindowAddedViewLifecycleOwner.kt
new file mode 100644
index 0000000..55c7ac9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/lifecycle/WindowAddedViewLifecycleOwner.kt
@@ -0,0 +1,114 @@
+package com.android.systemui.lifecycle
+
+import android.view.View
+import android.view.ViewTreeObserver
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.LifecycleRegistry
+
+/**
+ * [LifecycleOwner] for Window-added Views.
+ *
+ * These are [View] instances that are added to a `Window` using the `WindowManager` API.
+ *
+ * This implementation goes to:
+ * * The <b>CREATED</b> `Lifecycle.State` when the view gets attached to the window but the window
+ * is not yet visible
+ * * The <b>STARTED</b> `Lifecycle.State` when the view is attached to the window and the window is
+ * visible
+ * * The <b>RESUMED</b> `Lifecycle.State` when the view is attached to the window and the window is
+ * visible and the window receives focus
+ *
+ * In table format:
+ * ```
+ * | ----------------------------------------------------------------------------- |
+ * | View attached to window | Window visible | Window has focus | Lifecycle state |
+ * | ----------------------------------------------------------------------------- |
+ * |       not attached      |               Any                 |   INITIALIZED   |
+ * | ----------------------------------------------------------------------------- |
+ * |                         |  not visible   |       Any        |     CREATED     |
+ * |                         ----------------------------------------------------- |
+ * |        attached         |                |    not focused   |     STARTED     |
+ * |                         |   is visible   |----------------------------------- |
+ * |                         |                |    has focus     |     RESUMED     |
+ * | ----------------------------------------------------------------------------- |
+ * ```
+ * ### Notes
+ * * [dispose] must be invoked when the [LifecycleOwner] is done and won't be reused
+ * * It is always better for [LifecycleOwner] implementations to be more explicit than just
+ * listening to the state of the `Window`. E.g. if the code that added the `View` to the `Window`
+ * already has access to the correct state to know when that `View` should become visible and when
+ * it is ready to receive interaction from the user then it already knows when to move to `STARTED`
+ * and `RESUMED`, respectively. In that case, it's better to implement your own `LifecycleOwner`
+ * instead of relying on the `Window` callbacks.
+ */
+class WindowAddedViewLifecycleOwner
+@JvmOverloads
+constructor(
+    private val view: View,
+    registryFactory: (LifecycleOwner) -> LifecycleRegistry = { LifecycleRegistry(it) },
+) : LifecycleOwner {
+
+    private val windowAttachListener =
+        object : ViewTreeObserver.OnWindowAttachListener {
+            override fun onWindowAttached() {
+                updateCurrentState()
+            }
+
+            override fun onWindowDetached() {
+                updateCurrentState()
+            }
+        }
+    private val windowFocusListener =
+        ViewTreeObserver.OnWindowFocusChangeListener { updateCurrentState() }
+    private val windowVisibilityListener =
+        ViewTreeObserver.OnWindowVisibilityChangeListener { updateCurrentState() }
+
+    private val registry = registryFactory(this)
+
+    init {
+        setCurrentState(Lifecycle.State.INITIALIZED)
+
+        with(view.viewTreeObserver) {
+            addOnWindowAttachListener(windowAttachListener)
+            addOnWindowVisibilityChangeListener(windowVisibilityListener)
+            addOnWindowFocusChangeListener(windowFocusListener)
+        }
+
+        updateCurrentState()
+    }
+
+    override fun getLifecycle(): Lifecycle {
+        return registry
+    }
+
+    /**
+     * Disposes of this [LifecycleOwner], performing proper clean-up.
+     *
+     * <p>Invoke this when the instance is finished and won't be reused.
+     */
+    fun dispose() {
+        with(view.viewTreeObserver) {
+            removeOnWindowAttachListener(windowAttachListener)
+            removeOnWindowVisibilityChangeListener(windowVisibilityListener)
+            removeOnWindowFocusChangeListener(windowFocusListener)
+        }
+    }
+
+    private fun updateCurrentState() {
+        val state =
+            when {
+                !view.isAttachedToWindow -> Lifecycle.State.INITIALIZED
+                view.windowVisibility != View.VISIBLE -> Lifecycle.State.CREATED
+                !view.hasWindowFocus() -> Lifecycle.State.STARTED
+                else -> Lifecycle.State.RESUMED
+            }
+        setCurrentState(state)
+    }
+
+    private fun setCurrentState(state: Lifecycle.State) {
+        if (registry.currentState != state) {
+            registry.currentState = state
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 1ed65b3..012d766 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -682,9 +682,22 @@
             Drawable artwork;
             boolean isArtworkBound;
             Icon artworkIcon = data.getArtwork();
+            WallpaperColors wallpaperColors = null;
             if (artworkIcon != null) {
-                WallpaperColors wallpaperColors = WallpaperColors
-                        .fromBitmap(artworkIcon.getBitmap());
+                if (artworkIcon.getType() == Icon.TYPE_BITMAP
+                        || artworkIcon.getType() == Icon.TYPE_ADAPTIVE_BITMAP) {
+                    // Avoids extra processing if this is already a valid bitmap
+                    wallpaperColors = WallpaperColors
+                            .fromBitmap(artworkIcon.getBitmap());
+                } else {
+                    Drawable artworkDrawable = artworkIcon.loadDrawable(mContext);
+                    if (artworkDrawable != null) {
+                        wallpaperColors = WallpaperColors
+                                .fromDrawable(artworkIcon.loadDrawable(mContext));
+                    }
+                }
+            }
+            if (wallpaperColors != null) {
                 mutableColorScheme = new ColorScheme(wallpaperColors, true, Style.CONTENT);
                 Drawable albumArt = getScaledBackground(artworkIcon, width, height);
                 GradientDrawable gradient = (GradientDrawable) mContext
@@ -1005,16 +1018,13 @@
 
     private void bindScrubbingTime(MediaData data) {
         ConstraintSet expandedSet = mMediaViewController.getExpandedLayout();
-        ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
         int elapsedTimeId = mMediaViewHolder.getScrubbingElapsedTimeView().getId();
         int totalTimeId = mMediaViewHolder.getScrubbingTotalTimeView().getId();
 
         boolean visible = scrubbingTimeViewsEnabled(data.getSemanticActions()) && mIsScrubbing;
         setVisibleAndAlpha(expandedSet, elapsedTimeId, visible);
         setVisibleAndAlpha(expandedSet, totalTimeId, visible);
-        // Never show in collapsed
-        setVisibleAndAlpha(collapsedSet, elapsedTimeId, false);
-        setVisibleAndAlpha(collapsedSet, totalTimeId, false);
+        // Collapsed view is always GONE as set in XML, so doesn't need to be updated dynamically
     }
 
     private boolean scrubbingTimeViewsEnabled(@Nullable MediaButton semanticActions) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
index 8305050..2518659 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
@@ -188,24 +188,28 @@
 
         @AnyThread
         fun start() = bgExecutor.execute {
-            localMediaManager.registerCallback(this)
-            localMediaManager.startScan()
-            muteAwaitConnectionManager?.startListening()
-            playbackType = controller?.playbackInfo?.playbackType ?: PLAYBACK_TYPE_UNKNOWN
-            controller?.registerCallback(this)
-            updateCurrent()
-            started = true
-            configurationController.addCallback(configListener)
+            if (!started) {
+                localMediaManager.registerCallback(this)
+                localMediaManager.startScan()
+                muteAwaitConnectionManager?.startListening()
+                playbackType = controller?.playbackInfo?.playbackType ?: PLAYBACK_TYPE_UNKNOWN
+                controller?.registerCallback(this)
+                updateCurrent()
+                started = true
+                configurationController.addCallback(configListener)
+            }
         }
 
         @AnyThread
         fun stop() = bgExecutor.execute {
-            started = false
-            controller?.unregisterCallback(this)
-            localMediaManager.stopScan()
-            localMediaManager.unregisterCallback(this)
-            muteAwaitConnectionManager?.stopListening()
-            configurationController.removeCallback(configListener)
+            if (started) {
+                started = false
+                controller?.unregisterCallback(this)
+                localMediaManager.stopScan()
+                localMediaManager.unregisterCallback(this)
+                muteAwaitConnectionManager?.stopListening()
+                configurationController.removeCallback(configListener)
+            }
         }
 
         fun dump(pw: PrintWriter) {
@@ -265,7 +269,6 @@
             updateCurrent()
         }
 
-
         override fun onBroadcastStarted(reason: Int, broadcastId: Int) {
             if (DEBUG) {
                 Log.d(TAG, "onBroadcastStarted(), reason = $reason , broadcastId = $broadcastId")
@@ -279,8 +282,10 @@
             }
         }
 
-        override fun onBroadcastMetadataChanged(broadcastId: Int,
-                                                metadata: BluetoothLeBroadcastMetadata) {
+        override fun onBroadcastMetadataChanged(
+            broadcastId: Int,
+            metadata: BluetoothLeBroadcastMetadata
+        ) {
             if (DEBUG) {
                 Log.d(TAG, "onBroadcastMetadataChanged(), broadcastId = $broadcastId , " +
                         "metadata = $metadata")
@@ -291,7 +296,6 @@
         override fun onBroadcastStopped(reason: Int, broadcastId: Int) {
             if (DEBUG) {
                 Log.d(TAG, "onBroadcastStopped(), reason = $reason , broadcastId = $broadcastId")
-
             }
             updateCurrent()
         }
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
index 2f732de..458ed40 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
@@ -144,8 +144,7 @@
                     animatedFraction)
                 // When crossfading, let's keep the bounds at the right location during fading
                 boundsProgress = if (animationCrossFadeProgress < 0.5f) 0.0f else 1.0f
-                currentAlpha = calculateAlphaFromCrossFade(animationCrossFadeProgress,
-                    instantlyShowAtEnd = false)
+                currentAlpha = calculateAlphaFromCrossFade(animationCrossFadeProgress)
             } else {
                 // If we're not crossfading, let's interpolate from the start alpha to 1.0f
                 currentAlpha = MathUtils.lerp(animationStartAlpha, 1.0f, animatedFraction)
@@ -276,7 +275,7 @@
             if (value >= 0) {
                 updateTargetState()
                 // Setting the alpha directly, as the below call will use it to update the alpha
-                carouselAlpha = calculateAlphaFromCrossFade(field, instantlyShowAtEnd = true)
+                carouselAlpha = calculateAlphaFromCrossFade(field)
                 applyTargetStateIfNotAnimating()
             }
         }
@@ -414,18 +413,10 @@
      * @param crossFadeProgress The current cross fade progress. 0.5f means it's just switching
      * between the start and the end location and the content is fully faded, while 0.75f means
      * that we're halfway faded in again in the target state.
-     *
-     * @param instantlyShowAtEnd should the view be instantly shown at the end. This is needed
-     * to avoid fadinging in when the target was hidden anyway.
      */
-    private fun calculateAlphaFromCrossFade(
-        crossFadeProgress: Float,
-        instantlyShowAtEnd: Boolean
-    ): Float {
+    private fun calculateAlphaFromCrossFade(crossFadeProgress: Float): Float {
         if (crossFadeProgress <= 0.5f) {
             return 1.0f - crossFadeProgress / 0.5f
-        } else if (instantlyShowAtEnd) {
-            return 1.0f
         } else {
             return (crossFadeProgress - 0.5f) / 0.5f
         }
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
new file mode 100644
index 0000000..6802da3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.media
+
+import android.app.ActivityOptions
+import android.content.Intent
+import android.media.projection.IMediaProjection
+import android.media.projection.MediaProjectionManager.EXTRA_MEDIA_PROJECTION
+import android.os.Binder
+import android.os.Bundle
+import android.os.IBinder
+import android.view.View
+import com.android.internal.app.ChooserActivity
+import com.android.internal.app.chooser.NotSelectableTargetInfo
+import com.android.internal.app.chooser.TargetInfo
+import com.android.systemui.util.AsyncActivityLauncher
+import com.android.systemui.R;
+import javax.inject.Inject
+
+class MediaProjectionAppSelectorActivity @Inject constructor(
+    private val activityLauncher: AsyncActivityLauncher
+) : ChooserActivity() {
+
+    public override fun onCreate(bundle: Bundle?) {
+        val queryIntent = Intent(Intent.ACTION_MAIN)
+            .addCategory(Intent.CATEGORY_LAUNCHER)
+        intent.putExtra(Intent.EXTRA_INTENT, queryIntent)
+
+        // TODO(b/235465652) Use resource lexeme
+        intent.putExtra(Intent.EXTRA_TITLE, "Record or cast an app")
+
+        super.onCreate(bundle)
+
+        // TODO(b/235465652) we should update VisD of the title and add an icon
+        findViewById<View>(R.id.title)?.visibility = View.VISIBLE
+    }
+
+    override fun appliedThemeResId(): Int =
+        R.style.Theme_SystemUI_MediaProjectionAppSelector
+
+    override fun startSelected(which: Int, always: Boolean, filtered: Boolean) {
+        val currentListAdapter = mChooserMultiProfilePagerAdapter.activeListAdapter
+        val targetInfo = currentListAdapter.targetInfoForPosition(which, filtered) ?: return
+        if (targetInfo is NotSelectableTargetInfo) return
+
+        val intent = createIntent(targetInfo)
+
+        val launchToken: IBinder = Binder("media_projection_launch_token")
+        val activityOptions = ActivityOptions.makeBasic()
+        activityOptions.launchCookie = launchToken
+
+        val userHandle = mMultiProfilePagerAdapter.activeListAdapter.userHandle
+
+        // Launch activity asynchronously and wait for the result, launching of an activity
+        // is typically very fast, so we don't show any loaders.
+        // We wait for the activity to be launched to make sure that the window of the activity
+        // is created and ready to be captured.
+        val activityStarted = activityLauncher
+            .startActivityAsUser(intent, userHandle, activityOptions.toBundle()) {
+                onTargetActivityLaunched(launchToken)
+            }
+
+        // Rely on the ActivityManager to pop up a dialog regarding app suspension
+        // and return false if suspended
+        if (!targetInfo.isSuspended && activityStarted) {
+            // TODO(b/222078415) track activity launch
+        }
+    }
+
+    private fun createIntent(target: TargetInfo): Intent {
+        val intent = Intent(target.resolvedIntent)
+
+        // Launch the app in a new task, so it won't be in the host's app task
+        intent.flags = intent.flags or Intent.FLAG_ACTIVITY_NEW_TASK
+
+        // Remove activity forward result flag as this activity will
+        // return the media projection session
+        intent.flags = intent.flags and Intent.FLAG_ACTIVITY_FORWARD_RESULT.inv()
+
+        return intent
+    }
+
+    override fun onDestroy() {
+        activityLauncher.destroy()
+        super.onDestroy()
+    }
+
+    override fun onActivityStarted(cti: TargetInfo) {
+        // do nothing
+    }
+
+    private fun onTargetActivityLaunched(launchToken: IBinder) {
+        val mediaProjectionBinder = intent.getIBinderExtra(EXTRA_MEDIA_PROJECTION)
+        val projection = IMediaProjection.Stub.asInterface(mediaProjectionBinder)
+
+        projection.launchCookie = launchToken
+
+        val intent = Intent()
+        intent.putExtra(EXTRA_MEDIA_PROJECTION, projection.asBinder())
+        setResult(RESULT_OK, intent)
+        setForceSendResultForMediaProjection()
+        finish()
+    }
+
+    override fun shouldGetOnlyDefaultActivities() = false
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
index 3860409..397bffc 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
@@ -40,7 +40,10 @@
 import android.util.Log;
 import android.view.Window;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 import com.android.systemui.util.Utils;
 
@@ -53,6 +56,7 @@
     private String mPackageName;
     private int mUid;
     private IMediaProjectionManager mService;
+    private FeatureFlags mFeatureFlags;
 
     private AlertDialog mDialog;
 
@@ -60,6 +64,7 @@
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
+        mFeatureFlags = Dependency.get(FeatureFlags.class);
         mPackageName = getCallingPackage();
         IBinder b = ServiceManager.getService(MEDIA_PROJECTION_SERVICE);
         mService = IMediaProjectionManager.Stub.asInterface(b);
@@ -141,14 +146,22 @@
             dialogTitle = getString(R.string.media_projection_dialog_title, appName);
         }
 
-        mDialog = new AlertDialog.Builder(this, R.style.Theme_SystemUI_Dialog)
+        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this,
+                R.style.Theme_SystemUI_Dialog)
                 .setTitle(dialogTitle)
                 .setIcon(R.drawable.ic_media_projection_permission)
                 .setMessage(dialogText)
                 .setPositiveButton(R.string.media_projection_action_text, this)
                 .setNeutralButton(android.R.string.cancel, this)
-                .setOnCancelListener(this)
-                .create();
+                .setOnCancelListener(this);
+
+        if (isPartialScreenSharingEnabled()) {
+            // This is a temporary entry point before we have a new permission dialog
+            // TODO(b/233183090): this activity should be redesigned to have a dropdown selector
+            dialogBuilder.setNegativeButton("App", this);
+        }
+
+        mDialog = dialogBuilder.create();
 
         SystemUIDialog.registerDismissListener(mDialog);
         SystemUIDialog.applyFlags(mDialog);
@@ -177,6 +190,15 @@
             if (which == AlertDialog.BUTTON_POSITIVE) {
                 setResult(RESULT_OK, getMediaProjectionIntent(mUid, mPackageName));
             }
+
+            if (isPartialScreenSharingEnabled() && which == AlertDialog.BUTTON_NEGATIVE) {
+                IMediaProjection projection = createProjection(mUid, mPackageName);
+                final Intent intent = new Intent(this, MediaProjectionAppSelectorActivity.class);
+                intent.putExtra(MediaProjectionManager.EXTRA_MEDIA_PROJECTION,
+                        projection.asBinder());
+                intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+                startActivity(intent);
+            }
         } catch (RemoteException e) {
             Log.e(TAG, "Error granting projection permission", e);
             setResult(RESULT_CANCELED);
@@ -188,10 +210,14 @@
         }
     }
 
+    private IMediaProjection createProjection(int uid, String packageName) throws RemoteException {
+        return mService.createProjection(uid, packageName,
+                MediaProjectionManager.TYPE_SCREEN_CAPTURE, false /* permanentGrant */);
+    }
+
     private Intent getMediaProjectionIntent(int uid, String packageName)
             throws RemoteException {
-        IMediaProjection projection = mService.createProjection(uid, packageName,
-                MediaProjectionManager.TYPE_SCREEN_CAPTURE, false /* permanentGrant */);
+        IMediaProjection projection = createProjection(uid, packageName);
         Intent intent = new Intent();
         intent.putExtra(MediaProjectionManager.EXTRA_MEDIA_PROJECTION, projection.asBinder());
         return intent;
@@ -201,4 +227,8 @@
     public void onCancel(DialogInterface dialog) {
         finish();
     }
+
+    private boolean isPartialScreenSharingEnabled() {
+        return mFeatureFlags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java b/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
index a617850..f8f784f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
@@ -112,7 +112,7 @@
                                     if (DEBUG) Log.d(mTag, "requesting AudioFocus");
                                     int focusGain = AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK;
                                     if (mCmd.looping) {
-                                        focusGain = AudioManager.AUDIOFOCUS_GAIN;
+                                        focusGain = AudioManager.AUDIOFOCUS_GAIN_TRANSIENT;
                                     }
                                     mNotificationRampTimeMs = audioManager.getFocusRampTimeMs(
                                             focusGain, mCmd.attributes);
diff --git a/packages/SystemUI/src/com/android/systemui/media/dagger/MediaProjectionModule.kt b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaProjectionModule.kt
new file mode 100644
index 0000000..e33a1b9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaProjectionModule.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.dagger
+
+import android.app.Activity
+import com.android.systemui.media.MediaProjectionAppSelectorActivity
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.ClassKey
+import dagger.multibindings.IntoMap
+
+@Module
+abstract class MediaProjectionModule {
+
+    @Binds
+    @IntoMap
+    @ClassKey(MediaProjectionAppSelectorActivity::class)
+    abstract fun provideMediaProjectionAppSelectorActivity(
+        activity: MediaProjectionAppSelectorActivity): Activity
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
index f2f2753..e9b6af4 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -42,14 +42,11 @@
     private static final String TAG = "MediaOutputAdapter";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
-    private final MediaOutputDialog mMediaOutputDialog;
     private ViewGroup mConnectedItem;
     private boolean mIncludeDynamicGroup;
 
-    public MediaOutputAdapter(MediaOutputController controller,
-            MediaOutputDialog mediaOutputDialog) {
+    public MediaOutputAdapter(MediaOutputController controller) {
         super(controller);
-        mMediaOutputDialog = mediaOutputDialog;
         setHasStableIds(true);
     }
 
@@ -63,7 +60,7 @@
     @Override
     public void onBindViewHolder(@NonNull MediaDeviceBaseViewHolder viewHolder, int position) {
         final int size = mController.getMediaDevices().size();
-        if (position == size && mController.isZeroMode()) {
+        if (position == size) {
             viewHolder.onBind(CUSTOMIZED_ITEM_PAIR_NEW, false /* topMargin */,
                     true /* bottomMargin */);
         } else if (position < size) {
@@ -78,7 +75,7 @@
     @Override
     public long getItemId(int position) {
         final int size = mController.getMediaDevices().size();
-        if (position == size && mController.isZeroMode()) {
+        if (position == size) {
             return -1;
         } else if (position < size) {
             return ((List<MediaDevice>) (mController.getMediaDevices()))
@@ -91,11 +88,8 @@
 
     @Override
     public int getItemCount() {
-        if (mController.isZeroMode()) {
-            // Add extra one for "pair new" or dynamic group
-            return mController.getMediaDevices().size() + 1;
-        }
-        return mController.getMediaDevices().size();
+        // Add extra one for "pair new"
+        return mController.getMediaDevices().size() + 1;
     }
 
     class MediaDeviceViewHolder extends MediaDeviceBaseViewHolder {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index 9b964a5..1d773a1 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -91,6 +91,7 @@
     private TextView mHeaderSubtitle;
     private ImageView mHeaderIcon;
     private ImageView mAppResourceIcon;
+    private ImageView mBroadcastIcon;
     private RecyclerView mDevicesRecyclerView;
     private LinearLayout mDeviceListLayout;
     private LinearLayout mCastAppLayout;
@@ -239,6 +240,7 @@
         mAppButton = mDialogView.requireViewById(R.id.launch_app_button);
         mAppResourceIcon = mDialogView.requireViewById(R.id.app_source_icon);
         mCastAppLayout = mDialogView.requireViewById(R.id.cast_app_section);
+        mBroadcastIcon = mDialogView.requireViewById(R.id.broadcast_icon);
 
         mDeviceListLayout.getViewTreeObserver().addOnGlobalLayoutListener(
                 mDeviceListLayoutListener);
@@ -366,6 +368,9 @@
         mStopButton.setEnabled(true);
         mStopButton.setText(getStopButtonText());
         mStopButton.setOnClickListener(v -> onStopButtonClick());
+
+        mBroadcastIcon.setVisibility(getBroadcastIconVisibility());
+        mBroadcastIcon.setOnClickListener(v -> onBroadcastIconClick());
     }
 
     private void updateButtonBackgroundColorFilter() {
@@ -490,6 +495,14 @@
         dismiss();
     }
 
+    public int getBroadcastIconVisibility() {
+        return View.GONE;
+    }
+
+    public void onBroadcastIconClick() {
+        // Do nothing.
+    }
+
     public boolean isBroadcastSupported() {
         return false;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java
index 8f06546..310469d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java
@@ -74,7 +74,7 @@
     MediaOutputBroadcastDialog(Context context, boolean aboveStatusbar,
             BroadcastSender broadcastSender, MediaOutputController mediaOutputController) {
         super(context, broadcastSender, mediaOutputController);
-        mAdapter = new MediaOutputGroupAdapter(mMediaOutputController);
+        mAdapter = new MediaOutputAdapter(mMediaOutputController);
         // TODO(b/226710953): Move the part to MediaOutputBaseDialog for every class
         //  that extends MediaOutputBaseDialog
         if (!aboveStatusbar) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index 247ffa7..7e3275d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.media.dialog;
 
-import static android.provider.Settings.ACTION_BLUETOOTH_PAIRING_SETTINGS;
+import static android.provider.Settings.ACTION_BLUETOOTH_SETTINGS;
 
 import android.annotation.CallbackExecutor;
 import android.app.AlertDialog;
@@ -300,6 +300,9 @@
             return;
         }
         try {
+            synchronized (mMediaDevicesLock) {
+                mMediaDevices.removeIf(MediaDevice::isMutingExpectedDevice);
+            }
             mAudioManager.cancelMuteAwaitConnection(mAudioManager.getMutingExpectedDevice());
         } catch (Exception e) {
             Log.d(TAG, "Unable to cancel mute await connection");
@@ -711,22 +714,6 @@
         return false;
     }
 
-    boolean isZeroMode() {
-        synchronized (mMediaDevicesLock) {
-            if (mMediaDevices.size() == 1) {
-                final MediaDevice device = mMediaDevices.iterator().next();
-                // Add "pair new" only when local output device exists
-                final int type = device.getDeviceType();
-                if (type == MediaDevice.MediaDeviceType.TYPE_PHONE_DEVICE
-                        || type == MediaDevice.MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE
-                        || type == MediaDevice.MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE) {
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
-
     void launchBluetoothPairing(View view) {
         ActivityLaunchAnimator.Controller controller =
                 mDialogLaunchAnimator.createActivityLaunchController(view);
@@ -736,7 +723,7 @@
         }
 
         Intent launchIntent =
-                new Intent(ACTION_BLUETOOTH_PAIRING_SETTINGS)
+                new Intent(ACTION_BLUETOOTH_SETTINGS)
                         .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
         final Intent deepLinkIntent =
                 new Intent(Settings.ACTION_SETTINGS_EMBED_DEEP_LINK_ACTIVITY);
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
index 3fd920b..9fb96b5 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
@@ -42,7 +42,7 @@
             MediaOutputController mediaOutputController, UiEventLogger uiEventLogger) {
         super(context, broadcastSender, mediaOutputController);
         mUiEventLogger = uiEventLogger;
-        mAdapter = new MediaOutputAdapter(mMediaOutputController, this);
+        mAdapter = new MediaOutputAdapter(mMediaOutputController);
         if (!aboveStatusbar) {
             getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
         }
@@ -134,6 +134,17 @@
         }
     }
 
+    @Override
+    public int getBroadcastIconVisibility() {
+        return (isBroadcastSupported() && mMediaOutputController.isBluetoothLeBroadcastEnabled())
+                ? View.VISIBLE : View.GONE;
+    }
+
+    @Override
+    public void onBroadcastIconClick() {
+        startLeBroadcastDialog();
+    }
+
     @VisibleForTesting
     public enum MediaOutputEvent implements UiEventLogger.UiEventEnum {
         @UiEvent(doc = "The MediaOutput dialog became visible on the screen.")
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java
deleted file mode 100644
index ba2f006..0000000
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.media.dialog;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-
-import com.android.settingslib.media.MediaDevice;
-import com.android.systemui.R;
-
-import java.util.List;
-
-/**
- * Adapter for media output dynamic group dialog.
- */
-//TODO: clear this class after new UI updated
-public class MediaOutputGroupAdapter extends MediaOutputBaseAdapter {
-
-    private static final String TAG = "MediaOutputGroupAdapter";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    private final List<MediaDevice> mGroupMediaDevices;
-
-    public MediaOutputGroupAdapter(MediaOutputController controller) {
-        super(controller);
-        mGroupMediaDevices = controller.getGroupMediaDevices();
-    }
-
-    @Override
-    public MediaDeviceBaseViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup,
-            int viewType) {
-        super.onCreateViewHolder(viewGroup, viewType);
-
-        return new GroupViewHolder(mHolderView);
-    }
-
-    @Override
-    public void onBindViewHolder(@NonNull MediaDeviceBaseViewHolder viewHolder, int position) {
-        // Add "Group"
-        if (position == 0) {
-            viewHolder.onBind(CUSTOMIZED_ITEM_GROUP, true /* topMargin */,
-                    false /* bottomMargin */);
-            return;
-        }
-        // Add available devices
-        final int newPosition = position - 1;
-        final int size = mGroupMediaDevices.size();
-        if (newPosition < size) {
-            viewHolder.onBind(mGroupMediaDevices.get(newPosition), false /* topMargin */,
-                    newPosition == (size - 1) /* bottomMargin */, position);
-            return;
-        }
-        if (DEBUG) {
-            Log.d(TAG, "Incorrect position: " + position);
-        }
-    }
-
-    @Override
-    public int getItemCount() {
-        // Require extra item for group volume operation
-        return mGroupMediaDevices.size() + 1;
-    }
-
-    @Override
-    CharSequence getItemTitle(MediaDevice device) {
-        return super.getItemTitle(device);
-    }
-
-    class GroupViewHolder extends MediaDeviceBaseViewHolder {
-
-        GroupViewHolder(View view) {
-            super(view);
-        }
-
-        @Override
-        void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin, int position) {
-            super.onBind(device, topMargin, bottomMargin, position);
-            mCheckBox.setVisibility(View.VISIBLE);
-            mCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
-                onCheckBoxClicked(isChecked, device);
-            });
-            boolean isCurrentSeekbarInvisible = mSeekBar.getVisibility() == View.GONE;
-            setTwoLineLayout(device, false /* bFocused */, true /* showSeekBar */,
-                    false /* showProgressBar */, false /* showSubtitle*/);
-            initSeekbar(device, isCurrentSeekbarInvisible);
-            final List<MediaDevice> selectedDevices = mController.getSelectedMediaDevice();
-            if (isDeviceIncluded(mController.getSelectableMediaDevice(), device)) {
-                mCheckBox.setButtonDrawable(R.drawable.ic_check_box);
-                mCheckBox.setChecked(false);
-                mCheckBox.setEnabled(true);
-            } else if (isDeviceIncluded(selectedDevices, device)) {
-                if (selectedDevices.size() == 1 || !isDeviceIncluded(
-                        mController.getDeselectableMediaDevice(), device)) {
-                    mCheckBox.setButtonDrawable(getDisabledCheckboxDrawable());
-                    mCheckBox.setChecked(true);
-                    mCheckBox.setEnabled(false);
-                } else {
-                    mCheckBox.setButtonDrawable(R.drawable.ic_check_box);
-                    mCheckBox.setChecked(true);
-                    mCheckBox.setEnabled(true);
-                }
-            }
-        }
-
-        @Override
-        void onBind(int customizedItem, boolean topMargin, boolean bottomMargin) {
-            if (customizedItem == CUSTOMIZED_ITEM_GROUP) {
-                setTwoLineLayout(mContext.getText(R.string.media_output_dialog_group),
-                        true /* bFocused */, true /* showSeekBar */, false /* showProgressBar */,
-                        false /* showSubtitle*/);
-                mTitleIcon.setImageDrawable(getSpeakerDrawable());
-                mCheckBox.setVisibility(View.GONE);
-                initSessionSeekbar();
-            }
-        }
-
-        private void onCheckBoxClicked(boolean isChecked, MediaDevice device) {
-            if (isChecked && isDeviceIncluded(mController.getSelectableMediaDevice(), device)) {
-                mController.addDeviceToPlayMedia(device);
-            } else if (!isChecked && isDeviceIncluded(mController.getDeselectableMediaDevice(),
-                    device)) {
-                mController.removeDeviceFromPlayMedia(device);
-            }
-        }
-
-        private Drawable getDisabledCheckboxDrawable() {
-            final Drawable drawable = mContext.getDrawable(R.drawable.ic_check_box_blue_24dp)
-                    .mutate();
-            final Bitmap checkbox = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
-                    drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
-            final Canvas canvas = new Canvas(checkbox);
-            TypedValue value = new TypedValue();
-            mContext.getTheme().resolveAttribute(android.R.attr.disabledAlpha, value, true);
-            drawable.setAlpha((int) (value.getFloat() * 255));
-            drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
-            drawable.draw(canvas);
-
-            return drawable;
-        }
-
-        private boolean isDeviceIncluded(List<MediaDevice> deviceList, MediaDevice targetDevice) {
-            for (MediaDevice device : deviceList) {
-                if (TextUtils.equals(device.getId(), targetDevice.getId())) {
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupDialog.java
deleted file mode 100644
index bb3f969..0000000
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupDialog.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.media.dialog;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.view.View;
-import android.view.WindowManager;
-
-import androidx.core.graphics.drawable.IconCompat;
-
-import com.android.systemui.R;
-import com.android.systemui.broadcast.BroadcastSender;
-
-/**
- * Dialog for media output group.
- */
-// TODO(b/203073091): Remove this class once group logic been implemented.
-public class MediaOutputGroupDialog extends MediaOutputBaseDialog {
-
-    MediaOutputGroupDialog(Context context, boolean aboveStatusbar, BroadcastSender broadcastSender,
-            MediaOutputController mediaOutputController) {
-        super(context, broadcastSender, mediaOutputController);
-        mMediaOutputController.resetGroupMediaDevices();
-        mAdapter = new MediaOutputGroupAdapter(mMediaOutputController);
-        if (!aboveStatusbar) {
-            getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
-        }
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-    }
-
-    @Override
-    int getHeaderIconRes() {
-        return R.drawable.ic_arrow_back;
-    }
-
-    @Override
-    IconCompat getHeaderIcon() {
-        return null;
-    }
-
-    @Override
-    int getHeaderIconSize() {
-        return mContext.getResources().getDimensionPixelSize(
-                    R.dimen.media_output_dialog_header_back_icon_size);
-    }
-
-    @Override
-    CharSequence getHeaderText() {
-        return mContext.getString(R.string.media_output_dialog_add_output);
-    }
-
-    @Override
-    CharSequence getHeaderSubtitle() {
-        final int size = mMediaOutputController.getSelectedMediaDevice().size();
-        if (size == 1) {
-            return mContext.getText(R.string.media_output_dialog_single_device);
-        }
-        return mContext.getString(R.string.media_output_dialog_multiple_devices, size);
-    }
-
-    @Override
-    Drawable getAppSourceIcon() {
-        return null;
-    }
-
-    @Override
-    int getStopButtonVisibility() {
-        return View.VISIBLE;
-    }
-
-    @Override
-    void onHeaderIconClick() {
-        // Given that we launched the media output group dialog from the media output dialog,
-        // dismissing this dialog will show the media output dialog again.
-        dismiss();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index 5f52485..281ef94 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -626,6 +626,7 @@
                     }
                 }, mainExecutor, bgExecutor);
 
+        mView.setBackgroundExecutor(bgExecutor);
         mView.setEdgeBackGestureHandler(mEdgeBackGestureHandler);
         mNavBarMode = mNavigationModeController.addListener(mModeChangedListener);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index ad3cfa3..9e1ba5f 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -72,6 +72,7 @@
 import com.android.systemui.navigationbar.buttons.RotationContextButton;
 import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
 import com.android.systemui.recents.Recents;
+import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shared.rotation.FloatingRotationButton;
 import com.android.systemui.shared.rotation.RotationButton.RotationButtonUpdatesCallback;
 import com.android.systemui.shared.rotation.RotationButtonController;
@@ -81,13 +82,13 @@
 import com.android.systemui.statusbar.phone.AutoHideController;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.LightBarTransitionsController;
-import com.android.systemui.statusbar.phone.NotificationPanelViewController;
 import com.android.wm.shell.back.BackAnimation;
 import com.android.wm.shell.pip.Pip;
 
 import java.io.PrintWriter;
 import java.util.Map;
 import java.util.Optional;
+import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 
 /** */
@@ -97,6 +98,8 @@
 
     final static boolean ALTERNATE_CAR_MODE_UI = false;
 
+    private Executor mBgExecutor;
+
     // The current view is one of mHorizontal or mVertical depending on the current configuration
     View mCurrentView = null;
     private View mVertical;
@@ -349,6 +352,10 @@
         notifyVerticalChangedListener(mIsVertical);
     }
 
+    public void setBackgroundExecutor(Executor bgExecutor) {
+        mBgExecutor = bgExecutor;
+    }
+
     public void setTouchHandler(Gefingerpoken touchHandler) {
         mTouchHandler = touchHandler;
     }
@@ -768,8 +775,8 @@
         updateSlippery();
         reloadNavIcons();
         updateNavButtonIcons();
-        WindowManagerWrapper.getInstance().setNavBarVirtualKeyHapticFeedbackEnabled(
-                !mShowSwipeUpUi);
+        mBgExecutor.execute(() -> WindowManagerWrapper.getInstance()
+                .setNavBarVirtualKeyHapticFeedbackEnabled(!mShowSwipeUpUi));
         getHomeButton().setAccessibilityDelegate(
                 mShowSwipeUpUi ? mQuickStepAccessibilityDelegate : null);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
index 8179d17..28ab83c 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
@@ -30,6 +30,7 @@
 import android.view.MotionEvent
 import android.view.VelocityTracker
 import android.view.View
+import android.view.ViewConfiguration
 import android.view.WindowManager
 import android.view.animation.DecelerateInterpolator
 import android.view.animation.PathInterpolator
@@ -98,6 +99,7 @@
     context: Context,
     private var backAnimation: BackAnimation?,
     private val windowManager: WindowManager,
+    private val viewConfiguration: ViewConfiguration,
     @Main private val mainHandler: Handler,
     private val vibratorHelper: VibratorHelper,
     private val configurationController: ConfigurationController,
@@ -112,6 +114,7 @@
      */
     class Factory @Inject constructor(
         private val windowManager: WindowManager,
+        private val viewConfiguration: ViewConfiguration,
         @Main private val mainHandler: Handler,
         private val vibratorHelper: VibratorHelper,
         private val configurationController: ConfigurationController,
@@ -123,6 +126,7 @@
                 context,
                 backAnimation,
                 windowManager,
+                viewConfiguration,
                 mainHandler,
                 vibratorHelper,
                 configurationController,
@@ -164,6 +168,10 @@
 
     private var gestureStartTime = 0L
 
+    // Whether the current gesture has moved a sufficiently large amount,
+    // so that we can unambiguously start showing the ENTRY animation
+    private var hasPassedDragSlop = false
+
     private val failsafeRunnable = Runnable { onFailsafe() }
 
     private enum class GestureState {
@@ -304,29 +312,53 @@
                 startX = event.x
                 startY = event.y
                 gestureStartTime = SystemClock.uptimeMillis()
-
-                // Reset the arrow to the side
-                updateArrowState(GestureState.ENTRY)
-
-                windowManager.updateViewLayout(mView, layoutParams)
-                mView.startTrackingShowBackArrowLatency()
             }
-            MotionEvent.ACTION_MOVE -> handleMoveEvent(event)
+            MotionEvent.ACTION_MOVE -> {
+                // only go to the ENTRY state after some minimum motion has occurred
+                if (dragSlopExceeded(event.x, startX)) {
+                    handleMoveEvent(event)
+                }
+            }
             MotionEvent.ACTION_UP -> {
                 if (currentState == GestureState.ACTIVE) {
                     updateArrowState(if (isFlung()) GestureState.FLUNG else GestureState.COMMITTED)
-                } else {
+                } else if (currentState != GestureState.GONE) { // if invisible, skip animation
                     updateArrowState(GestureState.CANCELLED)
                 }
                 velocityTracker = null
             }
             MotionEvent.ACTION_CANCEL -> {
-                updateArrowState(GestureState.CANCELLED)
+                // Receiving a CANCEL implies that something else intercepted
+                // the gesture, i.e., the user did not cancel their gesture.
+                // Therefore, disappear immediately, with minimum fanfare.
+                updateArrowState(GestureState.GONE)
                 velocityTracker = null
             }
         }
     }
 
+    /**
+     * Returns false until the current gesture exceeds the touch slop threshold,
+     * and returns true thereafter (we reset on the subsequent back gesture).
+     * The moment it switches from false -> true is important,
+     * because that's when we switch state, from GONE -> ENTRY.
+     * @return whether the current gesture has moved past a minimum threshold.
+     */
+    private fun dragSlopExceeded(curX: Float, startX: Float): Boolean {
+        if (hasPassedDragSlop) return true
+
+        if (abs(curX - startX) > viewConfiguration.scaledTouchSlop) {
+            // Reset the arrow to the side
+            updateArrowState(GestureState.ENTRY)
+
+            windowManager.updateViewLayout(mView, layoutParams)
+            mView.startTrackingShowBackArrowLatency()
+
+            hasPassedDragSlop = true
+        }
+        return hasPassedDragSlop
+    }
+
     private fun updateArrowStateOnMove(yTranslation: Float, xTranslation: Float) {
         if (!currentState.isInteractive())
             return
@@ -530,6 +562,7 @@
     }
 
     private fun resetOnDown() {
+        hasPassedDragSlop = false
         hasHapticPlayed = false
         totalTouchDelta = 0f
         vibrationTime = 0
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index bd6a5fc..067f4cb 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -53,7 +53,6 @@
 import android.view.Surface;
 import android.view.ViewConfiguration;
 import android.view.WindowManager;
-import android.view.WindowMetrics;
 
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.internal.policy.GestureNavigationSettingsObserver;
@@ -133,7 +132,7 @@
                 @Override
                 public void onPrioritizedRotation(@Surface.Rotation int rotation) {
                     mStartingQuickstepRotation = rotation;
-                    updateDisabledForQuickstep(mContext.getResources().getConfiguration());
+                    updateDisabledForQuickstep(mLastReportedConfig);
                 }
             };
 
@@ -183,6 +182,7 @@
     private final IWindowManager mWindowManagerService;
     private final Optional<Pip> mPipOptional;
     private final FalsingManager mFalsingManager;
+    private final Configuration mLastReportedConfig = new Configuration();
     // Activities which should not trigger Back gesture.
     private final List<ComponentName> mGestureBlockingActivities = new ArrayList<>();
 
@@ -338,6 +338,7 @@
         mLatencyTracker = latencyTracker;
         mBackGestureTfClassifierProviderProvider = backGestureTfClassifierProviderProvider;
         mFeatureFlags = featureFlags;
+        mLastReportedConfig.setTo(mContext.getResources().getConfiguration());
         ComponentName recentsComponentName = ComponentName.unflattenFromString(
                 context.getString(com.android.internal.R.string.config_recentsComponentName));
         if (recentsComponentName != null) {
@@ -886,12 +887,12 @@
         if (DEBUG_MISSING_GESTURE) {
             Log.d(DEBUG_MISSING_GESTURE_TAG, "Config changed: config=" + newConfig);
         }
+        mLastReportedConfig.updateFrom(newConfig);
         updateDisplaySize();
     }
 
     private void updateDisplaySize() {
-        WindowMetrics metrics = mWindowManager.getMaximumWindowMetrics();
-        Rect bounds = metrics.getBounds();
+        Rect bounds = mLastReportedConfig.windowConfiguration.getMaxBounds();
         mDisplaySize.set(bounds.width(), bounds.height());
         if (DEBUG_MISSING_GESTURE) {
             Log.d(DEBUG_MISSING_GESTURE_TAG, "Update display size: mDisplaySize=" + mDisplaySize);
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleModule.kt b/packages/SystemUI/src/com/android/systemui/people/PeopleModule.kt
new file mode 100644
index 0000000..dd35445
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleModule.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.people
+
+import com.android.systemui.people.data.repository.PeopleTileRepository
+import com.android.systemui.people.data.repository.PeopleTileRepositoryImpl
+import com.android.systemui.people.data.repository.PeopleWidgetRepository
+import com.android.systemui.people.data.repository.PeopleWidgetRepositoryImpl
+import dagger.Binds
+import dagger.Module
+
+/** Dagger module to provide/bind people space dependencies. */
+@Module
+interface PeopleModule {
+    @Binds fun bindTileRepository(impl: PeopleTileRepositoryImpl): PeopleTileRepository
+
+    @Binds fun bindWidgetRepository(impl: PeopleWidgetRepositoryImpl): PeopleWidgetRepository
+}
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java b/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java
index b55d86e..0ba077e 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java
@@ -29,7 +29,8 @@
 import android.util.Log;
 import android.widget.RemoteViews;
 
-import com.android.systemui.SystemUIAppComponentFactory;
+import com.android.systemui.SystemUIAppComponentFactoryBase.ContextAvailableCallback;
+import com.android.systemui.SystemUIAppComponentFactoryBase.ContextInitializer;
 import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
 import com.android.systemui.shared.system.PeopleProviderUtils;
 
@@ -37,11 +38,11 @@
 
 /** API that returns a People Tile preview. */
 public class PeopleProvider extends ContentProvider implements
-        SystemUIAppComponentFactory.ContextInitializer {
+        ContextInitializer {
     private static final String TAG = "PeopleProvider";
     private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
     private static final String EMPTY_STRING = "";
-    private SystemUIAppComponentFactory.ContextAvailableCallback mCallback;
+    private ContextAvailableCallback mCallback;
 
     @Inject
     PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
@@ -144,7 +145,7 @@
 
     @Override
     public void setContextAvailableCallback(
-            SystemUIAppComponentFactory.ContextAvailableCallback callback) {
+            ContextAvailableCallback callback) {
         mCallback = callback;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
index 93a3f81..e845aa8 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
@@ -19,144 +19,52 @@
 import static android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID;
 import static android.appwidget.AppWidgetManager.INVALID_APPWIDGET_ID;
 
-import static com.android.systemui.people.PeopleTileViewHelper.getPersonIconBitmap;
-import static com.android.systemui.people.PeopleTileViewHelper.getSizeInDp;
-
-import android.app.Activity;
-import android.app.people.PeopleSpaceTile;
-import android.content.Context;
 import android.content.Intent;
-import android.content.res.TypedArray;
-import android.graphics.Color;
-import android.graphics.Outline;
-import android.graphics.drawable.GradientDrawable;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewOutlineProvider;
-import android.widget.LinearLayout;
 
-import com.android.systemui.R;
-import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
-import com.android.systemui.people.widget.PeopleTileKey;
+import androidx.activity.ComponentActivity;
+import androidx.lifecycle.ViewModelProvider;
 
-import java.util.ArrayList;
-import java.util.List;
+import com.android.systemui.people.ui.view.PeopleViewBinder;
+import com.android.systemui.people.ui.viewmodel.PeopleViewModel;
 
 import javax.inject.Inject;
 
 /** People Tile Widget configuration activity that shows the user their conversation tiles. */
-public class PeopleSpaceActivity extends Activity {
+public class PeopleSpaceActivity extends ComponentActivity {
 
     private static final String TAG = "PeopleSpaceActivity";
     private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
 
-    private PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
-    private Context mContext;
-    private int mAppWidgetId;
+    private final PeopleViewModel.Factory mViewModelFactory;
+    private PeopleViewModel mViewModel;
 
     @Inject
-    public PeopleSpaceActivity(PeopleSpaceWidgetManager peopleSpaceWidgetManager) {
+    public PeopleSpaceActivity(PeopleViewModel.Factory viewModelFactory) {
         super();
-        mPeopleSpaceWidgetManager = peopleSpaceWidgetManager;
-
+        mViewModelFactory = viewModelFactory;
     }
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        mContext = getApplicationContext();
-        mAppWidgetId = getIntent().getIntExtra(EXTRA_APPWIDGET_ID,
-                INVALID_APPWIDGET_ID);
         setResult(RESULT_CANCELED);
-    }
+        mViewModel = new ViewModelProvider(this, mViewModelFactory).get(PeopleViewModel.class);
 
-    /** Builds the conversation selection activity. */
-    private void buildActivity() {
-        List<PeopleSpaceTile> priorityTiles = new ArrayList<>();
-        List<PeopleSpaceTile> recentTiles = new ArrayList<>();
-        try {
-            priorityTiles = mPeopleSpaceWidgetManager.getPriorityTiles();
-            recentTiles = mPeopleSpaceWidgetManager.getRecentTiles();
-        } catch (Exception e) {
-            Log.e(TAG, "Couldn't retrieve conversations", e);
-        }
+        // Update the widget ID coming from the intent.
+        int widgetId = getIntent().getIntExtra(EXTRA_APPWIDGET_ID, INVALID_APPWIDGET_ID);
+        mViewModel.onWidgetIdChanged(widgetId);
 
-        // If no conversations, render activity without conversations
-        if (recentTiles.isEmpty() && priorityTiles.isEmpty()) {
-            setContentView(R.layout.people_space_activity_no_conversations);
-
-            // The Tile preview has colorBackground as its background. Change it so it's different
-            // than the activity's background.
-            LinearLayout item = findViewById(android.R.id.background);
-            GradientDrawable shape = (GradientDrawable) item.getBackground();
-            final TypedArray ta = mContext.getTheme().obtainStyledAttributes(
-                    new int[]{com.android.internal.R.attr.colorSurface});
-            shape.setColor(ta.getColor(0, Color.WHITE));
-            return;
-        }
-
-        setContentView(R.layout.people_space_activity);
-        setTileViews(R.id.priority, R.id.priority_tiles, priorityTiles);
-        setTileViews(R.id.recent, R.id.recent_tiles, recentTiles);
-    }
-
-    private ViewOutlineProvider mViewOutlineProvider = new ViewOutlineProvider() {
-        @Override
-        public void getOutline(View view, Outline outline) {
-            outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(),
-                    mContext.getResources().getDimension(R.dimen.people_space_widget_radius));
-        }
-    };
-
-    /** Sets a {@link PeopleSpaceTileView}s for each conversation. */
-    private void setTileViews(int viewId, int tilesId, List<PeopleSpaceTile> tiles) {
-        if (tiles.isEmpty()) {
-            LinearLayout view = findViewById(viewId);
-            view.setVisibility(View.GONE);
-            return;
-        }
-
-        ViewGroup layout = findViewById(tilesId);
-        layout.setClipToOutline(true);
-        layout.setOutlineProvider(mViewOutlineProvider);
-        for (int i = 0; i < tiles.size(); ++i) {
-            PeopleSpaceTile tile = tiles.get(i);
-            PeopleSpaceTileView tileView = new PeopleSpaceTileView(mContext,
-                    layout, tile.getId(), i == (tiles.size() - 1));
-            setTileView(tileView, tile);
-        }
-    }
-
-    /** Sets {@code tileView} with the data in {@code conversation}. */
-    private void setTileView(PeopleSpaceTileView tileView, PeopleSpaceTile tile) {
-        try {
-            if (tile.getUserName() != null) {
-                tileView.setName(tile.getUserName().toString());
-            }
-            tileView.setPersonIcon(getPersonIconBitmap(mContext, tile,
-                    getSizeInDp(mContext, R.dimen.avatar_size_for_medium,
-                            mContext.getResources().getDisplayMetrics().density)));
-
-            PeopleTileKey key = new PeopleTileKey(tile);
-            tileView.setOnClickListener(v -> storeWidgetConfiguration(tile, key));
-        } catch (Exception e) {
-            Log.e(TAG, "Couldn't retrieve shortcut information", e);
-        }
-    }
-
-    /** Stores the user selected configuration for {@code mAppWidgetId}. */
-    private void storeWidgetConfiguration(PeopleSpaceTile tile, PeopleTileKey key) {
-        if (PeopleSpaceUtils.DEBUG) {
-            if (DEBUG) {
-                Log.d(TAG, "Put " + tile.getUserName() + "'s shortcut ID: "
-                        + tile.getId() + " for widget ID: "
-                        + mAppWidgetId);
-            }
-        }
-        mPeopleSpaceWidgetManager.addNewWidget(mAppWidgetId, key);
-        finishActivity();
+        ViewGroup view = PeopleViewBinder.create(this);
+        PeopleViewBinder.bind(view, mViewModel, /* lifecycleOwner= */ this,
+                () -> {
+                    finishActivity();
+                    return null;
+                });
+        setContentView(view);
     }
 
     /** Finish activity with a successful widget configuration result. */
@@ -169,19 +77,13 @@
     /** Finish activity without choosing a widget. */
     public void dismissActivity(View v) {
         if (DEBUG) Log.d(TAG, "Activity dismissed with no widgets added!");
+        setResult(RESULT_CANCELED);
         finish();
     }
 
     private void setActivityResult(int result) {
         Intent resultValue = new Intent();
-        resultValue.putExtra(EXTRA_APPWIDGET_ID, mAppWidgetId);
+        resultValue.putExtra(EXTRA_APPWIDGET_ID, mViewModel.getAppWidgetId().getValue());
         setResult(result, resultValue);
     }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-        // Refresh tile views to sync new conversations.
-        buildActivity();
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleStoryIconFactory.java b/packages/SystemUI/src/com/android/systemui/people/PeopleStoryIconFactory.java
index 4ee951f..58e700f 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleStoryIconFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleStoryIconFactory.java
@@ -28,6 +28,7 @@
 import android.graphics.drawable.Drawable;
 import android.util.IconDrawableFactory;
 import android.util.Log;
+import android.view.ContextThemeWrapper;
 
 import androidx.core.graphics.drawable.RoundedBitmapDrawable;
 
@@ -52,16 +53,15 @@
 
     PeopleStoryIconFactory(Context context, PackageManager pm,
             IconDrawableFactory iconDrawableFactory, int iconSizeDp) {
-        context.setTheme(android.R.style.Theme_DeviceDefault_DayNight);
-        mIconBitmapSize = (int) (iconSizeDp * context.getResources().getDisplayMetrics().density);
-        mDensity = context.getResources().getDisplayMetrics().density;
+        mContext = new ContextThemeWrapper(context, android.R.style.Theme_DeviceDefault_DayNight);
+        mIconBitmapSize = (int) (iconSizeDp * mContext.getResources().getDisplayMetrics().density);
+        mDensity = mContext.getResources().getDisplayMetrics().density;
         mIconSize = mDensity * iconSizeDp;
         mPackageManager = pm;
         mIconDrawableFactory = iconDrawableFactory;
-        mImportantConversationColor = context.getColor(R.color.important_conversation);
-        mAccentColor = Utils.getColorAttr(context,
+        mImportantConversationColor = mContext.getColor(R.color.important_conversation);
+        mAccentColor = Utils.getColorAttr(mContext,
                 com.android.internal.R.attr.colorAccentPrimaryVariant).getDefaultColor();
-        mContext = context;
     }
 
 
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
index 00aa138..be82b1f 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
@@ -75,6 +75,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.R;
+import com.android.systemui.people.data.model.PeopleTileModel;
 import com.android.systemui.people.widget.LaunchConversationActivity;
 import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
 import com.android.systemui.people.widget.PeopleTileKey;
@@ -299,7 +300,8 @@
         return createLastInteractionRemoteViews();
     }
 
-    private static boolean isDndBlockingTileData(@Nullable PeopleSpaceTile tile) {
+    /** Whether the conversation associated with {@code tile} can bypass DND. */
+    public static boolean isDndBlockingTileData(@Nullable PeopleSpaceTile tile) {
         if (tile == null) return false;
 
         int notificationPolicyState = tile.getNotificationPolicyState();
@@ -536,7 +538,8 @@
         return views;
     }
 
-    private static boolean getHasNewStory(PeopleSpaceTile tile) {
+    /** Whether {@code tile} has a new story. */
+    public static boolean getHasNewStory(PeopleSpaceTile tile) {
         return tile.getStatuses() != null && tile.getStatuses().stream().anyMatch(
                 c -> c.getActivity() == ACTIVITY_NEW_STORY);
     }
@@ -1250,16 +1253,24 @@
     }
 
     /** Returns a bitmap with the user icon and package icon. */
-    public static Bitmap getPersonIconBitmap(Context context, PeopleSpaceTile tile,
+    public static Bitmap getPersonIconBitmap(Context context, PeopleTileModel tile,
             int maxAvatarSize) {
-        boolean hasNewStory = getHasNewStory(tile);
-        return getPersonIconBitmap(context, tile, maxAvatarSize, hasNewStory);
+        return getPersonIconBitmap(context, maxAvatarSize, tile.getHasNewStory(),
+                tile.getUserIcon(), tile.getKey().getPackageName(), tile.getKey().getUserId(),
+                tile.isImportant(),  tile.isDndBlocking());
     }
 
     /** Returns a bitmap with the user icon and package icon. */
     private static Bitmap getPersonIconBitmap(
             Context context, PeopleSpaceTile tile, int maxAvatarSize, boolean hasNewStory) {
-        Icon icon = tile.getUserIcon();
+        return getPersonIconBitmap(context, maxAvatarSize, hasNewStory, tile.getUserIcon(),
+                tile.getPackageName(), getUserId(tile),
+                tile.isImportantConversation(), isDndBlockingTileData(tile));
+    }
+
+    private static Bitmap getPersonIconBitmap(
+            Context context, int maxAvatarSize, boolean hasNewStory, Icon icon, String packageName,
+            int userId, boolean importantConversation, boolean dndBlockingTileData) {
         if (icon == null) {
             Drawable placeholder = context.getDrawable(R.drawable.ic_avatar_with_badge).mutate();
             placeholder.setColorFilter(getDisabledColorFilter());
@@ -1272,10 +1283,10 @@
         RoundedBitmapDrawable roundedDrawable = RoundedBitmapDrawableFactory.create(
                 context.getResources(), icon.getBitmap());
         Drawable personDrawable = storyIcon.getPeopleTileDrawable(roundedDrawable,
-                tile.getPackageName(), getUserId(tile), tile.isImportantConversation(),
+                packageName, userId, importantConversation,
                 hasNewStory);
 
-        if (isDndBlockingTileData(tile)) {
+        if (dndBlockingTileData) {
             personDrawable.setColorFilter(getDisabledColorFilter());
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java b/packages/SystemUI/src/com/android/systemui/people/data/model/PeopleTileModel.kt
similarity index 60%
copy from packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java
copy to packages/SystemUI/src/com/android/systemui/people/data/model/PeopleTileModel.kt
index 2aaf6a5..5d8539f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/people/data/model/PeopleTileModel.kt
@@ -14,17 +14,17 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.people.data.model
 
-import com.android.systemui.dagger.SysUISingleton;
+import android.graphics.drawable.Icon
+import com.android.systemui.people.widget.PeopleTileKey
 
-import dagger.Binds;
-import dagger.Module;
-
-/** Provides a {@link NotifPanelEvents} in {@link SysUISingleton} scope. */
-@Module
-public abstract class NotifPanelEventsModule {
-    @Binds
-    abstract NotifPanelEvents bindPanelEvents(
-            NotificationPanelViewController.PanelEventsEmitter impl);
-}
+/** Models a tile/conversation. */
+data class PeopleTileModel(
+    val key: PeopleTileKey,
+    val username: String,
+    val userIcon: Icon,
+    val hasNewStory: Boolean,
+    val isImportant: Boolean,
+    val isDndBlocking: Boolean,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/people/data/repository/PeopleTileRepository.kt b/packages/SystemUI/src/com/android/systemui/people/data/repository/PeopleTileRepository.kt
new file mode 100644
index 0000000..01b43d5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/people/data/repository/PeopleTileRepository.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.people.data.repository
+
+import android.app.people.PeopleSpaceTile
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.people.PeopleTileViewHelper
+import com.android.systemui.people.data.model.PeopleTileModel
+import com.android.systemui.people.widget.PeopleSpaceWidgetManager
+import com.android.systemui.people.widget.PeopleTileKey
+import javax.inject.Inject
+
+/** A Repository to fetch the current tiles/conversations. */
+// TODO(b/238993727): Make the tiles API reactive.
+interface PeopleTileRepository {
+    /* The current priority tiles. */
+    fun priorityTiles(): List<PeopleTileModel>
+
+    /* The current recent tiles. */
+    fun recentTiles(): List<PeopleTileModel>
+}
+
+@SysUISingleton
+class PeopleTileRepositoryImpl
+@Inject
+constructor(
+    private val peopleSpaceWidgetManager: PeopleSpaceWidgetManager,
+) : PeopleTileRepository {
+    override fun priorityTiles(): List<PeopleTileModel> {
+        return peopleSpaceWidgetManager.priorityTiles.map { it.toModel() }
+    }
+
+    override fun recentTiles(): List<PeopleTileModel> {
+        return peopleSpaceWidgetManager.recentTiles.map { it.toModel() }
+    }
+
+    private fun PeopleSpaceTile.toModel(): PeopleTileModel {
+        return PeopleTileModel(
+            PeopleTileKey(this),
+            userName.toString(),
+            userIcon,
+            PeopleTileViewHelper.getHasNewStory(this),
+            isImportantConversation,
+            PeopleTileViewHelper.isDndBlockingTileData(this),
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/people/data/repository/PeopleWidgetRepository.kt b/packages/SystemUI/src/com/android/systemui/people/data/repository/PeopleWidgetRepository.kt
new file mode 100644
index 0000000..f2b6cb1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/people/data/repository/PeopleWidgetRepository.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.people.data.repository
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.people.widget.PeopleSpaceWidgetManager
+import com.android.systemui.people.widget.PeopleTileKey
+import javax.inject.Inject
+
+interface PeopleWidgetRepository {
+    /**
+     * Bind the widget with ID [widgetId] to the tile keyed by [tileKey].
+     *
+     * If there is already a widget with [widgetId], this existing widget will be reconfigured and
+     * associated to this tile. If there is no widget with [widgetId], a new one will be created.
+     */
+    fun setWidgetTile(widgetId: Int, tileKey: PeopleTileKey)
+}
+
+@SysUISingleton
+class PeopleWidgetRepositoryImpl
+@Inject
+constructor(
+    private val peopleSpaceWidgetManager: PeopleSpaceWidgetManager,
+) : PeopleWidgetRepository {
+    override fun setWidgetTile(widgetId: Int, tileKey: PeopleTileKey) {
+        peopleSpaceWidgetManager.addNewWidget(widgetId, tileKey)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt b/packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt
new file mode 100644
index 0000000..bc982cc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.people.ui.view
+
+import android.content.Context
+import android.graphics.Color
+import android.graphics.Outline
+import android.graphics.drawable.GradientDrawable
+import android.util.Log
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.ViewOutlineProvider
+import android.widget.LinearLayout
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.Lifecycle.State.CREATED
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.systemui.R
+import com.android.systemui.people.PeopleSpaceTileView
+import com.android.systemui.people.ui.viewmodel.PeopleTileViewModel
+import com.android.systemui.people.ui.viewmodel.PeopleViewModel
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.launch
+
+/** A ViewBinder for [PeopleViewModel]. */
+object PeopleViewBinder {
+    private const val TAG = "PeopleSpaceViewBinder"
+
+    /**
+     * The [ViewOutlineProvider] used to clip the corner radius of the recent and priority lists.
+     */
+    private val ViewOutlineProvider =
+        object : ViewOutlineProvider() {
+            override fun getOutline(view: View, outline: Outline) {
+                outline.setRoundRect(
+                    0,
+                    0,
+                    view.width,
+                    view.height,
+                    view.context.resources.getDimension(R.dimen.people_space_widget_radius),
+                )
+            }
+        }
+
+    /** Create a [View] that can later be [bound][bind] to a [PeopleViewModel]. */
+    @JvmStatic
+    fun create(context: Context): ViewGroup {
+        return LayoutInflater.from(context)
+            .inflate(R.layout.people_space_activity, /* root= */ null) as ViewGroup
+    }
+
+    /** Bind [view] to [viewModel]. */
+    @JvmStatic
+    fun bind(
+        view: ViewGroup,
+        viewModel: PeopleViewModel,
+        lifecycleOwner: LifecycleOwner,
+        onFinish: () -> Unit,
+    ) {
+        // Call [onFinish] this activity when the ViewModel tells us so.
+        lifecycleOwner.lifecycleScope.launch {
+            lifecycleOwner.repeatOnLifecycle(CREATED) {
+                viewModel.isFinished.collect { isFinished ->
+                    if (isFinished) {
+                        viewModel.clearIsFinished()
+                        onFinish()
+                    }
+                }
+            }
+        }
+
+        // Start collecting the UI data once the Activity is STARTED.
+        lifecycleOwner.lifecycleScope.launch {
+            lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
+                combine(
+                        viewModel.priorityTiles,
+                        viewModel.recentTiles,
+                    ) { priority, recent ->
+                        priority to recent
+                    }
+                    .collect { (priorityTiles, recentTiles) ->
+                        if (priorityTiles.isNotEmpty() || recentTiles.isNotEmpty()) {
+                            setConversationsContent(
+                                view,
+                                priorityTiles,
+                                recentTiles,
+                                viewModel::onTileClicked,
+                            )
+                        } else {
+                            setNoConversationsContent(view)
+                        }
+                    }
+            }
+        }
+
+        // Make sure to refresh the tiles/conversations when the Activity is resumed, so that it
+        // updates them when going back to the Activity after leaving it.
+        lifecycleOwner.lifecycleScope.launch {
+            lifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
+                viewModel.onTileRefreshRequested()
+            }
+        }
+    }
+
+    private fun setNoConversationsContent(view: ViewGroup) {
+        // This should never happen.
+        if (view.childCount > 1) {
+            error("view has ${view.childCount} children, it should have maximum 1")
+        }
+
+        // The static content for no conversations is already shown.
+        if (view.findViewById<View>(R.id.top_level_no_conversations) != null) {
+            return
+        }
+
+        // If we were showing the content with conversations earlier, remove it.
+        if (view.childCount == 1) {
+            view.removeViewAt(0)
+        }
+
+        val context = view.context
+        val noConversationsView =
+            LayoutInflater.from(context)
+                .inflate(R.layout.people_space_activity_no_conversations, /* root= */ view)
+
+        // The Tile preview has colorBackground as its background. Change it so it's different than
+        // the activity's background.
+        val item = noConversationsView.findViewById<LinearLayout>(android.R.id.background)
+        val shape = item.background as GradientDrawable
+        val ta =
+            context.theme.obtainStyledAttributes(
+                intArrayOf(com.android.internal.R.attr.colorSurface)
+            )
+        shape.setColor(ta.getColor(0, Color.WHITE))
+        ta.recycle()
+    }
+
+    private fun setConversationsContent(
+        view: ViewGroup,
+        priorityTiles: List<PeopleTileViewModel>,
+        recentTiles: List<PeopleTileViewModel>,
+        onTileClicked: (PeopleTileViewModel) -> Unit,
+    ) {
+        // This should never happen.
+        if (view.childCount > 1) {
+            error("view has ${view.childCount} children, it should have maximum 1")
+        }
+
+        // Inflate the content with conversations, if it's not already.
+        if (view.findViewById<View>(R.id.top_level_with_conversations) == null) {
+            // If we were showing the content without conversations earlier, remove it.
+            if (view.childCount == 1) {
+                view.removeViewAt(0)
+            }
+
+            LayoutInflater.from(view.context)
+                .inflate(R.layout.people_space_activity_with_conversations, /* root= */ view)
+        }
+
+        // TODO(b/193782241): Replace the NestedScrollView + 2x LinearLayout from this layout into a
+        // single RecyclerView once this screen is tested by screenshot tests. Introduce a
+        // PeopleSpaceTileViewBinder that will properly create and bind the View associated to a
+        // PeopleSpaceTileViewModel (and remove the PeopleSpaceTileView class).
+        val conversationsView = view.requireViewById<View>(R.id.top_level_with_conversations)
+        setTileViews(
+            conversationsView,
+            R.id.priority,
+            R.id.priority_tiles,
+            priorityTiles,
+            onTileClicked,
+        )
+
+        setTileViews(
+            conversationsView,
+            R.id.recent,
+            R.id.recent_tiles,
+            recentTiles,
+            onTileClicked,
+        )
+    }
+
+    /** Sets a [PeopleSpaceTileView]s for each conversation. */
+    private fun setTileViews(
+        root: View,
+        tilesListId: Int,
+        tilesId: Int,
+        tiles: List<PeopleTileViewModel>,
+        onTileClicked: (PeopleTileViewModel) -> Unit,
+    ) {
+        // Remove any previously added tile.
+        // TODO(b/193782241): Once this list is a big RecyclerView, set the current list and use
+        // DiffUtil to do as less addView/removeView as possible.
+        val layout = root.requireViewById<ViewGroup>(tilesId)
+        layout.removeAllViews()
+        layout.outlineProvider = ViewOutlineProvider
+
+        val tilesListView = root.requireViewById<LinearLayout>(tilesListId)
+        if (tiles.isEmpty()) {
+            tilesListView.visibility = View.GONE
+            return
+        }
+        tilesListView.visibility = View.VISIBLE
+
+        // Add each tile.
+        tiles.forEachIndexed { i, tile ->
+            val tileView =
+                PeopleSpaceTileView(root.context, layout, tile.key.shortcutId, i == tiles.size - 1)
+            bindTileView(tileView, tile, onTileClicked)
+        }
+    }
+
+    /** Sets [tileView] with the data in [conversation]. */
+    private fun bindTileView(
+        tileView: PeopleSpaceTileView,
+        tile: PeopleTileViewModel,
+        onTileClicked: (PeopleTileViewModel) -> Unit,
+    ) {
+        try {
+            tileView.setName(tile.username)
+            tileView.setPersonIcon(tile.icon)
+            tileView.setOnClickListener { onTileClicked(tile) }
+        } catch (e: Exception) {
+            Log.e(TAG, "Couldn't retrieve shortcut information", e)
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java b/packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleTileViewModel.kt
similarity index 60%
copy from packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java
copy to packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleTileViewModel.kt
index 2aaf6a5..40205ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleTileViewModel.kt
@@ -14,17 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.people.ui.viewmodel
 
-import com.android.systemui.dagger.SysUISingleton;
+import android.graphics.Bitmap
+import com.android.systemui.people.widget.PeopleTileKey
 
-import dagger.Binds;
-import dagger.Module;
-
-/** Provides a {@link NotifPanelEvents} in {@link SysUISingleton} scope. */
-@Module
-public abstract class NotifPanelEventsModule {
-    @Binds
-    abstract NotifPanelEvents bindPanelEvents(
-            NotificationPanelViewController.PanelEventsEmitter impl);
-}
+/** Models UI state for a single tile/conversation. */
+data class PeopleTileViewModel(
+    val key: PeopleTileKey,
+    val icon: Bitmap,
+    val username: String?,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleViewModel.kt b/packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleViewModel.kt
new file mode 100644
index 0000000..17de991
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleViewModel.kt
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.people.ui.viewmodel
+
+import android.appwidget.AppWidgetManager.INVALID_APPWIDGET_ID
+import android.content.Context
+import android.util.Log
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import com.android.systemui.R
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.people.PeopleSpaceUtils
+import com.android.systemui.people.PeopleTileViewHelper
+import com.android.systemui.people.data.model.PeopleTileModel
+import com.android.systemui.people.data.repository.PeopleTileRepository
+import com.android.systemui.people.data.repository.PeopleWidgetRepository
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+
+/**
+ * Models UI state for the people space, allowing the user to select which conversation should be
+ * associated to a new or existing Conversation widget.
+ */
+class PeopleViewModel(
+    @Application private val context: Context,
+    private val tileRepository: PeopleTileRepository,
+    private val widgetRepository: PeopleWidgetRepository,
+) : ViewModel() {
+    /**
+     * The list of the priority tiles/conversations.
+     *
+     * Important: Even though this is a Flow, the underlying API used to populate this Flow is not
+     * reactive and you have to manually call [onTileRefreshRequested] to refresh the tiles.
+     */
+    private val _priorityTiles = MutableStateFlow(priorityTiles())
+    val priorityTiles: Flow<List<PeopleTileViewModel>> = _priorityTiles
+
+    /**
+     * The list of the priority tiles/conversations.
+     *
+     * Important: Even though this is a Flow, the underlying API used to populate this Flow is not
+     * reactive and you have to manually call [onTileRefreshRequested] to refresh the tiles.
+     */
+    private val _recentTiles = MutableStateFlow(recentTiles())
+    val recentTiles: Flow<List<PeopleTileViewModel>> = _recentTiles
+
+    /** The ID of the widget currently being edited/added. */
+    private val _appWidgetId = MutableStateFlow(INVALID_APPWIDGET_ID)
+    val appWidgetId: StateFlow<Int> = _appWidgetId
+
+    /** Whether the user journey is complete. */
+    private val _isFinished = MutableStateFlow(false)
+    val isFinished: StateFlow<Boolean> = _isFinished
+
+    /** Refresh the [priorityTiles] and [recentTiles]. */
+    fun onTileRefreshRequested() {
+        _priorityTiles.value = priorityTiles()
+        _recentTiles.value = recentTiles()
+    }
+
+    /** Called when the [appWidgetId] should be changed to [widgetId]. */
+    fun onWidgetIdChanged(widgetId: Int) {
+        _appWidgetId.value = widgetId
+    }
+
+    /** Clear [isFinished], setting it to false. */
+    fun clearIsFinished() {
+        _isFinished.value = false
+    }
+
+    /** Called when a tile is clicked. */
+    fun onTileClicked(tile: PeopleTileViewModel) {
+        if (PeopleSpaceUtils.DEBUG) {
+            Log.d(
+                TAG,
+                "Put ${tile.username}'s shortcut ID: ${tile.key.shortcutId} for widget ID: " +
+                    _appWidgetId.value
+            )
+        }
+        widgetRepository.setWidgetTile(_appWidgetId.value, tile.key)
+        _isFinished.value = true
+    }
+
+    private fun priorityTiles(): List<PeopleTileViewModel> {
+        return try {
+            tileRepository.priorityTiles().map { it.toViewModel() }
+        } catch (e: Exception) {
+            Log.e(TAG, "Couldn't retrieve priority conversations", e)
+            emptyList()
+        }
+    }
+
+    private fun recentTiles(): List<PeopleTileViewModel> {
+        return try {
+            tileRepository.recentTiles().map { it.toViewModel() }
+        } catch (e: Exception) {
+            Log.e(TAG, "Couldn't retrieve recent conversations", e)
+            emptyList()
+        }
+    }
+
+    private fun PeopleTileModel.toViewModel(): PeopleTileViewModel {
+        val icon =
+            PeopleTileViewHelper.getPersonIconBitmap(
+                context,
+                this,
+                PeopleTileViewHelper.getSizeInDp(
+                    context,
+                    R.dimen.avatar_size_for_medium,
+                    context.resources.displayMetrics.density,
+                )
+            )
+        return PeopleTileViewModel(key, icon, username)
+    }
+
+    /** The Factory that should be used to create a [PeopleViewModel]. */
+    class Factory
+    @Inject
+    constructor(
+        @Application private val context: Context,
+        private val tileRepository: PeopleTileRepository,
+        private val widgetRepository: PeopleWidgetRepository,
+    ) : ViewModelProvider.Factory {
+        override fun <T : ViewModel> create(modelClass: Class<T>): T {
+            check(modelClass == PeopleViewModel::class.java)
+            return PeopleViewModel(context, tileRepository, widgetRepository) as T
+        }
+    }
+
+    companion object {
+        private const val TAG = "PeopleSpaceViewModel"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/LaunchConversationActivity.java b/packages/SystemUI/src/com/android/systemui/people/widget/LaunchConversationActivity.java
index e1b97a4..20c6c556 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/LaunchConversationActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/LaunchConversationActivity.java
@@ -21,6 +21,7 @@
 import android.content.Intent;
 import android.content.pm.LauncherApps;
 import android.os.Bundle;
+import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -34,6 +35,7 @@
 import com.android.internal.logging.UiEventLoggerImpl;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.NotificationVisibility;
+import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.people.PeopleSpaceUtils;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -43,6 +45,7 @@
 import com.android.wm.shell.bubbles.Bubble;
 
 import java.util.Optional;
+import java.util.concurrent.Executor;
 
 import javax.inject.Inject;
 
@@ -58,6 +61,7 @@
     private boolean mIsForTesting;
     private IStatusBarService mIStatusBarService;
     private CommandQueue mCommandQueue;
+    private Executor mBgExecutor;
     private Bubble mBubble;
     private NotificationEntry mEntryToBubble;
 
@@ -67,7 +71,8 @@
             CommonNotifCollection commonNotifCollection,
             Optional<BubblesManager> bubblesManagerOptional,
             UserManager userManager,
-            CommandQueue commandQueue
+            CommandQueue commandQueue,
+            @Background Executor bgExecutor
     ) {
         super();
         mVisibilityProvider = visibilityProvider;
@@ -91,6 +96,7 @@
                 mCommandQueue.removeCallback(this);
             }
         });
+        mBgExecutor = bgExecutor;
     }
 
     @Override
@@ -172,34 +178,36 @@
             return;
         }
 
-        try {
-            if (mIStatusBarService == null || mCommonNotifCollection == null) {
-                if (DEBUG) {
-                    Log.d(TAG, "Skipping clear notification: null services, key: " + notifKey);
-                }
-                return;
+        if (mIStatusBarService == null || mCommonNotifCollection == null) {
+            if (DEBUG) {
+                Log.d(TAG, "Skipping clear notification: null services, key: " + notifKey);
             }
-
-            NotificationEntry entry = mCommonNotifCollection.getEntry(notifKey);
-            if (entry == null || entry.getRanking() == null) {
-                if (DEBUG) {
-                    Log.d(TAG, "Skipping clear notification: NotificationEntry or its Ranking"
-                            + " is null, key: " + notifKey);
-                }
-                return;
-            }
-
-            NotificationVisibility notifVisibility = mVisibilityProvider.obtain(entry, true);
-            int rank = notifVisibility.rank;
-
-            if (DEBUG) Log.d(TAG, "Clearing notification, key: " + notifKey + ", rank: " + rank);
-            mIStatusBarService.onNotificationClear(
-                    packageName, userHandle.getIdentifier(), notifKey,
-                    NotificationStats.DISMISSAL_OTHER,
-                    NotificationStats.DISMISS_SENTIMENT_POSITIVE, notifVisibility);
-        } catch (Exception e) {
-            Log.e(TAG, "Exception cancelling notification:" + e);
+            return;
         }
+
+        NotificationEntry entry = mCommonNotifCollection.getEntry(notifKey);
+        if (entry == null || entry.getRanking() == null) {
+            if (DEBUG) {
+                Log.d(TAG, "Skipping clear notification: NotificationEntry or its Ranking"
+                        + " is null, key: " + notifKey);
+            }
+            return;
+        }
+
+        NotificationVisibility notifVisibility = mVisibilityProvider.obtain(entry, true);
+        int rank = notifVisibility.rank;
+
+        if (DEBUG) Log.d(TAG, "Clearing notification, key: " + notifKey + ", rank: " + rank);
+        mBgExecutor.execute(() -> {
+            try {
+                mIStatusBarService.onNotificationClear(
+                        packageName, userHandle.getIdentifier(), notifKey,
+                        NotificationStats.DISMISSAL_OTHER,
+                        NotificationStats.DISMISS_SENTIMENT_POSITIVE, notifVisibility);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Exception cancelling notification:" + e);
+            }
+        });
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index fcafead..0697133 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -15,6 +15,7 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.animation.Interpolator;
 import android.view.animation.OvershootInterpolator;
@@ -626,6 +627,16 @@
         }
     }
 
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(event);
+        if (mAdapter != null && mAdapter.getCount() > 0) {
+            event.setItemCount(mAdapter.getCount());
+            event.setFromIndex(getCurrentPageNumber());
+            event.setToIndex(getCurrentPageNumber());
+        }
+    }
+
     private static Animator setupBounceAnimator(View view, int ordinal) {
         view.setAlpha(0f);
         view.setScaleX(0f);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index ccec80d..86d4fa3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -56,7 +56,6 @@
 
 /** Quick settings tile: Airplane mode **/
 public class AirplaneModeTile extends QSTileImpl<BooleanState> {
-    private final Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_airplane);
     private final SettingObserver mSetting;
     private final BroadcastDispatcher mBroadcastDispatcher;
     private final Lazy<ConnectivityManager> mLazyConnectivityManager;
@@ -129,11 +128,8 @@
         final boolean airplaneMode = value != 0;
         state.value = airplaneMode;
         state.label = mContext.getString(R.string.airplane_mode);
-        state.icon = mIcon;
-        if (state.slash == null) {
-            state.slash = new SlashState();
-        }
-        state.slash.isSlashed = !airplaneMode;
+        state.icon = ResourceIcon.get(state.value
+                ? R.drawable.qs_airplane_icon_on : R.drawable.qs_airplane_icon_off);
         state.state = airplaneMode ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
         state.contentDescription = state.label;
         state.expandedAccessibilityClassName = Switch.class.getName();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
index 1004fca..ee49b29 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -57,8 +57,6 @@
     private boolean mCharging;
     private boolean mPluggedIn;
 
-    private Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_battery_saver);
-
     @Inject
     public BatterySaverTile(
             QSHost host,
@@ -145,7 +143,9 @@
     protected void handleUpdateState(BooleanState state, Object arg) {
         state.state = mPluggedIn ? Tile.STATE_UNAVAILABLE
                 : mPowerSave ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
-        state.icon = mIcon;
+        state.icon = ResourceIcon.get(mPowerSave
+                ? R.drawable.qs_battery_saver_icon_on
+                : R.drawable.qs_battery_saver_icon_off);
         state.label = mContext.getString(R.string.battery_detail_switch_title);
         state.secondaryLabel = "";
         state.contentDescription = state.label;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java
index fa2d444..ee41f1d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java
@@ -72,9 +72,9 @@
     @Override
     public @DrawableRes int getIconRes(boolean isBlocked) {
         if (isBlocked) {
-            return com.android.internal.R.drawable.ic_camera_blocked;
+            return R.drawable.qs_camera_access_icon_off;
         } else {
-            return com.android.internal.R.drawable.ic_camera_allowed;
+            return R.drawable.qs_camera_access_icon_on;
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 3dcfbc0..8b7f53f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -226,16 +226,15 @@
         if (mController == null) return;
         final int zen = arg instanceof Integer ? (Integer) arg : mController.getZen();
         final boolean newValue = zen != ZEN_MODE_OFF;
-        final boolean valueChanged = state.value != newValue;
-        if (state.slash == null) state.slash = new SlashState();
         state.dualTarget = true;
         state.value = newValue;
         state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
-        state.slash.isSlashed = !state.value;
+        state.icon = ResourceIcon.get(state.value
+                ? R.drawable.qs_dnd_icon_on
+                : R.drawable.qs_dnd_icon_off);
         state.label = getTileLabel();
         state.secondaryLabel = TextUtils.emptyIfNull(ZenModeConfig.getDescription(mContext,
                 zen != Global.ZEN_MODE_OFF, mController.getConfig(), false));
-        state.icon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_dnd);
         checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_ADJUST_VOLUME);
         // Keeping the secondaryLabel in contentDescription instead of stateDescription is easier
         // to understand.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index fc93f44..9466a69 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -48,8 +48,6 @@
 /** Quick settings tile: Location **/
 public class LocationTile extends QSTileImpl<BooleanState> {
 
-    private final Icon mIcon = ResourceIcon.get(R.drawable.ic_location);
-
     private final LocationController mController;
     private final KeyguardStateController mKeyguard;
     private final Callback mCallback = new Callback();
@@ -119,8 +117,8 @@
         if (state.disabledByPolicy == false) {
             checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_CONFIG_LOCATION);
         }
-        state.icon = mIcon;
-        state.slash.isSlashed = !state.value;
+        state.icon = ResourceIcon.get(state.value
+                ? R.drawable.qs_location_icon_on : R.drawable.qs_location_icon_off);
         state.label = mContext.getString(R.string.quick_settings_location_label);
         state.contentDescription = state.label;
         state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java
index f4f0b2c..e547095 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java
@@ -72,9 +72,9 @@
     @Override
     public @DrawableRes int getIconRes(boolean isBlocked) {
         if (isBlocked) {
-            return com.android.internal.R.drawable.ic_mic_blocked;
+            return R.drawable.qs_mic_access_off;
         } else {
-            return com.android.internal.R.drawable.ic_mic_allowed;
+            return R.drawable.qs_mic_access_on;
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt b/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
index 260a371..bdcc6b0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
@@ -128,15 +128,16 @@
         private val animateFrom: Dialog,
         private val dialogLaunchAnimator: DialogLaunchAnimator
     ) : DialogInterface by animateFrom, DialogShower {
-        override fun showDialog(dialog: Dialog) {
+        override fun showDialog(dialog: Dialog, cuj: DialogCuj) {
             dialogLaunchAnimator.showFromDialog(
                 dialog,
-                animateFrom = animateFrom
+                animateFrom = animateFrom,
+                cuj
             )
         }
     }
 
     interface DialogShower : DialogInterface {
-        fun showDialog(dialog: Dialog)
+        fun showDialog(dialog: Dialog, cuj: DialogCuj)
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 6c58c45..438236d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -51,7 +51,6 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
-import android.graphics.Bitmap;
 import android.graphics.Insets;
 import android.graphics.Rect;
 import android.graphics.Region;
@@ -97,6 +96,7 @@
 import com.android.systemui.navigationbar.buttons.KeyButtonView;
 import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
 import com.android.systemui.settings.CurrentUserTracker;
+import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.recents.model.Task;
@@ -105,7 +105,6 @@
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
-import com.android.systemui.statusbar.phone.NotificationPanelViewController;
 import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
 import com.android.systemui.statusbar.policy.CallbackController;
 import com.android.wm.shell.back.BackAnimation;
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index 5bb3413..a837cbb 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -29,6 +29,7 @@
 import android.media.MediaRecorder;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -40,6 +41,8 @@
 import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.R;
 import com.android.systemui.dagger.qualifiers.LongRunning;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.screenrecord.ScreenMediaRecorder.ScreenMediaRecorderListener;
 import com.android.systemui.settings.UserContextProvider;
 import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
 
@@ -51,9 +54,10 @@
 /**
  * A service which records the device screen and optionally microphone input.
  */
-public class RecordingService extends Service implements MediaRecorder.OnInfoListener {
+public class RecordingService extends Service implements ScreenMediaRecorderListener {
     public static final int REQUEST_CODE = 2;
 
+    private static final int USER_ID_NOT_SPECIFIED = -1;
     private static final int NOTIFICATION_RECORDING_ID = 4274;
     private static final int NOTIFICATION_PROCESSING_ID = 4275;
     private static final int NOTIFICATION_VIEW_ID = 4273;
@@ -73,6 +77,7 @@
 
     private final RecordingController mController;
     private final KeyguardDismissUtil mKeyguardDismissUtil;
+    private final Handler mMainHandler;
     private ScreenRecordingAudioSource mAudioSource;
     private boolean mShowTaps;
     private boolean mOriginalShowTaps;
@@ -84,10 +89,12 @@
 
     @Inject
     public RecordingService(RecordingController controller, @LongRunning Executor executor,
-            UiEventLogger uiEventLogger, NotificationManager notificationManager,
+            @Main Handler handler, UiEventLogger uiEventLogger,
+            NotificationManager notificationManager,
             UserContextProvider userContextTracker, KeyguardDismissUtil keyguardDismissUtil) {
         mController = controller;
         mLongExecutor = executor;
+        mMainHandler = handler;
         mUiEventLogger = uiEventLogger;
         mNotificationManager = notificationManager;
         mUserContextTracker = userContextTracker;
@@ -138,6 +145,7 @@
 
                 mRecorder = new ScreenMediaRecorder(
                         mUserContextTracker.getUserContext(),
+                        mMainHandler,
                         currentUserId,
                         mAudioSource,
                         this
@@ -166,14 +174,8 @@
                 }
                 // Check user ID - we may be getting a stop intent after user switch, in which case
                 // we want to post the notifications for that user, which is NOT current user
-                int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
-                if (userId == -1) {
-                    userId = mUserContextTracker.getUserContext().getUserId();
-                }
-                Log.d(TAG, "notifying for user " + userId);
-                stopRecording(userId);
-                mNotificationManager.cancel(NOTIFICATION_RECORDING_ID);
-                stopSelf();
+                int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_ID_NOT_SPECIFIED);
+                stopService(userId);
                 break;
 
             case ACTION_SHARE:
@@ -378,15 +380,39 @@
         return builder.build();
     }
 
-    private void stopRecording(int userId) {
+    private void stopService() {
+        stopService(USER_ID_NOT_SPECIFIED);
+    }
+
+    private void stopService(int userId) {
+        if (userId == USER_ID_NOT_SPECIFIED) {
+            userId = mUserContextTracker.getUserContext().getUserId();
+        }
+        Log.d(TAG, "notifying for user " + userId);
         setTapsVisible(mOriginalShowTaps);
         if (getRecorder() != null) {
-            getRecorder().end();
-            saveRecording(userId);
+            try {
+                getRecorder().end();
+                saveRecording(userId);
+            } catch (RuntimeException exception) {
+                // RuntimeException could happen if the recording stopped immediately after starting
+                // let's release the recorder and delete all temporary files in this case
+                getRecorder().release();
+                showErrorToast(R.string.screenrecord_start_error);
+                Log.e(TAG, "stopRecording called, but there was an error when ending"
+                        + "recording");
+                exception.printStackTrace();
+            } catch (Throwable throwable) {
+                // Something unexpected happen, SystemUI will crash but let's delete
+                // the temporary files anyway
+                getRecorder().release();
+                throw new RuntimeException(throwable);
+            }
         } else {
             Log.e(TAG, "stopRecording called, but recorder was null");
         }
         updateState(false);
+        stopSelf();
     }
 
     private void saveRecording(int userId) {
@@ -446,4 +472,12 @@
         Log.d(TAG, "Media recorder info: " + what);
         onStartCommand(getStopIntent(this), 0, 0);
     }
+
+    @Override
+    public void onStopped() {
+        if (mController.isRecording()) {
+            Log.d(TAG, "Stopping recording because the system requested the stop");
+            stopService();
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
index 2133cf6..d098b4b 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
@@ -40,6 +40,7 @@
 import android.media.projection.MediaProjection;
 import android.media.projection.MediaProjectionManager;
 import android.net.Uri;
+import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -51,16 +52,19 @@
 import android.view.WindowManager;
 
 import java.io.File;
+import java.io.Closeable;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.nio.file.Files;
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.List;
 
 /**
  * Recording screen and mic/internal audio
  */
-public class ScreenMediaRecorder {
+public class ScreenMediaRecorder extends MediaProjection.Callback {
     private static final int TOTAL_NUM_TRACKS = 1;
     private static final int VIDEO_FRAME_RATE = 30;
     private static final int VIDEO_FRAME_RATE_TO_RESOLUTION_RATIO = 6;
@@ -81,14 +85,16 @@
     private ScreenRecordingMuxer mMuxer;
     private ScreenInternalAudioRecorder mAudio;
     private ScreenRecordingAudioSource mAudioSource;
+    private final Handler mHandler;
 
     private Context mContext;
-    MediaRecorder.OnInfoListener mListener;
+    ScreenMediaRecorderListener mListener;
 
-    public ScreenMediaRecorder(Context context,
+    public ScreenMediaRecorder(Context context, Handler handler,
             int user, ScreenRecordingAudioSource audioSource,
-            MediaRecorder.OnInfoListener listener) {
+            ScreenMediaRecorderListener listener) {
         mContext = context;
+        mHandler = handler;
         mUser = user;
         mListener = listener;
         mAudioSource = audioSource;
@@ -105,6 +111,7 @@
         IBinder projection = proj.asBinder();
         mMediaProjection = new MediaProjection(mContext,
                 IMediaProjection.Stub.asInterface(projection));
+        mMediaProjection.registerCallback(this, mHandler);
 
         File cacheDir = mContext.getCacheDir();
         cacheDir.mkdirs();
@@ -162,10 +169,15 @@
                 metrics.densityDpi,
                 DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                 mInputSurface,
-                null,
-                null);
+                new VirtualDisplay.Callback() {
+                    @Override
+                    public void onStopped() {
+                        onStop();
+                    }
+                },
+                mHandler);
 
-        mMediaRecorder.setOnInfoListener(mListener);
+        mMediaRecorder.setOnInfoListener((mr, what, extra) -> mListener.onInfo(mr, what, extra));
         if (mAudioSource == INTERNAL ||
                 mAudioSource == MIC_AND_INTERNAL) {
             mTempAudioFile = File.createTempFile("temp", ".aac",
@@ -259,21 +271,34 @@
     }
 
     /**
-     * End screen recording
+     * End screen recording, throws an exception if stopping recording failed
      */
-    void end() {
-        mMediaRecorder.stop();
-        mMediaRecorder.release();
-        mInputSurface.release();
-        mVirtualDisplay.release();
-        mMediaProjection.stop();
+    void end() throws IOException {
+        Closer closer = new Closer();
+
+        // MediaRecorder might throw RuntimeException if stopped immediately after starting
+        // We should remove the recording in this case as it will be invalid
+        closer.register(mMediaRecorder::stop);
+        closer.register(mMediaRecorder::release);
+        closer.register(mInputSurface::release);
+        closer.register(mVirtualDisplay::release);
+        closer.register(mMediaProjection::stop);
+        closer.register(this::stopInternalAudioRecording);
+
+        closer.close();
+
         mMediaRecorder = null;
         mMediaProjection = null;
-        stopInternalAudioRecording();
 
         Log.d(TAG, "end recording");
     }
 
+    @Override
+    public void onStop() {
+        Log.d(TAG, "The system notified about stopping the projection");
+        mListener.onStopped();
+    }
+
     private void stopInternalAudioRecording() {
         if (mAudioSource == INTERNAL || mAudioSource == MIC_AND_INTERNAL) {
             mAudio.end();
@@ -337,6 +362,18 @@
     }
 
     /**
+     * Release the resources without saving the data
+     */
+    protected void release() {
+        if (mTempVideoFile != null) {
+            mTempVideoFile.delete();
+        }
+        if (mTempAudioFile != null) {
+            mTempAudioFile.delete();
+        }
+    }
+
+    /**
     * Object representing the recording
     */
     public class SavedRecording {
@@ -362,4 +399,66 @@
             return mThumbnailBitmap;
         }
     }
+
+    interface ScreenMediaRecorderListener {
+        /**
+         * Called to indicate an info or a warning during recording.
+         * See {@link MediaRecorder.OnInfoListener} for the full description.
+         */
+        void onInfo(MediaRecorder mr, int what, int extra);
+
+        /**
+         * Called when the recording stopped by the system.
+         * For example, this might happen when doing partial screen sharing of an app
+         * and the app that is being captured is closed.
+         */
+        void onStopped();
+    }
+
+    /**
+     * Allows to register multiple {@link Closeable} objects and close them all by calling
+     * {@link Closer#close}. If there is an exception thrown during closing of one
+     * of the registered closeables it will continue trying closing the rest closeables.
+     * If there are one or more exceptions thrown they will be re-thrown at the end.
+     * In case of multiple exceptions only the first one will be thrown and all the rest
+     * will be printed.
+     */
+    private static class Closer implements Closeable {
+        private final List<Closeable> mCloseables = new ArrayList<>();
+
+        void register(Closeable closeable) {
+            mCloseables.add(closeable);
+        }
+
+        @Override
+        public void close() throws IOException {
+            Throwable throwable = null;
+
+            for (int i = 0; i < mCloseables.size(); i++) {
+                Closeable closeable = mCloseables.get(i);
+
+                try {
+                    closeable.close();
+                } catch (Throwable e) {
+                    if (throwable == null) {
+                        throwable = e;
+                    } else {
+                        e.printStackTrace();
+                    }
+                }
+            }
+
+            if (throwable != null) {
+                if (throwable instanceof IOException) {
+                    throw (IOException) throwable;
+                }
+
+                if (throwable instanceof RuntimeException) {
+                    throw (RuntimeException) throwable;
+                }
+
+                throw (Error) throwable;
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserFileManager.kt b/packages/SystemUI/src/com/android/systemui/settings/UserFileManager.kt
new file mode 100644
index 0000000..aa218db
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/settings/UserFileManager.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.settings
+
+import android.content.Context
+import android.content.SharedPreferences
+import java.io.File
+
+/**
+ * Interface for retrieving file paths for file storage of system and secondary users.
+ */
+interface UserFileManager {
+    /**
+     * Return the file based on current user.
+     */
+    fun getFile(fileName: String, userId: Int): File
+    /**
+     * Get shared preferences from user.
+     */
+    fun getSharedPreferences(
+        fileName: String,
+        @Context.PreferencesMode mode: Int,
+        userId: Int
+    ): SharedPreferences
+}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt
new file mode 100644
index 0000000..8c8f54f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.settings
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.content.SharedPreferences
+import android.os.Environment
+import android.os.UserHandle
+import android.os.UserManager
+import android.util.Log
+import androidx.annotation.VisibleForTesting
+import com.android.systemui.CoreStartable
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.util.concurrency.DelayableExecutor
+import java.io.File
+import javax.inject.Inject
+
+/**
+ * Implementation for retrieving file paths for file storage of system and secondary users.
+ * Files lie in {File Directory}/UserFileManager/{User Id} for secondary user.
+ * For system user, we use the conventional {File Directory}
+ */
+@SysUISingleton
+class UserFileManagerImpl @Inject constructor(
+    // Context of system process and system user.
+    val context: Context,
+    val userManager: UserManager,
+    val broadcastDispatcher: BroadcastDispatcher,
+    @Background val backgroundExecutor: DelayableExecutor
+) : UserFileManager, CoreStartable(context) {
+    companion object {
+        private const val FILES = "files"
+        private const val SHARED_PREFS = "shared_prefs"
+        internal const val ID = "UserFileManager"
+    }
+
+   private val broadcastReceiver = object : BroadcastReceiver() {
+        /**
+         * Listen to Intent.ACTION_USER_REMOVED to clear user data.
+         */
+        override fun onReceive(context: Context, intent: Intent) {
+            if (intent.action == Intent.ACTION_USER_REMOVED) {
+                clearDeletedUserData()
+            }
+        }
+    }
+
+    /**
+     * Poll for user-specific directories to delete upon start up.
+     */
+    override fun start() {
+        clearDeletedUserData()
+        val filter = IntentFilter().apply {
+            addAction(Intent.ACTION_USER_REMOVED)
+        }
+        broadcastDispatcher.registerReceiver(broadcastReceiver, filter, backgroundExecutor)
+    }
+
+    /**
+     * Return the file based on current user.
+     */
+    override fun getFile(fileName: String, userId: Int): File {
+        return if (UserHandle(userId).isSystem) {
+            Environment.buildPath(
+                context.filesDir,
+                fileName
+            )
+        } else {
+            Environment.buildPath(
+                context.filesDir,
+                ID,
+                userId.toString(),
+                FILES,
+                fileName
+            )
+        }
+    }
+
+    /**
+     * Get shared preferences from user.
+     */
+    override fun getSharedPreferences(
+        fileName: String,
+        @Context.PreferencesMode mode: Int,
+        userId: Int
+    ): SharedPreferences {
+        if (UserHandle(userId).isSystem) {
+            return context.getSharedPreferences(fileName, mode)
+        }
+        val secondaryUserDir = Environment.buildPath(
+            context.filesDir,
+            ID,
+            userId.toString(),
+            SHARED_PREFS,
+            fileName
+        )
+
+        return context.getSharedPreferences(secondaryUserDir, mode)
+    }
+
+    /**
+     * Remove dirs for deleted users.
+     */
+    @VisibleForTesting
+    internal fun clearDeletedUserData() {
+        backgroundExecutor.execute {
+            val file = Environment.buildPath(context.filesDir, ID)
+            if (!file.exists()) return@execute
+            val aliveUsers = userManager.aliveUsers.map { it.id.toString() }
+            val dirsToDelete = file.list().filter { !aliveUsers.contains(it) }
+
+            dirsToDelete.forEach { dir ->
+                try {
+                    val dirToDelete = Environment.buildPath(
+                        file,
+                        dir,
+                    )
+                    dirToDelete.deleteRecursively()
+                } catch (e: Exception) {
+                    Log.e(ID, "Deletion failed.", e)
+                }
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java b/packages/SystemUI/src/com/android/systemui/settings/dagger/MultiUserUtilsModule.java
similarity index 79%
rename from packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java
rename to packages/SystemUI/src/com/android/systemui/settings/dagger/MultiUserUtilsModule.java
index 7084d3f..2f62e44 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/dagger/MultiUserUtilsModule.java
@@ -21,25 +21,28 @@
 import android.os.Handler;
 import android.os.UserManager;
 
+import com.android.systemui.CoreStartable;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.settings.UserContentResolverProvider;
 import com.android.systemui.settings.UserContextProvider;
+import com.android.systemui.settings.UserFileManager;
+import com.android.systemui.settings.UserFileManagerImpl;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.settings.UserTrackerImpl;
 
 import dagger.Binds;
 import dagger.Module;
 import dagger.Provides;
+import dagger.multibindings.ClassKey;
+import dagger.multibindings.IntoMap;
 
 /**
  * Dagger Module for classes found within the com.android.systemui.settings package.
  */
 @Module
-public abstract class SettingsModule {
-
-
+public abstract class MultiUserUtilsModule {
     @Binds
     @SysUISingleton
     abstract UserContextProvider bindUserContextProvider(UserTracker tracker);
@@ -62,4 +65,12 @@
         tracker.initialize(startingUser);
         return tracker;
     }
+
+    @Binds
+    @IntoMap
+    @ClassKey(UserFileManagerImpl.class)
+    abstract CoreStartable bindUserFileManagerCoreStartable(UserFileManagerImpl sysui);
+
+    @Binds
+    abstract UserFileManager bindUserFileManager(UserFileManagerImpl impl);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NPVCDownEventState.kt b/packages/SystemUI/src/com/android/systemui/shade/NPVCDownEventState.kt
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/NPVCDownEventState.kt
rename to packages/SystemUI/src/com/android/systemui/shade/NPVCDownEventState.kt
index d44a569..07e8b9f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NPVCDownEventState.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/NPVCDownEventState.kt
@@ -11,7 +11,7 @@
  * KIND, either express or implied. See the License for the specific language governing
  * permissions and limitations under the License.
  */
-package com.android.systemui.statusbar.phone
+package com.android.systemui.shade
 
 import android.view.MotionEvent
 import com.android.systemui.dump.DumpsysTableLogger
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEvents.kt b/packages/SystemUI/src/com/android/systemui/shade/NotifPanelEvents.kt
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEvents.kt
rename to packages/SystemUI/src/com/android/systemui/shade/NotifPanelEvents.kt
index a385e22..ce9d89f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEvents.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotifPanelEvents.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone
+package com.android.systemui.shade
 
 /** Provides certain notification panel events.  */
 interface NotifPanelEvents {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java b/packages/SystemUI/src/com/android/systemui/shade/NotifPanelEventsModule.java
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java
rename to packages/SystemUI/src/com/android/systemui/shade/NotifPanelEventsModule.java
index 2aaf6a5..6772384 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotifPanelEventsModule.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.shade;
 
 import com.android.systemui.dagger.SysUISingleton;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelUnfoldAnimationController.kt b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelUnfoldAnimationController.kt
rename to packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt
index ff48755..e0cd482 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelUnfoldAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone
+package com.android.systemui.shade
 
 import android.content.Context
 import android.view.ViewGroup
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java
similarity index 90%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
rename to packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java
index d9ba494..e0997ff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.shade;
 
 import android.content.Context;
 import android.graphics.Canvas;
@@ -25,6 +25,8 @@
 import android.util.AttributeSet;
 
 import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.PanelView;
+import com.android.systemui.statusbar.phone.TapAgainView;
 
 public class NotificationPanelView extends PanelView {
 
@@ -35,8 +37,8 @@
      */
     public static final int FLING_EXPAND = 0;
 
-    static final String COUNTER_PANEL_OPEN = "panel_open";
-    static final String COUNTER_PANEL_OPEN_QS = "panel_open_qs";
+    public static final String COUNTER_PANEL_OPEN = "panel_open";
+    public static final String COUNTER_PANEL_OPEN_QS = "panel_open_qs";
 
     private int mCurrentPanelAlpha;
     private final Paint mAlphaPaint = new Paint();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
rename to packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 5810d64..893a409 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.shade;
 
 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
 
@@ -40,8 +40,6 @@
 import static com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManagerKt.STATE_OPENING;
 import static com.android.systemui.util.DumpUtilsKt.asIndenting;
 
-import static java.lang.Float.isNaN;
-
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
@@ -50,13 +48,13 @@
 import android.app.Fragment;
 import android.app.StatusBarManager;
 import android.content.ContentResolver;
-import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.ColorFilter;
 import android.graphics.Insets;
 import android.graphics.Paint;
+import android.graphics.PixelFormat;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.Region;
@@ -79,6 +77,7 @@
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
+import android.view.View.AccessibilityDelegate;
 import android.view.ViewGroup;
 import android.view.ViewPropertyAnimator;
 import android.view.ViewStub;
@@ -141,6 +140,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
 import com.android.systemui.qrcodescanner.controller.QRCodeScannerController;
 import com.android.systemui.screenrecord.RecordingController;
+import com.android.systemui.shade.transition.ShadeTransitionController;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.GestureRecorder;
@@ -177,12 +177,35 @@
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
 import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
+import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
+import com.android.systemui.statusbar.phone.KeyguardBottomAreaViewController;
+import com.android.systemui.statusbar.phone.KeyguardBouncer;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.KeyguardClockPositionAlgorithm;
+import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
+import com.android.systemui.statusbar.phone.KeyguardStatusBarViewController;
+import com.android.systemui.statusbar.phone.LargeScreenShadeHeaderController;
+import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
 import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent;
+import com.android.systemui.statusbar.phone.NotificationIconAreaController;
+import com.android.systemui.statusbar.phone.PanelView;
+import com.android.systemui.statusbar.phone.PanelViewController;
+import com.android.systemui.statusbar.phone.PhoneStatusBarView;
+import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
+import com.android.systemui.statusbar.phone.ScrimController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
+import com.android.systemui.statusbar.phone.TapAgainViewController;
+import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
 import com.android.systemui.statusbar.phone.panelstate.PanelState;
-import com.android.systemui.statusbar.phone.shade.transition.ShadeTransitionController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardQsUserSwitchController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -195,7 +218,6 @@
 import com.android.systemui.util.LargeScreenUtils;
 import com.android.systemui.util.ListenerSet;
 import com.android.systemui.util.Utils;
-import com.android.systemui.util.settings.SecureSettings;
 import com.android.systemui.util.time.SystemClock;
 import com.android.systemui.wallet.controller.QuickAccessWalletController;
 import com.android.wm.shell.animation.FlingAnimationUtils;
@@ -207,14 +229,13 @@
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
-import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 
 import javax.inject.Inject;
 import javax.inject.Provider;
 
 @CentralSurfacesComponent.CentralSurfacesScope
-public class NotificationPanelViewController extends PanelViewController {
+public final class NotificationPanelViewController extends PanelViewController {
 
     private static final boolean DEBUG_LOGCAT = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG);
     private static final boolean SPEW_LOGCAT = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.VERBOSE);
@@ -260,7 +281,8 @@
     private final ConfigurationListener mConfigurationListener = new ConfigurationListener();
     private final SettingsChangeObserver mSettingsChangeObserver;
 
-    @VisibleForTesting final StatusBarStateListener mStatusBarStateListener =
+    @VisibleForTesting
+    final StatusBarStateListener mStatusBarStateListener =
             new StatusBarStateListener();
     private final NotificationPanelView mView;
     private final VibratorHelper mVibratorHelper;
@@ -332,19 +354,20 @@
     private KeyguardUserSwitcherController mKeyguardUserSwitcherController;
     private KeyguardStatusBarView mKeyguardStatusBar;
     private KeyguardStatusBarViewController mKeyguardStatusBarViewController;
-    @VisibleForTesting QS mQs;
+    @VisibleForTesting
+    QS mQs;
     private FrameLayout mQsFrame;
-    private QsFrameTranslateController mQsFrameTranslateController;
+    private final QsFrameTranslateController mQsFrameTranslateController;
     private KeyguardStatusViewController mKeyguardStatusViewController;
-    private LockIconViewController mLockIconViewController;
+    private final LockIconViewController mLockIconViewController;
     private NotificationsQuickSettingsContainer mNotificationContainerParent;
-    private NotificationsQSContainerController mNotificationsQSContainerController;
+    private final NotificationsQSContainerController mNotificationsQSContainerController;
     private final Provider<KeyguardBottomAreaViewController>
             mKeyguardBottomAreaViewControllerProvider;
     private boolean mAnimateNextPositionUpdate;
     private float mQuickQsHeaderHeight;
-    private ScreenOffAnimationController mScreenOffAnimationController;
-    private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
+    private final ScreenOffAnimationController mScreenOffAnimationController;
+    private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
 
     private int mTrackingPointer;
     private VelocityTracker mQsVelocityTracker;
@@ -397,12 +420,6 @@
     private int mLargeScreenShadeHeaderHeight;
     private int mSplitShadeNotificationsScrimMarginBottom;
 
-    /**
-     * Vertical overlap allowed between the bottom of the notification shelf and
-     * the top of the lock icon or the under-display fingerprint sensor background.
-     */
-    private int mShelfAndLockIconOverlap;
-
     private final KeyguardClockPositionAlgorithm
             mClockPositionAlgorithm =
             new KeyguardClockPositionAlgorithm();
@@ -417,7 +434,8 @@
      * Determines if QS should be already expanded when expanding shade.
      * Used for split shade, two finger gesture as well as accessibility shortcut to QS.
      */
-    @VisibleForTesting boolean mQsExpandImmediate;
+    @VisibleForTesting
+    boolean mQsExpandImmediate;
     private boolean mTwoFingerQsExpandPossible;
     private String mHeaderDebugInfo;
 
@@ -439,14 +457,13 @@
     private int mNavigationBarBottomHeight;
     private boolean mExpandingFromHeadsUp;
     private boolean mCollapsedOnDown;
-    private int mPositionMinSideMargin;
     private boolean mClosingWithAlphaFadeOut;
     private boolean mHeadsUpAnimatingAway;
     private boolean mLaunchingAffordance;
     private final FalsingManager mFalsingManager;
     private final FalsingCollector mFalsingCollector;
 
-    private Runnable mHeadsUpExistenceChangedRunnable = () -> {
+    private final Runnable mHeadsUpExistenceChangedRunnable = () -> {
         setHeadsUpAnimatingAway(false);
         updatePanelExpansionAndVisibility();
     };
@@ -456,9 +473,6 @@
     private boolean mIsFullWidth;
     private boolean mBlockingExpansionForCurrentTouch;
 
-    // TODO (b/204204226): no longer needed once refactor is complete
-    private final boolean mUseCombinedQSHeaders;
-
     /**
      * Following variables maintain state of events when input focus transfer may occur.
      */
@@ -502,10 +516,10 @@
                     mPanelAlphaAnimator.getProperty(), Interpolators.ALPHA_OUT);
     private final AnimationProperties mPanelAlphaInPropertiesAnimator =
             new AnimationProperties().setDuration(200).setAnimationEndAction((property) -> {
-                            if (mPanelAlphaEndAction != null) {
-                                mPanelAlphaEndAction.run();
-                            }
-                        }).setCustomInterpolator(
+                if (mPanelAlphaEndAction != null) {
+                    mPanelAlphaEndAction.run();
+                }
+            }).setCustomInterpolator(
                     mPanelAlphaAnimator.getProperty(), Interpolators.ALPHA_IN);
     private final NotificationEntryManager mEntryManager;
 
@@ -514,19 +528,10 @@
     private final MediaDataManager mMediaDataManager;
     private final SysUiState mSysUiState;
 
-    private NotificationShadeDepthController mDepthController;
-    private int mDisplayId;
+    private final NotificationShadeDepthController mDepthController;
+    private final int mDisplayId;
 
-    /**
-     * Cache the resource id of the theme to avoid unnecessary work in onThemeChanged.
-     *
-     * onThemeChanged is forced when the theme might not have changed. So, to avoid unncessary
-     * work, check the current id with the cached id.
-     */
-    private int mThemeResId;
     private KeyguardIndicationController mKeyguardIndicationController;
-    private int mShelfHeight;
-    private int mDarkIconSize;
     private int mHeadsUpInset;
     private boolean mHeadsUpPinnedMode;
     private boolean mAllowExpandForSmallExpansion;
@@ -640,15 +645,12 @@
     private final ContentResolver mContentResolver;
     private float mMinFraction;
 
-    private final Executor mUiExecutor;
-    private final SecureSettings mSecureSettings;
-
-    private KeyguardMediaController mKeyguardMediaController;
+    private final KeyguardMediaController mKeyguardMediaController;
 
     private boolean mStatusViewCentered = true;
 
-    private Optional<KeyguardUnfoldTransition> mKeyguardUnfoldTransition;
-    private Optional<NotificationPanelUnfoldAnimationController>
+    private final Optional<KeyguardUnfoldTransition> mKeyguardUnfoldTransition;
+    private final Optional<NotificationPanelUnfoldAnimationController>
             mNotificationPanelUnfoldAnimationController;
 
     /** The drag distance required to fully expand the split shade. */
@@ -659,9 +661,13 @@
 
     private final NPVCDownEventState.Buffer mLastDownEvents;
 
-    private View.AccessibilityDelegate mAccessibilityDelegate = new View.AccessibilityDelegate() {
+    private final Runnable mAnimateKeyguardBottomAreaInvisibleEndRunnable =
+            () -> mKeyguardBottomArea.setVisibility(View.GONE);
+
+    private final AccessibilityDelegate mAccessibilityDelegate = new AccessibilityDelegate() {
         @Override
-        public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+        public void onInitializeAccessibilityNodeInfo(View host,
+                AccessibilityNodeInfo info) {
             super.onInitializeAccessibilityNodeInfo(host, info);
             info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD);
             info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_UP);
@@ -669,7 +675,8 @@
 
         @Override
         public boolean performAccessibilityAction(View host, int action, Bundle args) {
-            if (action == AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD.getId()
+            if (action
+                    == AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD.getId()
                     || action
                     == AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_UP.getId()) {
                 mStatusBarKeyguardViewManager.showBouncer(true);
@@ -696,7 +703,6 @@
 
     @Inject
     public NotificationPanelViewController(NotificationPanelView view,
-            @Main Resources resources,
             @Main Handler handler,
             LayoutInflater layoutInflater,
             FeatureFlags featureFlags,
@@ -746,8 +752,6 @@
             QuickAccessWalletController quickAccessWalletController,
             QRCodeScannerController qrCodeScannerController,
             RecordingController recordingController,
-            @Main Executor uiExecutor,
-            SecureSettings secureSettings,
             LargeScreenShadeHeaderController largeScreenShadeHeaderController,
             ScreenOffAnimationController screenOffAnimationController,
             LockscreenGestureLogger lockscreenGestureLogger,
@@ -834,8 +838,6 @@
         mUserManager = userManager;
         mMediaDataManager = mediaDataManager;
         mTapAgainViewController = tapAgainViewController;
-        mUiExecutor = uiExecutor;
-        mSecureSettings = secureSettings;
         mInteractionJankMonitor = interactionJankMonitor;
         mSysUiState = sysUiState;
         mPanelEventsEmitter = panelEventsEmitter;
@@ -845,7 +847,6 @@
             }
         });
         statusBarWindowStateController.addListener(this::onStatusBarWindowStateChanged);
-        mThemeResId = mView.getContext().getThemeResId();
         mKeyguardBypassController = bypassController;
         mUpdateMonitor = keyguardUpdateMonitor;
         mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
@@ -892,14 +893,14 @@
             mView.getOverlay().add(new DebugDrawable());
         }
 
-        mKeyguardUnfoldTransition = unfoldComponent.map(c -> c.getKeyguardUnfoldTransition());
+        mKeyguardUnfoldTransition = unfoldComponent.map(
+                SysUIUnfoldComponent::getKeyguardUnfoldTransition);
         mNotificationPanelUnfoldAnimationController = unfoldComponent.map(
                 SysUIUnfoldComponent::getNotificationPanelUnfoldAnimationController);
 
         mQsFrameTranslateController = qsFrameTranslateController;
         updateUserSwitcherFlags();
         onFinishInflate();
-        mUseCombinedQSHeaders = featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS);
         keyguardUnlockAnimationController.addKeyguardUnlockAnimationListener(
                 new KeyguardUnlockAnimationController.KeyguardUnlockAnimationListener() {
                     @Override
@@ -975,8 +976,8 @@
 
         mKeyguardStatusBarViewController =
                 mKeyguardStatusBarViewComponentFactory.build(
-                        mKeyguardStatusBar,
-                        mNotificationPanelViewStateProvider)
+                                mKeyguardStatusBar,
+                                mNotificationPanelViewStateProvider)
                         .getKeyguardStatusBarViewController();
         mKeyguardStatusBarViewController.init();
 
@@ -1047,12 +1048,8 @@
         mQsPeekHeight = mResources.getDimensionPixelSize(R.dimen.qs_peek_height);
         mClockPositionAlgorithm.loadDimens(mResources);
         mQsFalsingThreshold = mResources.getDimensionPixelSize(R.dimen.qs_falsing_threshold);
-        mPositionMinSideMargin = mResources.getDimensionPixelSize(
-                R.dimen.notification_panel_min_side_margin);
         mIndicationBottomPadding = mResources.getDimensionPixelSize(
                 R.dimen.keyguard_indication_bottom_padding);
-        mShelfHeight = mResources.getDimensionPixelSize(R.dimen.notification_shelf_height);
-        mDarkIconSize = mResources.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size_dark);
         int statusbarHeight = SystemBarUtils.getStatusBarHeight(mView.getContext());
         mHeadsUpInset = statusbarHeight + mResources.getDimensionPixelSize(
                 R.dimen.heads_up_status_bar_padding);
@@ -1110,16 +1107,12 @@
     private void setCentralSurfaces(CentralSurfaces centralSurfaces) {
         // TODO: this can be injected.
         mCentralSurfaces = centralSurfaces;
-        mKeyguardBottomArea.setCentralSurfaces(mCentralSurfaces);
     }
 
     public void updateResources() {
         mSplitShadeNotificationsScrimMarginBottom =
                 mResources.getDimensionPixelSize(
                         R.dimen.split_shade_notifications_scrim_margin_bottom);
-        mShelfAndLockIconOverlap =
-                mResources.getDimensionPixelSize(R.dimen.shelf_and_lock_icon_overlap);
-
         final boolean newSplitShadeEnabled =
                 LargeScreenUtils.shouldUseSplitNotificationShade(mResources);
         final boolean splitShadeChanged = mSplitShadeEnabled != newSplitShadeEnabled;
@@ -1283,11 +1276,11 @@
     }
 
     private void initBottomArea() {
-        mKeyguardBottomArea.setCentralSurfaces(mCentralSurfaces);
-        mKeyguardBottomArea.setFalsingManager(mFalsingManager);
-        mKeyguardBottomArea.initWallet(mQuickAccessWalletController);
-        mKeyguardBottomArea.initControls(mControlsComponent);
-        mKeyguardBottomArea.initQRCodeScanner(mQRCodeScannerController);
+        mKeyguardBottomArea.init(
+                mFalsingManager,
+                mQuickAccessWalletController,
+                mControlsComponent,
+                mQRCodeScannerController);
     }
 
     @VisibleForTesting
@@ -1297,7 +1290,7 @@
 
     private void updateMaxDisplayedNotifications(boolean recompute) {
         if (recompute) {
-            mMaxAllowedKeyguardNotifications = Math.max(computeMaxKeyguardNotifications(), 1);
+            setMaxDisplayedNotifications(Math.max(computeMaxKeyguardNotifications(), 1));
         } else {
             if (SPEW_LOGCAT) Log.d(TAG, "Skipping computeMaxKeyguardNotifications() by request");
         }
@@ -1325,7 +1318,7 @@
 
     private void updateGestureExclusionRect() {
         Rect exclusionRect = calculateGestureExclusionRect();
-        mView.setSystemGestureExclusionRects(exclusionRect.isEmpty() ? Collections.EMPTY_LIST
+        mView.setSystemGestureExclusionRects(exclusionRect.isEmpty() ? Collections.emptyList()
                 : Collections.singletonList(exclusionRect));
     }
 
@@ -1353,14 +1346,11 @@
         mQsSizeChangeAnimator = ValueAnimator.ofInt(oldHeight, newHeight);
         mQsSizeChangeAnimator.setDuration(300);
         mQsSizeChangeAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
-        mQsSizeChangeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                requestScrollerTopPaddingUpdate(false /* animate */);
-                requestPanelHeightUpdate();
-                int height = (int) mQsSizeChangeAnimator.getAnimatedValue();
-                mQs.setHeightOverride(height);
-            }
+        mQsSizeChangeAnimator.addUpdateListener(animation -> {
+            requestScrollerTopPaddingUpdate(false /* animate */);
+            requestPanelHeightUpdate();
+            int height = (int) mQsSizeChangeAnimator.getAnimatedValue();
+            mQs.setHeightOverride(height);
         });
         mQsSizeChangeAnimator.addListener(new AnimatorListenerAdapter() {
             @Override
@@ -1701,11 +1691,16 @@
         setQsExpansion(mQsMinExpansionHeight);
     }
 
+    @Override
+    @VisibleForTesting
+    protected void cancelHeightAnimator() {
+        super.cancelHeightAnimator();
+    }
+
     public void cancelAnimation() {
         mView.animate().cancel();
     }
 
-
     /**
      * Animate QS closing by flinging it.
      * If QS is expanded, it will collapse into QQS and stop.
@@ -1905,12 +1900,8 @@
             mListenForHeadsUp = mCollapsedOnDown && mHeadsUpManager.hasPinnedHeadsUp();
             mAllowExpandForSmallExpansion = mExpectingSynthesizedDown;
             mTouchSlopExceededBeforeDown = mExpectingSynthesizedDown;
-            if (mExpectingSynthesizedDown) {
-                mLastEventSynthesizedDown = true;
-            } else {
-                // down but not synthesized motion event.
-                mLastEventSynthesizedDown = false;
-            }
+            // When false, down but not synthesized motion event.
+            mLastEventSynthesizedDown = mExpectingSynthesizedDown;
             mLastDownEvents.insert(
                     mSystemClock.currentTimeMillis(),
                     mDownX,
@@ -1935,7 +1926,6 @@
      *
      * @param downX the x location where the touch started
      * @param downY the y location where the touch started
-     *
      * @return true if the panel could be collapsed because it stared on QQS
      */
     private boolean canPanelCollapseOnQQS(float downX, float downY) {
@@ -1944,7 +1934,7 @@
         }
         View header = mQs == null ? mKeyguardStatusBar : mQs.getHeader();
         return downX >= mQsFrame.getX() && downX <= mQsFrame.getX() + mQsFrame.getWidth()
-                        && downY <= header.getBottom();
+                && downY <= header.getBottom();
 
     }
 
@@ -2089,7 +2079,7 @@
             return false;
         }
         return y <= mNotificationStackScrollLayoutController.getBottomMostNotificationBottom()
-                        || y <= mQs.getView().getY() + mQs.getView().getHeight();
+                || y <= mQs.getView().getY() + mQs.getView().getHeight();
     }
 
     private boolean isOpenQsEvent(MotionEvent event) {
@@ -2268,15 +2258,11 @@
     }
 
     private void onQsExpansionStarted() {
-        onQsExpansionStarted(0);
-    }
-
-    protected void onQsExpansionStarted(int overscrollAmount) {
         cancelQsAnimation();
         cancelHeightAnimator();
 
         // Reset scroll position and apply that position to the expanded height.
-        float height = mQsExpansionHeight - overscrollAmount;
+        float height = mQsExpansionHeight;
         setQsExpansion(height);
         requestPanelHeightUpdate();
         mNotificationStackScrollLayoutController.checkSnoozeLeavebehind();
@@ -2288,7 +2274,8 @@
         }
     }
 
-    @VisibleForTesting void setQsExpanded(boolean expanded) {
+    @VisibleForTesting
+    void setQsExpanded(boolean expanded) {
         boolean changed = mQsExpanded != expanded;
         if (changed) {
             mQsExpanded = expanded;
@@ -2313,13 +2300,6 @@
         }
     }
 
-    private final Runnable mAnimateKeyguardBottomAreaInvisibleEndRunnable = new Runnable() {
-        @Override
-        public void run() {
-            mKeyguardBottomArea.setVisibility(View.GONE);
-        }
-    };
-
     private void setKeyguardBottomAreaVisibility(int statusBarState, boolean goingToFullShade) {
         mKeyguardBottomArea.animate().cancel();
         if (goingToFullShade) {
@@ -2437,7 +2417,7 @@
             }
             setQSClippingBounds();
         }
-    };
+    }
 
     private void onNotificationScrolled(int newScrollPosition) {
         updateQSExpansionEnabledAmbient();
@@ -2602,7 +2582,7 @@
             boolean pulseExpanding = mPulseExpansionHandler.isExpanding();
             if (mTransitioningToFullShadeProgress > 0.0f || pulseExpanding
                     || (mQsClippingAnimation != null
-                        && (mIsQsTranslationResetAnimator || mIsPulseExpansionResetAnimator))) {
+                    && (mIsQsTranslationResetAnimator || mIsPulseExpansionResetAnimator))) {
                 if (pulseExpanding || mIsPulseExpansionResetAnimator) {
                     // qsTranslation should only be positive during pulse expansion because it's
                     // already translating in from the top
@@ -2621,8 +2601,8 @@
             mQs.setFancyClipping(
                     mQsClipTop,
                     mQsClipBottom,
-                    radius, qsVisible
-                    && !mSplitShadeEnabled);
+                    radius,
+                    qsVisible && !mSplitShadeEnabled);
         }
         mKeyguardStatusViewController.setClipBounds(
                 clipStatusView ? mKeyguardStatusAreaClipBounds : null);
@@ -2746,8 +2726,7 @@
         }
     }
 
-
-    protected void requestScrollerTopPaddingUpdate(boolean animate) {
+    private void requestScrollerTopPaddingUpdate(boolean animate) {
         mNotificationStackScrollLayoutController.updateTopPadding(
                 calculateNotificationsTopPadding(), animate);
         if (mKeyguardShowing && mKeyguardBypassController.getBypassEnabled()) {
@@ -2895,7 +2874,7 @@
      * @param onFinishRunnable Runnable to be executed at the end of animation.
      * @param isClick          If originated by click (different interpolator and duration.)
      */
-    protected void flingSettings(float vel, int type, final Runnable onFinishRunnable,
+    private void flingSettings(float vel, int type, final Runnable onFinishRunnable,
             boolean isClick) {
         float target;
         switch (type) {
@@ -2937,11 +2916,11 @@
         if (oppositeDirection) {
             animator.setDuration(350);
         }
-        animator.addUpdateListener(animation -> {
-            setQsExpansion((Float) animation.getAnimatedValue());
-        });
+        animator.addUpdateListener(
+                animation -> setQsExpansion((Float) animation.getAnimatedValue()));
         animator.addListener(new AnimatorListenerAdapter() {
             private boolean mIsCanceled;
+
             @Override
             public void onAnimationStart(Animator animation) {
                 notifyExpandingStarted();
@@ -3015,7 +2994,7 @@
     }
 
     @Override
-    protected int getMaxPanelHeight() {
+    public int getMaxPanelHeight() {
         int min = mStatusBarMinHeight;
         if (!(mBarState == KEYGUARD)
                 && mNotificationStackScrollLayoutController.getNotGoneChildCount() == 0) {
@@ -3039,7 +3018,7 @@
             maxHeight = calculatePanelHeightShade();
         }
         maxHeight = Math.max(min, maxHeight);
-        if (maxHeight == 0 || isNaN(maxHeight)) {
+        if (maxHeight == 0) {
             Log.wtf(TAG, "maxPanelHeight is invalid. mOverExpansion: "
                     + mOverExpansion + ", calculatePanelHeightQsExpanded: "
                     + calculatePanelHeightQsExpanded() + ", calculatePanelHeightShade: "
@@ -3119,12 +3098,14 @@
         }
     }
 
-    boolean isPanelExpanded() {
+    public boolean isPanelExpanded() {
         return mPanelExpanded;
     }
 
     private int calculatePanelHeightShade() {
-        final int maxHeight = mNotificationStackScrollLayoutController.getHeight();
+        int emptyBottomMargin = mNotificationStackScrollLayoutController.getEmptyBottomMargin();
+        int maxHeight = mNotificationStackScrollLayoutController.getHeight() - emptyBottomMargin;
+
         if (mBarState == KEYGUARD) {
             int minKeyguardPanelBottom = mClockPositionAlgorithm.getLockscreenStatusViewHeight()
                     + mNotificationStackScrollLayoutController.getIntrinsicContentHeight();
@@ -3202,7 +3183,7 @@
         updateQsExpansion();
     }
 
-    protected float getHeaderTranslation() {
+    private float getHeaderTranslation() {
         if (mBarState == KEYGUARD && !mKeyguardBypassController.getBypassEnabled()) {
             return -mQs.getQsMinExpansionHeight();
         }
@@ -3233,14 +3214,7 @@
                 getExpandedFraction());
         float alpha = Math.min(expansionAlpha, 1 - computeQsExpansionFraction());
         alpha *= mBottomAreaShadeAlpha;
-        mKeyguardBottomArea.setAffordanceAlpha(alpha);
-        mKeyguardBottomArea.setImportantForAccessibility(
-                alpha == 0f ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
-                        : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
-        View ambientIndicationContainer = mCentralSurfaces.getAmbientIndicationContainer();
-        if (ambientIndicationContainer != null) {
-            ambientIndicationContainer.setAlpha(alpha);
-        }
+        mKeyguardBottomArea.setComponentAlphas(alpha);
         mLockIconViewController.setAlpha(alpha);
     }
 
@@ -3272,22 +3246,13 @@
         mMediaHierarchyManager.setCollapsingShadeFromQS(false);
         mMediaHierarchyManager.setQsExpanded(mQsExpanded);
         if (isFullyCollapsed()) {
-            DejankUtils.postAfterTraversal(new Runnable() {
-                @Override
-                public void run() {
-                    setListening(false);
-                }
-            });
+            DejankUtils.postAfterTraversal(() -> setListening(false));
 
             // Workaround b/22639032: Make sure we invalidate something because else RenderThread
             // thinks we are actually drawing a frame put in reality we don't, so RT doesn't go
             // ahead with rendering and we jank.
-            mView.postOnAnimation(new Runnable() {
-                @Override
-                public void run() {
-                    mView.getParent().invalidateChild(mView, M_DUMMY_DIRTY_RECT);
-                }
-            });
+            mView.postOnAnimation(
+                    () -> mView.getParent().invalidateChild(mView, M_DUMMY_DIRTY_RECT));
         } else {
             setListening(true);
         }
@@ -3487,13 +3452,13 @@
                     if (mUpdateMonitor.isFaceEnrolled()
                             && !mUpdateMonitor.isFaceDetectionRunning()
                             && !mUpdateMonitor.getUserCanSkipBouncer(
-                                    KeyguardUpdateMonitor.getCurrentUser())) {
+                            KeyguardUpdateMonitor.getCurrentUser())) {
                         mUpdateMonitor.requestFaceAuth(true);
                     } else {
                         mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_HINT,
                                 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
                         mLockscreenGestureLogger
-                            .log(LockscreenUiEvent.LOCKSCREEN_LOCK_SHOW_HINT);
+                                .log(LockscreenUiEvent.LOCKSCREEN_LOCK_SHOW_HINT);
                         startUnlockHintAnimation();
                     }
                     if (mUpdateMonitor.isFaceEnrolled()) {
@@ -3572,7 +3537,7 @@
         mNotificationStackScrollLayoutController.forceNoOverlappingRendering(closing);
     }
 
-    protected void updateExpandedHeight(float expandedHeight) {
+    private void updateExpandedHeight(float expandedHeight) {
         if (mTracking) {
             mNotificationStackScrollLayoutController
                     .setExpandingVelocity(getCurrentExpandVelocity());
@@ -3595,12 +3560,10 @@
     }
 
     private void updateStatusBarIcons() {
-        boolean
-                showIconsWhenExpanded =
+        boolean showIconsWhenExpanded =
                 (isPanelVisibleBecauseOfHeadsUp() || isFullWidth())
                         && getExpandedHeight() < getOpeningHeight();
-        boolean noVisibleNotifications = true;
-        if (showIconsWhenExpanded && noVisibleNotifications && isOnKeyguard()) {
+        if (showIconsWhenExpanded && isOnKeyguard()) {
             showIconsWhenExpanded = false;
         }
         if (showIconsWhenExpanded != mShowIconsWhenExpanded) {
@@ -3892,24 +3855,25 @@
      */
     public void startFoldToAodAnimation(Runnable endAction) {
         mView.animate()
-            .translationX(0)
-            .alpha(1f)
-            .setDuration(ANIMATION_DURATION_FOLD_TO_AOD)
-            .setInterpolator(EMPHASIZED_DECELERATE)
-            .setListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationCancel(Animator animation) {
-                    endAction.run();
-                }
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    endAction.run();
-                }
-            })
-            .setUpdateListener(anim -> {
-                mKeyguardStatusViewController.animateFoldToAod(anim.getAnimatedFraction());
-            })
-            .start();
+                .translationX(0)
+                .alpha(1f)
+                .setDuration(ANIMATION_DURATION_FOLD_TO_AOD)
+                .setInterpolator(EMPHASIZED_DECELERATE)
+                .setListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationCancel(Animator animation) {
+                        endAction.run();
+                    }
+
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        endAction.run();
+                    }
+                })
+                .setUpdateListener(anim -> {
+                    mKeyguardStatusViewController.animateFoldToAod(anim.getAnimatedFraction());
+                })
+                .start();
     }
 
     /**
@@ -3921,7 +3885,6 @@
         resetTranslation();
     }
 
-    /** */
     public void setImportantForAccessibility(int mode) {
         mView.setImportantForAccessibility(mode);
     }
@@ -3969,7 +3932,6 @@
      * {@link ShadeViewManager}.
      */
     public void updateNotificationViews(String reason) {
-        mNotificationStackScrollLayoutController.updateSectionBoundaries(reason);
         mNotificationStackScrollLayoutController.updateFooter();
 
         mNotificationIconAreaController.updateNotificationIcons(createVisibleEntriesList());
@@ -4256,8 +4218,7 @@
             };
 
     @Override
-    protected PanelViewController.OnConfigurationChangedListener
-            createOnConfigurationChangedListener() {
+    protected OnConfigurationChangedListener createOnConfigurationChangedListener() {
         return new OnConfigurationChangedListener();
     }
 
@@ -4314,7 +4275,7 @@
                     + isFullyExpanded() + " inQs=" + isInSettings());
         }
         mSysUiState.setFlag(SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED,
-                isFullyExpanded() && !isInSettings())
+                        isFullyExpanded() && !isInSettings())
                 .setFlag(SYSUI_STATE_QUICK_SETTINGS_EXPANDED, isInSettings())
                 .commitUpdate(mDisplayId);
     }
@@ -4490,7 +4451,6 @@
         @Override
         public void onThemeChanged() {
             if (DEBUG_LOGCAT) Log.d(TAG, "onThemeChanged");
-            mThemeResId = mView.getContext().getThemeResId();
             reInflateViews();
         }
 
@@ -4639,6 +4599,7 @@
     public interface NotificationPanelViewStateProvider {
         /** Returns the expanded height of the panel view. */
         float getPanelViewExpandedHeight();
+
         /**
          * Returns true if heads up should be visible.
          *
@@ -4700,7 +4661,7 @@
         @Override
         public void onViewAttachedToWindow(View v) {
             mFragmentService.getFragmentHostManager(mView)
-                            .addTagListener(QS.TAG, mFragmentListener);
+                    .addTagListener(QS.TAG, mFragmentListener);
             mStatusBarStateController.addCallback(mStatusBarStateListener);
             mStatusBarStateListener.onStateChanged(mStatusBarStateController.getState());
             mConfigurationController.addCallback(mConfigurationListener);
@@ -4717,7 +4678,7 @@
         public void onViewDetachedFromWindow(View v) {
             unregisterSettingsChangeListener();
             mFragmentService.getFragmentHostManager(mView)
-                            .removeTagListener(QS.TAG, mFragmentListener);
+                    .removeTagListener(QS.TAG, mFragmentListener);
             mStatusBarStateController.removeCallback(mStatusBarStateListener);
             mConfigurationController.removeCallback(mConfigurationListener);
             mFalsingManager.removeTapListener(mFalsingTapListener);
@@ -4799,7 +4760,7 @@
         private final Paint mDebugPaint = new Paint();
 
         @Override
-        public void draw(@NonNull Canvas canvas) {
+        public void draw(@androidx.annotation.NonNull @NonNull Canvas canvas) {
             mDebugTextUsedYPositions.clear();
 
             mDebugPaint.setColor(Color.RED);
@@ -4873,7 +4834,7 @@
 
         @Override
         public int getOpacity() {
-            return 0;
+            return PixelFormat.UNKNOWN;
         }
     }
 
@@ -4927,6 +4888,16 @@
         return mStatusBarViewTouchEventHandler;
     }
 
+    @VisibleForTesting
+    StatusBarStateController getStatusBarStateController() {
+        return mStatusBarStateController;
+    }
+
+    @VisibleForTesting
+    boolean isHintAnimationRunning() {
+        return mHintAnimationRunning;
+    }
+
     private void onStatusBarWindowStateChanged(@StatusBarManager.WindowVisibleState int state) {
         if (state != WINDOW_STATE_SHOWING
                 && mStatusBarStateController.getState() == StatusBarState.SHADE) {
@@ -4943,15 +4914,16 @@
         private final ListenerSet<Listener> mListeners = new ListenerSet<>();
 
         @Inject
-        PanelEventsEmitter() {}
+        PanelEventsEmitter() {
+        }
 
         @Override
-        public void registerListener(@NonNull Listener listener) {
+        public void registerListener(@androidx.annotation.NonNull @NonNull Listener listener) {
             mListeners.addIfAbsent(listener);
         }
 
         @Override
-        public void unregisterListener(@NonNull Listener listener) {
+        public void unregisterListener(@androidx.annotation.NonNull @NonNull Listener listener) {
             mListeners.remove(listener);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
similarity index 99%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java
rename to packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
index 1e3a02b..121d69d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.shade;
 
 import static android.view.WindowInsets.Type.systemBars;
 
@@ -52,6 +52,7 @@
 import com.android.internal.view.FloatingActionMode;
 import com.android.internal.widget.floatingtoolbar.FloatingToolbar;
 import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 
 /**
  * Combined keyguard and notification panel view. Also holding backdrop and scrims.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
rename to packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index be5b33e..b8546df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.shade;
 
 import android.app.StatusBarManager;
 import android.hardware.display.AmbientDisplayConfiguration;
@@ -46,6 +46,9 @@
 import com.android.systemui.statusbar.notification.stack.AmbientState;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.phone.PhoneStatusBarViewController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
 import com.android.systemui.statusbar.window.StatusBarWindowStateController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt
rename to packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
index ebedbf9..13a5615 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
@@ -1,4 +1,4 @@
-package com.android.systemui.statusbar.phone
+package com.android.systemui.shade
 
 import android.view.View
 import android.view.ViewGroup
@@ -6,11 +6,7 @@
 import android.view.WindowInsets
 import androidx.annotation.VisibleForTesting
 import androidx.constraintlayout.widget.ConstraintSet
-import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
-import androidx.constraintlayout.widget.ConstraintSet.END
-import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
-import androidx.constraintlayout.widget.ConstraintSet.START
-import androidx.constraintlayout.widget.ConstraintSet.TOP
+import androidx.constraintlayout.widget.ConstraintSet.*
 import com.android.systemui.R
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.flags.FeatureFlags
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java
similarity index 99%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
rename to packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java
index 2446cf7..587e0e6d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.shade;
 
 import android.app.Fragment;
 import android.content.Context;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/OWNERS b/packages/SystemUI/src/com/android/systemui/shade/OWNERS
new file mode 100644
index 0000000..133711e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/OWNERS
@@ -0,0 +1,13 @@
+per-file *Notification* = set noparent
+per-file *Notification* = file:../statusbar/notification/OWNERS
+
+per-file NotificationsQuickSettingsContainer.java = kozynski@google.com, asc@google.com
+per-file NotificationsQSContainerController.kt = kozynski@google.com, asc@google.com
+
+per-file NotificationShadeWindowViewController.java = pixel@google.com, cinek@google.com, juliacr@google.com
+per-file NotificationShadeWindowView.java = pixel@google.com, cinek@google.com, juliacr@google.com
+
+per-file NotificationPanelUnfoldAnimationController.kt = alexflo@google.com, jeffdq@google.com, juliacr@google.com
+
+per-file NotificationPanelView.java = pixel@google.com, cinek@google.com, juliacr@google.com, justinweir@google.com
+per-file NotificationPanelViewController.java = pixel@google.com, cinek@google.com, juliacr@google.com, justinweir@google.com
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/NoOpOverScroller.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/NoOpOverScroller.kt
similarity index 87%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/NoOpOverScroller.kt
rename to packages/SystemUI/src/com/android/systemui/shade/transition/NoOpOverScroller.kt
index 2789db8..f4db3ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/NoOpOverScroller.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/transition/NoOpOverScroller.kt
@@ -1,4 +1,4 @@
-package com.android.systemui.statusbar.phone.shade.transition
+package com.android.systemui.shade.transition
 
 import javax.inject.Inject
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/ScrimShadeTransitionController.kt
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionController.kt
rename to packages/SystemUI/src/com/android/systemui/shade/transition/ScrimShadeTransitionController.kt
index 1b8afb9..afd57da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/transition/ScrimShadeTransitionController.kt
@@ -1,4 +1,4 @@
-package com.android.systemui.statusbar.phone.shade.transition
+package com.android.systemui.shade.transition
 
 import android.content.res.Configuration
 import android.content.res.Resources
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ShadeOverScroller.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeOverScroller.kt
similarity index 82%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ShadeOverScroller.kt
rename to packages/SystemUI/src/com/android/systemui/shade/transition/ShadeOverScroller.kt
index f1cedeb..6c3a028 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ShadeOverScroller.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeOverScroller.kt
@@ -1,4 +1,4 @@
-package com.android.systemui.statusbar.phone.shade.transition
+package com.android.systemui.shade.transition
 
 import com.android.systemui.statusbar.phone.panelstate.PanelState
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
similarity index 87%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionController.kt
rename to packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
index 71c6159..58acfb4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
@@ -1,4 +1,4 @@
-package com.android.systemui.statusbar.phone.shade.transition
+package com.android.systemui.shade.transition
 
 import android.content.Context
 import android.content.res.Configuration
@@ -6,8 +6,10 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.qs.QS
+import com.android.systemui.shade.NotificationPanelViewController
+import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.SysuiStatusBarStateController
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
-import com.android.systemui.statusbar.phone.NotificationPanelViewController
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager
 import com.android.systemui.statusbar.phone.panelstate.PanelState
@@ -27,7 +29,8 @@
     private val context: Context,
     private val splitShadeOverScrollerFactory: SplitShadeOverScroller.Factory,
     private val noOpOverScroller: NoOpOverScroller,
-    private val scrimShadeTransitionController: ScrimShadeTransitionController
+    private val scrimShadeTransitionController: ScrimShadeTransitionController,
+    private val statusBarStateController: SysuiStatusBarStateController,
 ) {
 
     lateinit var notificationPanelViewController: NotificationPanelViewController
@@ -43,7 +46,7 @@
     }
     private val shadeOverScroller: ShadeOverScroller
         get() =
-            if (inSplitShade && propertiesInitialized()) {
+            if (inSplitShade && isScreenUnlocked() && propertiesInitialized()) {
                 splitShadeOverScroller
             } else {
                 noOpOverScroller
@@ -90,6 +93,7 @@
             """
             ShadeTransitionController:
                 inSplitShade: $inSplitShade
+                isScreenUnlocked: ${isScreenUnlocked()}
                 currentPanelState: ${currentPanelState?.panelStateToString()}
                 lastPanelExpansionChangeEvent: $lastPanelExpansionChangeEvent
                 qs.isInitialized: ${this::qs.isInitialized}
@@ -97,4 +101,7 @@
                 nssl.isInitialized: ${this::notificationStackScrollLayoutController.isInitialized}
             """.trimIndent())
     }
+
+    private fun isScreenUnlocked() =
+        statusBarStateController.currentOrUpcomingState == StatusBarState.SHADE
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/SplitShadeOverScroller.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/SplitShadeOverScroller.kt
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/SplitShadeOverScroller.kt
rename to packages/SystemUI/src/com/android/systemui/shade/transition/SplitShadeOverScroller.kt
index c25aab8..204dd3c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/SplitShadeOverScroller.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/transition/SplitShadeOverScroller.kt
@@ -1,4 +1,4 @@
-package com.android.systemui.statusbar.phone.shade.transition
+package com.android.systemui.shade.transition
 
 import android.animation.Animator
 import android.animation.ValueAnimator
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 9e02909..ca14728 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -900,16 +900,36 @@
                 mStatusBarKeyguardViewManager.showBouncerMessage(message, mInitialTextColorState);
             }
         } else {
-            if (!mAccessibilityManager.isEnabled()
-                    && !mAccessibilityManager.isTouchExplorationEnabled()
-                    && mKeyguardUpdateMonitor.isUdfpsSupported()
-                    && mKeyguardUpdateMonitor.getUserCanSkipBouncer(
-                    KeyguardUpdateMonitor.getCurrentUser())) {
-                final int stringId = mKeyguardUpdateMonitor.getIsFaceAuthenticated()
-                        ? R.string.keyguard_face_successful_unlock_press
-                        : R.string.keyguard_unlock_press;
-                showBiometricMessage(mContext.getString(stringId));
+            final boolean canSkipBouncer = mKeyguardUpdateMonitor.getUserCanSkipBouncer(
+                    KeyguardUpdateMonitor.getCurrentUser());
+            if (canSkipBouncer) {
+                final boolean faceAuthenticated = mKeyguardUpdateMonitor.getIsFaceAuthenticated();
+                final boolean udfpsSupported = mKeyguardUpdateMonitor.isUdfpsSupported();
+                final boolean a11yEnabled = mAccessibilityManager.isEnabled()
+                        || mAccessibilityManager.isTouchExplorationEnabled();
+                if (udfpsSupported && faceAuthenticated) { // co-ex
+                    if (a11yEnabled) {
+                        showBiometricMessage(mContext.getString(
+                                R.string.keyguard_face_successful_unlock_swipe));
+                    } else {
+                        showBiometricMessage(mContext.getString(
+                                R.string.keyguard_face_successful_unlock_press));
+                    }
+                } else if (faceAuthenticated) { // face-only
+                    showBiometricMessage(mContext.getString(
+                            R.string.keyguard_face_successful_unlock_swipe));
+                } else if (udfpsSupported) { // udfps-only
+                    if (a11yEnabled) {
+                        showBiometricMessage(mContext.getString(R.string.keyguard_unlock));
+                    } else {
+                        showBiometricMessage(mContext.getString(
+                                R.string.keyguard_unlock_press));
+                    }
+                } else { // no security or unlocked by a trust agent
+                    showBiometricMessage(mContext.getString(R.string.keyguard_unlock));
+                }
             } else {
+                // suggest swiping up for the primary authentication bouncer
                 showBiometricMessage(mContext.getString(R.string.keyguard_unlock));
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt
index 01eb444..886ad68 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt
@@ -6,7 +6,7 @@
 import com.android.systemui.R
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.media.MediaHierarchyManager
-import com.android.systemui.statusbar.phone.NotificationPanelViewController
+import com.android.systemui.shade.NotificationPanelViewController
 import com.android.systemui.statusbar.policy.ConfigurationController
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index 9d80d5f..74d8f1b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -29,6 +29,7 @@
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.plugins.qs.QS
 import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.shade.NotificationPanelViewController
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.ExpandableView
@@ -37,7 +38,6 @@
 import com.android.systemui.statusbar.phone.CentralSurfaces
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.phone.LSShadeTransitionLogger
-import com.android.systemui.statusbar.phone.NotificationPanelViewController
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.util.LargeScreenUtils
 import java.io.PrintWriter
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
index 587c23b..9e77dbc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
@@ -68,6 +68,7 @@
 import com.android.systemui.statusbar.phone.ManagedProfileControllerImpl;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarIconControllerImpl;
+import com.android.systemui.statusbar.phone.StatusBarIconList;
 import com.android.systemui.statusbar.phone.StatusBarRemoteInputCallback;
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallFlags;
@@ -256,6 +257,16 @@
      */
     @Provides
     @SysUISingleton
+    static StatusBarIconList provideStatusBarIconList(Context context) {
+        return new StatusBarIconList(
+                context.getResources().getStringArray(
+                        com.android.internal.R.array.config_statusBarIcons));
+    }
+
+    /**
+     */
+    @Provides
+    @SysUISingleton
     static OngoingCallController provideOngoingCallController(
             Context context,
             CommonNotifCollection notifCollection,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
index a509fca..dfba8cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
@@ -31,11 +31,13 @@
 import android.provider.Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS
 import android.provider.Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS
 import android.util.Log
+import android.view.ContextThemeWrapper
 import android.view.View
 import android.view.ViewGroup
 import com.android.settingslib.Utils
 import com.android.systemui.R
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
@@ -46,6 +48,7 @@
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.settings.UserTracker
+import com.android.systemui.shared.regionsampling.RegionSamplingInstance
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
@@ -60,22 +63,23 @@
  */
 @SysUISingleton
 class LockscreenSmartspaceController @Inject constructor(
-    private val context: Context,
-    private val featureFlags: FeatureFlags,
-    private val smartspaceManager: SmartspaceManager,
-    private val activityStarter: ActivityStarter,
-    private val falsingManager: FalsingManager,
-    private val secureSettings: SecureSettings,
-    private val userTracker: UserTracker,
-    private val contentResolver: ContentResolver,
-    private val configurationController: ConfigurationController,
-    private val statusBarStateController: StatusBarStateController,
-    private val deviceProvisionedController: DeviceProvisionedController,
-    private val bypassController: KeyguardBypassController,
-    private val execution: Execution,
-    @Main private val uiExecutor: Executor,
-    @Main private val handler: Handler,
-    optionalPlugin: Optional<BcSmartspaceDataPlugin>
+        private val context: Context,
+        private val featureFlags: FeatureFlags,
+        private val smartspaceManager: SmartspaceManager,
+        private val activityStarter: ActivityStarter,
+        private val falsingManager: FalsingManager,
+        private val secureSettings: SecureSettings,
+        private val userTracker: UserTracker,
+        private val contentResolver: ContentResolver,
+        private val configurationController: ConfigurationController,
+        private val statusBarStateController: StatusBarStateController,
+        private val deviceProvisionedController: DeviceProvisionedController,
+        private val bypassController: KeyguardBypassController,
+        private val execution: Execution,
+        @Main private val uiExecutor: Executor,
+        @Background private val bgExecutor: Executor,
+        @Main private val handler: Handler,
+        optionalPlugin: Optional<BcSmartspaceDataPlugin>
 ) {
     companion object {
         private const val TAG = "LockscreenSmartspaceController"
@@ -86,15 +90,37 @@
 
     // Smartspace can be used on multiple displays, such as when the user casts their screen
     private var smartspaceViews = mutableSetOf<SmartspaceView>()
+    private var regionSamplingInstances =
+            mutableMapOf<SmartspaceView, RegionSamplingInstance>()
+
+    private val regionSamplingEnabled =
+            featureFlags.isEnabled(Flags.REGION_SAMPLING)
 
     private var showNotifications = false
     private var showSensitiveContentForCurrentUser = false
     private var showSensitiveContentForManagedUser = false
     private var managedUserHandle: UserHandle? = null
 
+    private val updateFun = object : RegionSamplingInstance.UpdateColorCallback {
+        override fun updateColors() {
+            updateTextColorFromRegionSampler()
+        }
+    }
+
+    // TODO: Move logic into SmartspaceView
     var stateChangeListener = object : View.OnAttachStateChangeListener {
         override fun onViewAttachedToWindow(v: View) {
             smartspaceViews.add(v as SmartspaceView)
+
+            var regionSamplingInstance = RegionSamplingInstance(
+                    v,
+                    uiExecutor,
+                    bgExecutor,
+                    regionSamplingEnabled,
+                    updateFun
+            )
+            regionSamplingInstance.startRegionSampler()
+            regionSamplingInstances.put(v, regionSamplingInstance)
             connectSession()
 
             updateTextColorFromWallpaper()
@@ -104,6 +130,10 @@
         override fun onViewDetachedFromWindow(v: View) {
             smartspaceViews.remove(v as SmartspaceView)
 
+            var regionSamplingInstance = regionSamplingInstances.getValue(v)
+            regionSamplingInstance.stopRegionSampler()
+            regionSamplingInstances.remove(v)
+
             if (smartspaceViews.isEmpty()) {
                 disconnect()
             }
@@ -332,9 +362,29 @@
         }
     }
 
+    private fun updateTextColorFromRegionSampler() {
+        smartspaceViews.forEach {
+            val isRegionDark = regionSamplingInstances.getValue(it).currentRegionDarkness()
+            val themeID = if (isRegionDark.isDark) {
+                R.style.Theme_SystemUI
+            } else {
+                R.style.Theme_SystemUI_LightWallpaper
+            }
+            val themedContext = ContextThemeWrapper(context, themeID)
+            val wallpaperTextColor =
+                    Utils.getColorAttrDefaultColor(themedContext, R.attr.wallpaperTextColor)
+            it.setPrimaryTextColor(wallpaperTextColor)
+        }
+    }
+
     private fun updateTextColorFromWallpaper() {
-        val wallpaperTextColor = Utils.getColorAttrDefaultColor(context, R.attr.wallpaperTextColor)
-        smartspaceViews.forEach { it.setPrimaryTextColor(wallpaperTextColor) }
+        if (!regionSamplingEnabled) {
+            val wallpaperTextColor =
+                    Utils.getColorAttrDefaultColor(context, R.attr.wallpaperTextColor)
+            smartspaceViews.forEach { it.setPrimaryTextColor(wallpaperTextColor) }
+        } else {
+            updateTextColorFromRegionSampler()
+        }
     }
 
     private fun reloadSmartspace() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt
index 5aeab84..d248961 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt
@@ -31,7 +31,6 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.collection.inflation.BindEventManager
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
@@ -129,11 +128,9 @@
  */
 @SysUISingleton
 class ConversationNotificationManager @Inject constructor(
-    private val bindEventManager: BindEventManager,
-    private val notificationGroupManager: NotificationGroupManagerLegacy,
+    bindEventManager: BindEventManager,
     private val context: Context,
     private val notifCollection: CommonNotifCollection,
-    private val featureFlags: NotifPipelineFlags,
     @Main private val mainHandler: Handler
 ) {
     // Need this state to be thread safe, since it's accessed from the ui thread
@@ -172,12 +169,10 @@
                                 layout.setIsImportantConversation(important, false)
                             }
                         }
-                if (changed && !featureFlags.isNewPipelineEnabled()) {
-                    notificationGroupManager.updateIsolation(entry)
-                }
             }
         }
     }
+
     fun onEntryViewBound(entry: NotificationEntry) {
         if (!entry.ranking.isConversation) {
             return
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index c86bf93..852d5f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -41,6 +41,7 @@
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.NotificationVisibility;
 import com.android.systemui.Dumpable;
+import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.statusbar.NotificationLifetimeExtender;
 import com.android.systemui.statusbar.NotificationListener;
@@ -73,6 +74,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.Executor;
 
 import dagger.Lazy;
 
@@ -113,6 +115,7 @@
     private final IStatusBarService mStatusBarService;
     private final NotifLiveDataStoreImpl mNotifLiveDataStore;
     private final DumpManager mDumpManager;
+    private final Executor mBgExecutor;
 
     private final Set<NotificationEntry> mAllNotifications = new ArraySet<>();
     private final Set<NotificationEntry> mReadOnlyAllNotifications =
@@ -159,7 +162,8 @@
             LeakDetector leakDetector,
             IStatusBarService statusBarService,
             NotifLiveDataStoreImpl notifLiveDataStore,
-            DumpManager dumpManager
+            DumpManager dumpManager,
+            @Background Executor bgExecutor
     ) {
         mLogger = logger;
         mGroupManager = groupManager;
@@ -170,6 +174,7 @@
         mStatusBarService = statusBarService;
         mNotifLiveDataStore = notifLiveDataStore;
         mDumpManager = dumpManager;
+        mBgExecutor = bgExecutor;
     }
 
     /** Once called, the NEM will start processing notification events from system server. */
@@ -566,17 +571,19 @@
     private void sendNotificationRemovalToServer(
             StatusBarNotification notification,
             DismissedByUserStats dismissedByUserStats) {
-        try {
-            mStatusBarService.onNotificationClear(
-                    notification.getPackageName(),
-                    notification.getUser().getIdentifier(),
-                    notification.getKey(),
-                    dismissedByUserStats.dismissalSurface,
-                    dismissedByUserStats.dismissalSentiment,
-                    dismissedByUserStats.notificationVisibility);
-        } catch (RemoteException ex) {
-            // system process is dead if we're here.
-        }
+        mBgExecutor.execute(() -> {
+            try {
+                mStatusBarService.onNotificationClear(
+                        notification.getPackageName(),
+                        notification.getUser().getIdentifier(),
+                        notification.getKey(),
+                        dismissedByUserStats.dismissalSurface,
+                        dismissedByUserStats.dismissalSentiment,
+                        dismissedByUserStats.notificationVisibility);
+            } catch (RemoteException ex) {
+                // system process is dead if we're here.
+            }
+        });
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
index b764c27..31b21c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
@@ -4,10 +4,10 @@
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.animation.LaunchAnimator
+import com.android.systemui.shade.NotificationShadeWindowViewController
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
-import com.android.systemui.statusbar.phone.NotificationShadeWindowViewController
 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
 import com.android.systemui.statusbar.policy.HeadsUpUtil
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
index 1fdf18f..68bf69a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
@@ -70,6 +70,7 @@
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.Dumpable;
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.dump.LogBufferEulogizer;
@@ -112,6 +113,7 @@
 import java.util.Objects;
 import java.util.Queue;
 import java.util.Set;
+import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
 
 import javax.inject.Inject;
@@ -146,6 +148,7 @@
     private final NotifPipelineFlags mNotifPipelineFlags;
     private final NotifCollectionLogger mLogger;
     private final Handler mMainHandler;
+    private final Executor mBgExecutor;
     private final LogBufferEulogizer mEulogizer;
     private final DumpManager mDumpManager;
 
@@ -174,6 +177,7 @@
             NotifPipelineFlags notifPipelineFlags,
             NotifCollectionLogger logger,
             @Main Handler mainHandler,
+            @Background Executor bgExecutor,
             LogBufferEulogizer logBufferEulogizer,
             DumpManager dumpManager) {
         mStatusBarService = statusBarService;
@@ -181,6 +185,7 @@
         mNotifPipelineFlags = notifPipelineFlags;
         mLogger = logger;
         mMainHandler = mainHandler;
+        mBgExecutor = bgExecutor;
         mEulogizer = logBufferEulogizer;
         mDumpManager = dumpManager;
     }
@@ -294,18 +299,20 @@
             entriesToLocallyDismiss.add(entry);
             if (!isCanceled(entry)) {
                 // send message to system server if this notification hasn't already been cancelled
-                try {
-                    mStatusBarService.onNotificationClear(
-                            entry.getSbn().getPackageName(),
-                            entry.getSbn().getUser().getIdentifier(),
-                            entry.getSbn().getKey(),
-                            stats.dismissalSurface,
-                            stats.dismissalSentiment,
-                            stats.notificationVisibility);
-                } catch (RemoteException e) {
-                    // system process is dead if we're here.
-                    mLogger.logRemoteExceptionOnNotificationClear(entry, e);
-                }
+                mBgExecutor.execute(() -> {
+                    try {
+                        mStatusBarService.onNotificationClear(
+                                entry.getSbn().getPackageName(),
+                                entry.getSbn().getUser().getIdentifier(),
+                                entry.getSbn().getKey(),
+                                stats.dismissalSurface,
+                                stats.dismissalSentiment,
+                                stats.notificationVisibility);
+                    } catch (RemoteException e) {
+                        // system process is dead if we're here.
+                        mLogger.logRemoteExceptionOnNotificationClear(entry, e);
+                    }
+                });
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java
index 6a3799b..d1aa01b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java
@@ -75,8 +75,8 @@
     }
 
     @Override
-    public void abortInflation(NotificationEntry entry) {
-        entry.abortTask();
+    public boolean abortInflation(NotificationEntry entry) {
+        return entry.abortTask();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt
index a57440c..f662a04 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt
@@ -16,7 +16,6 @@
 package com.android.systemui.statusbar.notification.collection
 
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.statusbar.notification.NotifPipelineFlags
 import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderEntryListener
 import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderGroupListener
 import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderListListener
@@ -250,4 +249,4 @@
     fun getInternalNotifUpdater(name: String?): InternalNotifUpdater {
         return mNotifCollection.getInternalNotifUpdater(name)
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index 0a16fb6..b6392f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -476,11 +476,13 @@
     /**
      * Abort all existing inflation tasks
      */
-    public void abortTask() {
+    public boolean abortTask() {
         if (mRunningTask != null) {
             mRunningTask.abort();
             mRunningTask = null;
+            return true;
         }
+        return false;
     }
 
     public void setInflationTask(InflationTask abortableTask) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
index 8a18d31..420f21d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
@@ -314,60 +314,62 @@
                 }
             };
 
-    private void onPreRenderInvalidated(Invalidator invalidator) {
+    private void onPreRenderInvalidated(Invalidator invalidator, @Nullable String reason) {
         Assert.isMainThread();
 
-        mLogger.logPreRenderInvalidated(invalidator.getName(), mPipelineState.getState());
+        mLogger.logPreRenderInvalidated(invalidator, mPipelineState.getState(), reason);
 
         rebuildListIfBefore(STATE_FINALIZING);
     }
 
-    private void onPreGroupFilterInvalidated(NotifFilter filter) {
+    private void onPreGroupFilterInvalidated(NotifFilter filter, @Nullable String reason) {
         Assert.isMainThread();
 
-        mLogger.logPreGroupFilterInvalidated(filter.getName(), mPipelineState.getState());
+        mLogger.logPreGroupFilterInvalidated(filter, mPipelineState.getState(), reason);
 
         rebuildListIfBefore(STATE_PRE_GROUP_FILTERING);
     }
 
-    private void onReorderingAllowedInvalidated(NotifStabilityManager stabilityManager) {
+    private void onReorderingAllowedInvalidated(NotifStabilityManager stabilityManager,
+            @Nullable String reason) {
         Assert.isMainThread();
 
         mLogger.logReorderingAllowedInvalidated(
-                stabilityManager.getName(),
-                mPipelineState.getState());
+                stabilityManager,
+                mPipelineState.getState(),
+                reason);
 
         rebuildListIfBefore(STATE_GROUPING);
     }
 
-    private void onPromoterInvalidated(NotifPromoter promoter) {
+    private void onPromoterInvalidated(NotifPromoter promoter, @Nullable String reason) {
         Assert.isMainThread();
 
-        mLogger.logPromoterInvalidated(promoter.getName(), mPipelineState.getState());
+        mLogger.logPromoterInvalidated(promoter, mPipelineState.getState(), reason);
 
         rebuildListIfBefore(STATE_TRANSFORMING);
     }
 
-    private void onNotifSectionInvalidated(NotifSectioner section) {
+    private void onNotifSectionInvalidated(NotifSectioner section, @Nullable String reason) {
         Assert.isMainThread();
 
-        mLogger.logNotifSectionInvalidated(section.getName(), mPipelineState.getState());
+        mLogger.logNotifSectionInvalidated(section, mPipelineState.getState(), reason);
 
         rebuildListIfBefore(STATE_SORTING);
     }
 
-    private void onFinalizeFilterInvalidated(NotifFilter filter) {
+    private void onFinalizeFilterInvalidated(NotifFilter filter, @Nullable String reason) {
         Assert.isMainThread();
 
-        mLogger.logFinalizeFilterInvalidated(filter.getName(), mPipelineState.getState());
+        mLogger.logFinalizeFilterInvalidated(filter, mPipelineState.getState(), reason);
 
         rebuildListIfBefore(STATE_FINALIZE_FILTERING);
     }
 
-    private void onNotifComparatorInvalidated(NotifComparator comparator) {
+    private void onNotifComparatorInvalidated(NotifComparator comparator, @Nullable String reason) {
         Assert.isMainThread();
 
-        mLogger.logNotifComparatorInvalidated(comparator.getName(), mPipelineState.getState());
+        mLogger.logNotifComparatorInvalidated(comparator, mPipelineState.getState(), reason);
 
         rebuildListIfBefore(STATE_SORTING);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java
index 7293953..3627b40 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java
@@ -142,7 +142,7 @@
 
         @Override
         public void invalidateNotifications(String reason) {
-            mNotifFilter.invalidateList();
+            mNotifFilter.invalidateList(reason);
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DebugModeCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DebugModeCoordinator.kt
index df54ccd..2405405 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DebugModeCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DebugModeCoordinator.kt
@@ -30,12 +30,12 @@
 ) : Coordinator {
 
     override fun attach(pipeline: NotifPipeline) {
-        pipeline.addPreGroupFilter(preGroupFilter)
-        debugModeFilterProvider.registerInvalidationListener(preGroupFilter::invalidateList)
+        pipeline.addPreGroupFilter(filter)
+        debugModeFilterProvider.registerInvalidationListener { filter.invalidateList(null) }
     }
 
-    private val preGroupFilter = object : NotifFilter("DebugModeCoordinator") {
+    private val filter = object : NotifFilter("DebugModeFilter") {
         override fun shouldFilterOut(entry: NotificationEntry, now: Long) =
             debugModeFilterProvider.shouldFilterOut(entry)
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinator.java
index e865249..058042c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinator.java
@@ -90,7 +90,7 @@
             new DeviceProvisionedController.DeviceProvisionedListener() {
                 @Override
                 public void onDeviceProvisionedChanged() {
-                    mNotifFilter.invalidateList();
+                    mNotifFilter.invalidateList("onDeviceProvisionedChanged");
                 }
             };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
index a61db41..8278b54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
@@ -35,6 +35,7 @@
 import com.android.systemui.statusbar.notification.dagger.IncomingHeader
 import com.android.systemui.statusbar.notification.interruption.HeadsUpViewBinder
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider
+import com.android.systemui.statusbar.notification.logKey
 import com.android.systemui.statusbar.notification.stack.BUCKET_HEADS_UP
 import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
@@ -278,8 +279,8 @@
         .firstOrNull()
         ?.let { posted ->
             posted.entry.takeIf { entry ->
-                locationLookupByKey(entry.key) == GroupLocation.Isolated
-                        && entry.sbn.notification.groupAlertBehavior == GROUP_ALERT_SUMMARY
+                locationLookupByKey(entry.key) == GroupLocation.Isolated &&
+                        entry.sbn.notification.groupAlertBehavior == GROUP_ALERT_SUMMARY
             }
         }
 
@@ -512,7 +513,7 @@
     private val mOnHeadsUpChangedListener = object : OnHeadsUpChangedListener {
         override fun onHeadsUpStateChanged(entry: NotificationEntry, isHeadsUp: Boolean) {
             if (!isHeadsUp) {
-                mNotifPromoter.invalidateList()
+                mNotifPromoter.invalidateList("headsUpEnded: ${entry.logKey}")
                 mHeadsUpViewBinder.unbindHeadsUpView(entry)
                 endNotifLifetimeExtensionIfExtended(entry)
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinator.java
index 7b5cf85..e4e2bc1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinator.java
@@ -41,14 +41,11 @@
 @CoordinatorScope
 public class HideNotifsForOtherUsersCoordinator implements Coordinator {
     private final NotificationLockscreenUserManager mLockscreenUserManager;
-    private final SharedCoordinatorLogger mLogger;
 
     @Inject
     public HideNotifsForOtherUsersCoordinator(
-            NotificationLockscreenUserManager lockscreenUserManager,
-            SharedCoordinatorLogger logger) {
+            NotificationLockscreenUserManager lockscreenUserManager) {
         mLockscreenUserManager = lockscreenUserManager;
-        mLogger = logger;
     }
 
     @Override
@@ -70,23 +67,19 @@
         // changes
         @Override
         public void onCurrentProfilesChanged(SparseArray<UserInfo> currentProfiles) {
-            mLogger.logUserOrProfileChanged(
-                    mLockscreenUserManager.getCurrentUserId(),
-                    profileIdsToStr(currentProfiles));
-            mFilter.invalidateList();
+            StringBuilder sb = new StringBuilder("onCurrentProfilesChanged:");
+            sb.append(" user=").append(mLockscreenUserManager.getCurrentUserId());
+            sb.append(" profiles=");
+            sb.append("{");
+            for (int i = 0; i < currentProfiles.size(); i++) {
+                if (i != 0) {
+                    sb.append(",");
+                }
+                sb.append(currentProfiles.keyAt(i));
+            }
+            sb.append("}");
+            mFilter.invalidateList(sb.toString());
         }
     };
 
-    private String profileIdsToStr(SparseArray<UserInfo> currentProfiles) {
-        StringBuilder sb = new StringBuilder();
-        sb.append("{");
-        for (int i = 0; i < currentProfiles.size(); i++) {
-            sb.append(currentProfiles.keyAt(i));
-            if (i < currentProfiles.size() - 1) {
-                sb.append(",");
-            }
-        }
-        sb.append("}");
-        return sb.toString();
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
index ef63be0..e3d71c8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
@@ -38,18 +38,15 @@
     private static final String TAG = "KeyguardCoordinator";
     private final KeyguardNotificationVisibilityProvider mKeyguardNotificationVisibilityProvider;
     private final SectionHeaderVisibilityProvider mSectionHeaderVisibilityProvider;
-    private final SharedCoordinatorLogger mLogger;
     private final StatusBarStateController mStatusBarStateController;
 
     @Inject
     public KeyguardCoordinator(
             KeyguardNotificationVisibilityProvider keyguardNotificationVisibilityProvider,
             SectionHeaderVisibilityProvider sectionHeaderVisibilityProvider,
-            SharedCoordinatorLogger logger,
             StatusBarStateController statusBarStateController) {
         mKeyguardNotificationVisibilityProvider = keyguardNotificationVisibilityProvider;
         mSectionHeaderVisibilityProvider = sectionHeaderVisibilityProvider;
-        mLogger = logger;
         mStatusBarStateController = statusBarStateController;
     }
 
@@ -78,9 +75,8 @@
     }
 
     private void invalidateListFromFilter(String reason) {
-        mLogger.logKeyguardCoordinatorInvalidated(reason);
         updateSectionHeadersVisibility();
-        mNotifFilter.invalidateList();
+        mNotifFilter.invalidateList(reason);
     }
 
     private void updateSectionHeadersVisibility() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
index 023c4ef..ef1e57b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.notification.collection.coordinator;
 
+import static com.android.systemui.statusbar.notification.NotificationUtils.logKey;
 import static com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer.NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED;
 
 import static java.util.Objects.requireNonNull;
@@ -147,7 +148,8 @@
     @Override
     public void attach(NotifPipeline pipeline) {
         mNotifErrorManager.addInflationErrorListener(mInflationErrorListener);
-        mAdjustmentProvider.addDirtyListener(mNotifInflatingFilter::invalidateList);
+        mAdjustmentProvider.addDirtyListener(
+                () -> mNotifInflatingFilter.invalidateList("adjustmentProviderChanged"));
 
         pipeline.addCollectionListener(mNotifCollectionListener);
         // Inflate after grouping/sorting since that affects what views to inflate.
@@ -245,12 +247,13 @@
             } catch (RemoteException ex) {
                 // System server is dead, nothing to do about that
             }
-            mNotifInflationErrorFilter.invalidateList();
+            mNotifInflationErrorFilter.invalidateList("onNotifInflationError for " + logKey(entry));
         }
 
         @Override
         public void onNotifInflationErrorCleared(NotificationEntry entry) {
-            mNotifInflationErrorFilter.invalidateList();
+            mNotifInflationErrorFilter.invalidateList(
+                    "onNotifInflationErrorCleared for " + logKey(entry));
         }
     };
 
@@ -360,9 +363,11 @@
     }
 
     private void abortInflation(NotificationEntry entry, String reason) {
-        mLogger.logInflationAborted(entry, reason);
-        mNotifInflater.abortInflation(entry);
-        mInflatingNotifs.remove(entry);
+        final boolean taskAborted = mNotifInflater.abortInflation(entry);
+        final boolean wasInflating = mInflatingNotifs.remove(entry);
+        if (taskAborted || wasInflating) {
+            mLogger.logInflationAborted(entry, reason);
+        }
     }
 
     private void onInflationFinished(NotificationEntry entry, NotifViewController controller) {
@@ -371,7 +376,7 @@
         mViewBarn.registerViewForEntry(entry, controller);
         mInflationStates.put(entry, STATE_INFLATED);
         mBindEventManager.notifyViewBound(entry);
-        mNotifInflatingFilter.invalidateList();
+        mNotifInflatingFilter.invalidateList("onInflationFinished for " + logKey(entry));
     }
 
     private void freeNotifViews(NotificationEntry entry) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java
index 5ac4813..67a8a63 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java
@@ -199,7 +199,7 @@
             new StatusBarStateController.StateListener() {
                 @Override
                 public void onDozingChanged(boolean isDozing) {
-                    mDndVisualEffectsFilter.invalidateList();
+                    mDndVisualEffectsFilter.invalidateList("onDozingChanged to " + isDozing);
                 }
             };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
index 3f8a39f..aeeeb4f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
@@ -64,7 +64,7 @@
         pipeline.addPreRenderInvalidator(this)
     }
 
-    override fun onDynamicPrivacyChanged(): Unit = invalidateList()
+    override fun onDynamicPrivacyChanged(): Unit = invalidateList("onDynamicPrivacyChanged")
 
     override fun onBeforeRenderList(entries: List<ListEntry>) {
         if (keyguardStateController.isKeyguardGoingAway() ||
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SharedCoordinatorLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SharedCoordinatorLogger.kt
deleted file mode 100644
index 25bc641..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SharedCoordinatorLogger.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification.collection.coordinator
-
-import com.android.systemui.log.LogBuffer
-import com.android.systemui.log.LogLevel
-import com.android.systemui.log.dagger.NotificationLog
-import javax.inject.Inject
-
-/**
- * Shared logging class for coordinators that don't log enough to merit their own logger.
- */
-class SharedCoordinatorLogger @Inject constructor(
-    @NotificationLog private val buffer: LogBuffer
-) {
-    fun logUserOrProfileChanged(userId: Int, profiles: String) {
-        buffer.log("NotCurrentUserFilter", LogLevel.INFO, {
-            int1 = userId
-            str1 = profiles
-        }, {
-            "Current user or profiles changed. Current user is $int1; profiles are $str1"
-        })
-    }
-
-    fun logKeyguardCoordinatorInvalidated(reason: String) {
-        buffer.log("KeyguardCoordinator", LogLevel.DEBUG, {
-            str1 = reason
-        }, {
-            "KeyguardCoordinator invalidated: $str1"
-        })
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinator.kt
index ce361ea..9d0f974 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinator.kt
@@ -30,6 +30,7 @@
 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
+import com.android.systemui.statusbar.notification.logKey
 import com.android.systemui.util.concurrency.DelayableExecutor
 import com.android.systemui.util.time.SystemClock
 import java.util.concurrent.TimeUnit.SECONDS
@@ -130,7 +131,7 @@
         }
 
         if (changed) {
-            filter.invalidateList()
+            filter.invalidateList("onNewSmartspaceTargets")
             notificationEntryManager.updateNotifications("Smartspace targets changed")
         }
 
@@ -167,7 +168,7 @@
             target.cancelTimeoutRunnable = executor.executeDelayed({
                 target.cancelTimeoutRunnable = null
                 target.shouldFilter = true
-                filter.invalidateList()
+                filter.invalidateList("updateAlertException: ${entry.logKey}")
                 notificationEntryManager.updateNotifications("deduping timeout expired")
             }, alertExceptionExpires - now)
         }
@@ -184,7 +185,7 @@
         isOnLockscreen = newState == StatusBarState.KEYGUARD
 
         if (isOnLockscreen != wasOnLockscreen) {
-            filter.invalidateList()
+            filter.invalidateList("recordStatusBarState: " + StatusBarState.toString(newState))
             // No need to call notificationEntryManager.updateNotifications; something else already
             // does it for us when the keyguard state changes
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt
index 5a281b1..657c394d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt
@@ -145,4 +145,4 @@
         private const val TAG = "ViewConfigCoordinator"
         private val DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG)
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
index b9d23b4..d3bc257 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
@@ -28,13 +28,13 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shade.NotifPanelEvents;
 import com.android.systemui.statusbar.notification.collection.GroupEntry;
 import com.android.systemui.statusbar.notification.collection.ListEntry;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager;
 import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
-import com.android.systemui.statusbar.phone.NotifPanelEvents;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.util.Compile;
 import com.android.systemui.util.concurrency.DelayableExecutor;
@@ -192,11 +192,16 @@
                     + "  reorderingAllowed " + wasReorderingAllowed + "->" + mReorderingAllowed
                     + "  when setting " + field + "=" + value);
         }
-        if ((mPipelineRunAllowed && mIsSuppressingPipelineRun)
-                || (mReorderingAllowed && (mIsSuppressingGroupChange
-                        || isSuppressingSectionChange()
-                        || mIsSuppressingEntryReorder))) {
-            mNotifStabilityManager.invalidateList();
+        if (mPipelineRunAllowed && mIsSuppressingPipelineRun) {
+            mNotifStabilityManager.invalidateList("pipeline run suppression ended");
+        } else if (mReorderingAllowed && (mIsSuppressingGroupChange
+                || isSuppressingSectionChange()
+                || mIsSuppressingEntryReorder)) {
+            String reason = "reorder suppression ended for"
+                    + " group=" + mIsSuppressingGroupChange
+                    + " section=" + isSuppressingSectionChange()
+                    + " sort=" + mIsSuppressingEntryReorder;
+            mNotifStabilityManager.invalidateList(reason);
         }
         mVisualStabilityProvider.setReorderingAllowed(mReorderingAllowed);
     }
@@ -241,7 +246,7 @@
                         now + ALLOW_SECTION_CHANGE_TIMEOUT));
 
         if (!wasSectionChangeAllowed) {
-            mNotifStabilityManager.invalidateList();
+            mNotifStabilityManager.invalidateList("temporarilyAllowSectionChanges");
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt
index 567ec85..08e21e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt
@@ -42,9 +42,9 @@
 
     /**
      * Request to stop the inflation of an entry.  For example, called when a notification is
-     * removed and no longer needs to be inflated.
+     * removed and no longer needs to be inflated.  Returns whether anything may have been aborted.
      */
-    fun abortInflation(entry: NotificationEntry)
+    fun abortInflation(entry: NotificationEntry): Boolean
 
     /**
      * Called to let the system remove the content views from the notification row.
@@ -62,4 +62,4 @@
      * A class holding parameters used when inflating the notification row
      */
     class Params(val isLowPriority: Boolean, val reason: String)
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java
index 7dd3672..a7719d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java
@@ -23,6 +23,7 @@
 
 import androidx.annotation.NonNull;
 
+import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.notification.collection.NotifCollection;
 import com.android.systemui.statusbar.notification.collection.NotifCollection.CancellationReason;
@@ -33,10 +34,13 @@
 import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 
+import javax.inject.Inject;
+
 /**
  * Callback for when a user interacts with a {@see ExpandableNotificationRow}. Sends relevant
  * information about the interaction to the notification pipeline.
  */
+@SysUISingleton
 public class OnUserInteractionCallbackImpl implements OnUserInteractionCallback {
     private final NotificationVisibilityProvider mVisibilityProvider;
     private final NotifCollection mNotifCollection;
@@ -44,6 +48,7 @@
     private final StatusBarStateController mStatusBarStateController;
     private final VisualStabilityCoordinator mVisualStabilityCoordinator;
 
+    @Inject
     public OnUserInteractionCallbackImpl(
             NotificationVisibilityProvider visibilityProvider,
             NotifCollection notifCollection,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationPresenterExtensions.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationPresenterExtensions.java
deleted file mode 100644
index bdbb0eb..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationPresenterExtensions.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification.collection.legacy;
-
-import static com.android.systemui.statusbar.phone.CentralSurfaces.SPEW;
-
-import android.service.notification.StatusBarNotification;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.statusbar.notification.NotificationEntryListener;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
-
-import org.jetbrains.annotations.NotNull;
-
-import javax.inject.Inject;
-
-/**
- * This is some logic extracted from the
- * {@link com.android.systemui.statusbar.phone.StatusBarNotificationPresenter}
- * into a class that implements a new-pipeline interface so that the new pipeline can implement it
- * correctly.
- *
- * Specifically, this is the logic which updates notifications when uiMode and screen properties
- * change, and which closes the shade when the last notification disappears.
- */
-public class LegacyNotificationPresenterExtensions implements NotifShadeEventSource {
-    private static final String TAG = "LegacyNotifPresenter";
-    private final NotificationEntryManager mEntryManager;
-    private boolean mEntryListenerAdded;
-    private Runnable mShadeEmptiedCallback;
-    private Runnable mNotifRemovedByUserCallback;
-
-    @Inject
-    public LegacyNotificationPresenterExtensions(NotificationEntryManager entryManager) {
-        mEntryManager = entryManager;
-    }
-
-    private void ensureEntryListenerAdded() {
-        if (mEntryListenerAdded) return;
-        mEntryListenerAdded = true;
-        mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
-            @Override
-            public void onEntryRemoved(
-                    @NotNull NotificationEntry entry,
-                    NotificationVisibility visibility,
-                    boolean removedByUser,
-                    int reason) {
-                StatusBarNotification old = entry.getSbn();
-                if (SPEW) {
-                    Log.d(TAG, "removeNotification key=" + entry.getKey()
-                            + " old=" + old + " reason=" + reason);
-                }
-
-                if (old != null && !mEntryManager.hasActiveNotifications()) {
-                    if (mShadeEmptiedCallback != null) mShadeEmptiedCallback.run();
-                }
-                if (removedByUser) {
-                    if (mNotifRemovedByUserCallback != null) mNotifRemovedByUserCallback.run();
-                }
-            }
-        });
-    }
-
-    @Override
-    public void setNotifRemovedByUserCallback(@NonNull Runnable callback) {
-        if (mNotifRemovedByUserCallback != null) {
-            throw new IllegalStateException("mNotifRemovedByUserCallback already set");
-        }
-        mNotifRemovedByUserCallback = callback;
-        ensureEntryListenerAdded();
-    }
-
-    @Override
-    public void setShadeEmptiedCallback(@NonNull Runnable callback) {
-        if (mShadeEmptiedCallback != null) {
-            throw new IllegalStateException("mShadeEmptiedCallback already set");
-        }
-        mShadeEmptiedCallback = callback;
-        ensureEntryListenerAdded();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java
deleted file mode 100644
index 103b14b..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification.collection.legacy;
-
-import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
-
-import android.service.notification.NotificationListenerService;
-import android.service.notification.NotificationStats;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.collection.NotifCollection.CancellationReason;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
-import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
-import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
-import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
-
-/**
- * Callback for when a user interacts with a {@see ExpandableNotificationRow}.
- */
-public class OnUserInteractionCallbackImplLegacy implements OnUserInteractionCallback {
-    private final NotificationEntryManager mNotificationEntryManager;
-    private final NotificationVisibilityProvider mVisibilityProvider;
-    private final HeadsUpManager mHeadsUpManager;
-    private final StatusBarStateController mStatusBarStateController;
-    private final VisualStabilityManager mVisualStabilityManager;
-    private final GroupMembershipManager mGroupMembershipManager;
-
-    public OnUserInteractionCallbackImplLegacy(
-            NotificationEntryManager notificationEntryManager,
-            NotificationVisibilityProvider visibilityProvider,
-            HeadsUpManager headsUpManager,
-            StatusBarStateController statusBarStateController,
-            VisualStabilityManager visualStabilityManager,
-            GroupMembershipManager groupMembershipManager
-    ) {
-        mNotificationEntryManager = notificationEntryManager;
-        mVisibilityProvider = visibilityProvider;
-        mHeadsUpManager = headsUpManager;
-        mStatusBarStateController = statusBarStateController;
-        mVisualStabilityManager = visualStabilityManager;
-        mGroupMembershipManager = groupMembershipManager;
-    }
-
-    /**
-     * Callback triggered when a user:
-     * 1. Manually dismisses a notification {@see ExpandableNotificationRow}.
-     * 2. Clicks on a notification with flag {@link android.app.Notification#FLAG_AUTO_CANCEL}.
-     * {@see StatusBarNotificationActivityStarter}
-     *
-     * @param groupSummaryToDismiss the group summary that should be dismissed
-     *                              along with this dismissal. If null, does not additionally
-     *                              dismiss any notifications.
-     */
-    private void onDismiss(
-            NotificationEntry entry,
-            @NotificationListenerService.NotificationCancelReason int cancellationReason,
-            @Nullable NotificationEntry groupSummaryToDismiss
-    ) {
-        int dismissalSurface = NotificationStats.DISMISSAL_SHADE;
-        if (mHeadsUpManager.isAlerting(entry.getKey())) {
-            dismissalSurface = NotificationStats.DISMISSAL_PEEK;
-        } else if (mStatusBarStateController.isDozing()) {
-            dismissalSurface = NotificationStats.DISMISSAL_AOD;
-        }
-
-        if (groupSummaryToDismiss != null) {
-            onDismiss(groupSummaryToDismiss, cancellationReason, null);
-        }
-
-        mNotificationEntryManager.performRemoveNotification(
-                entry.getSbn(),
-                new DismissedByUserStats(
-                        dismissalSurface,
-                        DISMISS_SENTIMENT_NEUTRAL,
-                        mVisibilityProvider.obtain(entry, true)),
-                cancellationReason
-        );
-
-    }
-
-    @Override
-    public void onImportanceChanged(NotificationEntry entry) {
-        mVisualStabilityManager.temporarilyAllowReordering();
-    }
-
-    /**
-     * @param entry that is being dismissed
-     * @return the group summary to dismiss along with this entry if this is the last entry in
-     * the group. Else, returns null.
-     */
-    @Nullable
-    private NotificationEntry getGroupSummaryToDismiss(NotificationEntry entry) {
-        if (mGroupMembershipManager.isOnlyChildInGroup(entry)) {
-            NotificationEntry groupSummary = mGroupMembershipManager.getLogicalGroupSummary(entry);
-            return groupSummary.isDismissable() ? groupSummary : null;
-        }
-        return null;
-    }
-
-    @Override
-    @NonNull
-    public Runnable registerFutureDismissal(@NonNull NotificationEntry entry,
-            @CancellationReason int cancellationReason) {
-        NotificationEntry groupSummaryToDismiss = getGroupSummaryToDismiss(entry);
-        return () -> onDismiss(entry, cancellationReason, groupSummaryToDismiss);
-    }
-}
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
index 10a627d..4c406e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
@@ -25,8 +25,15 @@
 import com.android.systemui.statusbar.notification.collection.GroupEntry
 import com.android.systemui.statusbar.notification.collection.ListEntry
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.StateName
+import com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.getStateName
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Invalidator
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable
 import com.android.systemui.statusbar.notification.logKey
 import com.android.systemui.util.Compile
 import javax.inject.Inject
@@ -60,68 +67,63 @@
         })
     }
 
-    fun logPreRenderInvalidated(filterName: String, pipelineState: Int) {
+    private fun logPluggableInvalidated(
+        type: String,
+        pluggable: Pluggable<*>,
+        @StateName pipelineState: Int,
+        reason: String?
+    ) {
         buffer.log(TAG, DEBUG, {
-            str1 = filterName
+            str1 = type
+            str2 = pluggable.name
             int1 = pipelineState
+            str3 = reason
         }, {
-            """Pre-render Invalidator "$str1" invalidated; pipeline state is $int1"""
+            """Invalidated while ${getStateName(int1)} by $str1 "$str2" because $str3"""
         })
     }
 
-    fun logPreGroupFilterInvalidated(filterName: String, pipelineState: Int) {
-        buffer.log(TAG, DEBUG, {
-            str1 = filterName
-            int1 = pipelineState
-        }, {
-            """Pre-group NotifFilter "$str1" invalidated; pipeline state is $int1"""
-        })
-    }
+    fun logPreRenderInvalidated(
+        invalidator: Invalidator,
+        @StateName pipelineState: Int,
+        reason: String?
+    ) = logPluggableInvalidated("Pre-render Invalidator", invalidator, pipelineState, reason)
 
-    fun logReorderingAllowedInvalidated(name: String, pipelineState: Int) {
-        buffer.log(TAG, DEBUG, {
-            str1 = name
-            int1 = pipelineState
-        }, {
-            """ReorderingNowAllowed "$str1" invalidated; pipeline state is $int1"""
-        })
-    }
+    fun logPreGroupFilterInvalidated(
+        filter: NotifFilter,
+        @StateName pipelineState: Int,
+        reason: String?
+    ) = logPluggableInvalidated("Pre-group NotifFilter", filter, pipelineState, reason)
 
-    fun logPromoterInvalidated(name: String, pipelineState: Int) {
-        buffer.log(TAG, DEBUG, {
-            str1 = name
-            int1 = pipelineState
-        }, {
-            """NotifPromoter "$str1" invalidated; pipeline state is $int1"""
-        })
-    }
+    fun logReorderingAllowedInvalidated(
+        stabilityManager: NotifStabilityManager,
+        @StateName pipelineState: Int,
+        reason: String?
+    ) = logPluggableInvalidated("ReorderingNowAllowed", stabilityManager, pipelineState, reason)
 
-    fun logNotifSectionInvalidated(name: String, pipelineState: Int) {
-        buffer.log(TAG, DEBUG, {
-            str1 = name
-            int1 = pipelineState
-        }, {
-            """NotifSection "$str1" invalidated; pipeline state is $int1"""
-        })
-    }
+    fun logPromoterInvalidated(
+        promoter: NotifPromoter,
+        @StateName pipelineState: Int,
+        reason: String?
+    ) = logPluggableInvalidated("NotifPromoter", promoter, pipelineState, reason)
 
-    fun logNotifComparatorInvalidated(name: String, pipelineState: Int) {
-        buffer.log(TAG, DEBUG, {
-            str1 = name
-            int1 = pipelineState
-        }, {
-            """NotifComparator "$str1" invalidated; pipeline state is $int1"""
-        })
-    }
+    fun logNotifSectionInvalidated(
+        sectioner: NotifSectioner,
+        @StateName pipelineState: Int,
+        reason: String?
+    ) = logPluggableInvalidated("NotifSection", sectioner, pipelineState, reason)
 
-    fun logFinalizeFilterInvalidated(name: String, pipelineState: Int) {
-        buffer.log(TAG, DEBUG, {
-            str1 = name
-            int1 = pipelineState
-        }, {
-            """Finalize NotifFilter "$str1" invalidated; pipeline state is $int1"""
-        })
-    }
+    fun logNotifComparatorInvalidated(
+        comparator: NotifComparator,
+        @StateName pipelineState: Int,
+        reason: String?
+    ) = logPluggableInvalidated("NotifComparator", comparator, pipelineState, reason)
+
+    fun logFinalizeFilterInvalidated(
+        filter: NotifFilter,
+        @StateName pipelineState: Int,
+        reason: String?
+    ) = logPluggableInvalidated("Finalize NotifFilter", filter, pipelineState, reason)
 
     fun logDuplicateSummary(
         buildId: Int,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/Pluggable.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/Pluggable.java
index b981a96..966ab4c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/Pluggable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/Pluggable.java
@@ -49,10 +49,10 @@
      * Call this method when something has caused this pluggable's behavior to change. The pipeline
      * will be re-run.
      */
-    public final void invalidateList() {
+    public final void invalidateList(@Nullable String reason) {
         if (mListener != null) {
             Trace.beginSection("Pluggable<" + mName + ">.invalidateList");
-            mListener.onPluggableInvalidated((This) this);
+            mListener.onPluggableInvalidated((This) this, reason);
             Trace.endSection();
         }
     }
@@ -74,7 +74,7 @@
      * @param <T> The type of pluggable that is being listened to.
      */
     public interface PluggableListener<T> {
-        /** Called whenever {@link #invalidateList()} is called on this pluggable. */
-        void onPluggableInvalidated(T pluggable);
+        /** Called whenever {@link #invalidateList(String)} is called on this pluggable. */
+        void onPluggableInvalidated(T pluggable, @Nullable String reason);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationVisibilityProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationVisibilityProviderImpl.kt
index 6a1e36f..ec10aaf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationVisibilityProviderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationVisibilityProviderImpl.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.notification.collection.provider
 
 import com.android.internal.statusbar.NotificationVisibility
+import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
@@ -25,6 +26,7 @@
 import javax.inject.Inject
 
 /** pipeline-agnostic implementation for getting [NotificationVisibility]. */
+@SysUISingleton
 class NotificationVisibilityProviderImpl @Inject constructor(
     private val notifDataStore: NotifLiveDataStore,
     private val notifCollection: CommonNotifCollection
@@ -46,4 +48,4 @@
         NotificationLogger.getNotificationLocation(notifCollection.getEntry(key))
 
     private fun getCount() = notifDataStore.activeNotifCount.value
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
index a2cb950..1b3f83d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.notification.collection.render;
 
+import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.statusbar.notification.collection.GroupEntry;
 import com.android.systemui.statusbar.notification.collection.ListEntry;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
@@ -28,10 +29,13 @@
 import java.util.HashSet;
 import java.util.Set;
 
+import javax.inject.Inject;
+
 /**
  * Provides grouping information for notification entries including information about a group's
  * expanded state.
  */
+@SysUISingleton
 public class GroupExpansionManagerImpl implements GroupExpansionManager, Coordinator {
     private final GroupMembershipManager mGroupMembershipManager;
     private final Set<OnGroupExpansionChangeListener> mOnGroupChangeListeners = new HashSet<>();
@@ -39,6 +43,7 @@
     // Set of summary keys whose groups are expanded
     private final Set<NotificationEntry> mExpandedGroups = new HashSet<>();
 
+    @Inject
     public GroupExpansionManagerImpl(GroupMembershipManager groupMembershipManager) {
         mGroupMembershipManager = groupMembershipManager;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index c9c7fe9..bf08fc7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -35,29 +35,26 @@
 import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.settings.UserContextProvider;
+import com.android.systemui.shade.NotifPanelEventsModule;
 import com.android.systemui.statusbar.NotificationListener;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.notification.AssistantFeedbackController;
 import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.NotificationEntryManagerLogger;
-import com.android.systemui.statusbar.notification.collection.NotifCollection;
 import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl;
 import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore;
 import com.android.systemui.statusbar.notification.collection.NotifLiveDataStoreImpl;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotifPipelineChoreographerModule;
 import com.android.systemui.statusbar.notification.collection.coordinator.ShadeEventCoordinator;
-import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator;
 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorsModule;
 import com.android.systemui.statusbar.notification.collection.inflation.BindEventManager;
 import com.android.systemui.statusbar.notification.collection.inflation.BindEventManagerImpl;
 import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater;
 import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
 import com.android.systemui.statusbar.notification.collection.inflation.OnUserInteractionCallbackImpl;
-import com.android.systemui.statusbar.notification.collection.legacy.LegacyNotificationPresenterExtensions;
 import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
-import com.android.systemui.statusbar.notification.collection.legacy.OnUserInteractionCallbackImplLegacy;
 import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
 import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
@@ -88,9 +85,7 @@
 import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.phone.NotifPanelEventsModule;
 import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.util.leak.LeakDetector;
 import com.android.systemui.wmshell.BubblesManager;
 
@@ -116,12 +111,10 @@
 })
 public interface NotificationsModule {
     @Binds
-    StackScrollAlgorithm.SectionProvider bindSectionProvider(
-            NotificationSectionsManager impl);
+    StackScrollAlgorithm.SectionProvider bindSectionProvider(NotificationSectionsManager impl);
 
     @Binds
-    StackScrollAlgorithm.BypassController bindBypassController(
-            KeyguardBypassController impl);
+    StackScrollAlgorithm.BypassController bindBypassController(KeyguardBypassController impl);
 
     /** Provides an instance of {@link NotificationEntryManager} */
     @SysUISingleton
@@ -135,7 +128,8 @@
             LeakDetector leakDetector,
             IStatusBarService statusBarService,
             NotifLiveDataStoreImpl notifLiveDataStore,
-            DumpManager dumpManager) {
+            DumpManager dumpManager,
+            @Background Executor bgExecutor) {
         return new NotificationEntryManager(
                 logger,
                 groupManager,
@@ -145,7 +139,8 @@
                 leakDetector,
                 statusBarService,
                 notifLiveDataStore,
-                dumpManager);
+                dumpManager,
+                bgExecutor);
     }
 
     /** Provides an instance of {@link NotificationGutsManager} */
@@ -194,12 +189,8 @@
     }
 
     /** Provides an instance of {@link NotifGutsViewManager} */
-    @SysUISingleton
-    @Provides
-    static NotifGutsViewManager provideNotifGutsViewManager(
-            NotificationGutsManager notificationGutsManager) {
-        return notificationGutsManager;
-    }
+    @Binds
+    NotifGutsViewManager bindNotifGutsViewManager(NotificationGutsManager notificationGutsManager);
 
     /** Provides an instance of {@link VisualStabilityManager} */
     @SysUISingleton
@@ -226,10 +217,8 @@
     static NotificationLogger provideNotificationLogger(
             NotificationListener notificationListener,
             @UiBackground Executor uiBgExecutor,
-            NotifPipelineFlags notifPipelineFlags,
             NotifLiveDataStore notifLiveDataStore,
             NotificationVisibilityProvider visibilityProvider,
-            NotificationEntryManager entryManager,
             NotifPipeline notifPipeline,
             StatusBarStateController statusBarStateController,
             NotificationLogger.ExpansionStateLogger expansionStateLogger,
@@ -237,10 +226,8 @@
         return new NotificationLogger(
                 notificationListener,
                 uiBgExecutor,
-                notifPipelineFlags,
                 notifLiveDataStore,
                 visibilityProvider,
-                entryManager,
                 notifPipeline,
                 statusBarStateController,
                 expansionStateLogger,
@@ -257,25 +244,13 @@
     /** Provides an instance of {@link GroupMembershipManager} */
     @SysUISingleton
     @Provides
-    static GroupMembershipManager provideGroupMembershipManager(
-            NotifPipelineFlags notifPipelineFlags,
-            Lazy<NotificationGroupManagerLegacy> groupManagerLegacy) {
-        return notifPipelineFlags.isNewPipelineEnabled()
-                ? new GroupMembershipManagerImpl()
-                : groupManagerLegacy.get();
+    static GroupMembershipManager provideGroupMembershipManager() {
+        return new GroupMembershipManagerImpl();
     }
 
     /** Provides an instance of {@link GroupExpansionManager} */
-    @SysUISingleton
-    @Provides
-    static GroupExpansionManager provideGroupExpansionManager(
-            NotifPipelineFlags notifPipelineFlags,
-            Lazy<GroupMembershipManager> groupMembershipManager,
-            Lazy<NotificationGroupManagerLegacy> groupManagerLegacy) {
-        return notifPipelineFlags.isNewPipelineEnabled()
-                ? new GroupExpansionManagerImpl(groupMembershipManager.get())
-                : groupManagerLegacy.get();
-    }
+    @Binds
+    GroupExpansionManager provideGroupExpansionManager(GroupExpansionManagerImpl impl);
 
     /** Initializes the notification data pipeline (can be disabled via config). */
     @SysUISingleton
@@ -294,69 +269,28 @@
     /**
      * Provide the active notification collection managing the notifications to render.
      */
-    @Provides
-    @SysUISingleton
-    static CommonNotifCollection provideCommonNotifCollection(
-            NotifPipelineFlags notifPipelineFlags,
-            Lazy<NotifPipeline> pipeline,
-            NotificationEntryManager entryManager) {
-        return notifPipelineFlags.isNewPipelineEnabled()
-                ? pipeline.get() : entryManager;
-    }
+    @Binds
+    CommonNotifCollection provideCommonNotifCollection(NotifPipeline pipeline);
 
     /**
      * Provide the object which can be used to obtain NotificationVisibility objects.
      */
     @Binds
-    @SysUISingleton
     NotificationVisibilityProvider provideNotificationVisibilityProvider(
-            NotificationVisibilityProviderImpl newProvider);
+            NotificationVisibilityProviderImpl impl);
 
     /**
      * Provide the active implementation for presenting notifications.
      */
-    @Provides
-    @SysUISingleton
-    static NotifShadeEventSource provideNotifShadeEventSource(
-            NotifPipelineFlags notifPipelineFlags,
-            Lazy<ShadeEventCoordinator> shadeEventCoordinatorLazy,
-            Lazy<LegacyNotificationPresenterExtensions> legacyNotificationPresenterExtensionsLazy) {
-        return notifPipelineFlags.isNewPipelineEnabled()
-                ? shadeEventCoordinatorLazy.get()
-                : legacyNotificationPresenterExtensionsLazy.get();
-    }
+    @Binds
+    NotifShadeEventSource provideNotifShadeEventSource(ShadeEventCoordinator shadeEventCoordinator);
 
     /**
      * Provide a dismissal callback that's triggered when a user manually dismissed a notification
      * from the notification shade or it gets auto-cancelled by click.
      */
-    @Provides
-    @SysUISingleton
-    static OnUserInteractionCallback provideOnUserInteractionCallback(
-            NotifPipelineFlags notifPipelineFlags,
-            HeadsUpManager headsUpManager,
-            StatusBarStateController statusBarStateController,
-            Lazy<NotifCollection> notifCollection,
-            Lazy<NotificationVisibilityProvider> visibilityProvider,
-            Lazy<VisualStabilityCoordinator> visualStabilityCoordinator,
-            NotificationEntryManager entryManager,
-            VisualStabilityManager visualStabilityManager,
-            Lazy<GroupMembershipManager> groupMembershipManagerLazy) {
-        return notifPipelineFlags.isNewPipelineEnabled()
-                ? new OnUserInteractionCallbackImpl(
-                        visibilityProvider.get(),
-                        notifCollection.get(),
-                        headsUpManager,
-                        statusBarStateController,
-                        visualStabilityCoordinator.get())
-                : new OnUserInteractionCallbackImplLegacy(
-                        entryManager,
-                        visibilityProvider.get(),
-                        headsUpManager,
-                        statusBarStateController,
-                        visualStabilityManager,
-                        groupMembershipManagerLazy.get());
-    }
+    @Binds
+    OnUserInteractionCallback provideOnUserInteractionCallback(OnUserInteractionCallbackImpl impl);
 
     /** */
     @Binds
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt
index 016b388..99d320d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt
@@ -19,6 +19,7 @@
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.LogLevel.DEBUG
 import com.android.systemui.log.LogLevel.INFO
+import com.android.systemui.log.LogLevel.WARNING
 import com.android.systemui.log.dagger.NotificationInterruptLog
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.logKey
@@ -211,6 +212,33 @@
         })
     }
 
+    fun logNoFullscreen(entry: NotificationEntry, reason: String) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
+            str2 = reason
+        }, {
+            "No FullScreenIntent: $str2: $str1"
+        })
+    }
+
+    fun logNoFullscreenWarning(entry: NotificationEntry, reason: String) {
+        buffer.log(TAG, WARNING, {
+            str1 = entry.logKey
+            str2 = reason
+        }, {
+            "No FullScreenIntent: WARNING: $str2: $str1"
+        })
+    }
+
+    fun logFullscreen(entry: NotificationEntry, reason: String) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
+            str2 = reason
+        }, {
+            "FullScreenIntent: $str2: $str1"
+        })
+    }
+
     fun keyguardHideNotification(entry: NotificationEntry) {
         buffer.log(TAG, DEBUG, {
             str1 = entry.logKey
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
index 8378b69..535dc6e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
@@ -177,9 +177,69 @@
      */
     @Override
     public boolean shouldLaunchFullScreenIntentWhenAdded(NotificationEntry entry) {
-        return entry.getSbn().getNotification().fullScreenIntent != null
-                && (!shouldHeadsUp(entry)
-                || mStatusBarStateController.getState() == StatusBarState.KEYGUARD);
+        if (entry.getSbn().getNotification().fullScreenIntent == null) {
+            return false;
+        }
+
+        // Never show FSI when suppressed by DND
+        if (entry.shouldSuppressFullScreenIntent()) {
+            mLogger.logNoFullscreen(entry, "Suppressed by DND");
+            return false;
+        }
+
+        // Never show FSI if importance is not HIGH
+        if (entry.getImportance() < NotificationManager.IMPORTANCE_HIGH) {
+            mLogger.logNoFullscreen(entry, "Not important enough");
+            return false;
+        }
+
+        // If the notification has suppressive GroupAlertBehavior, block FSI and warn.
+        StatusBarNotification sbn = entry.getSbn();
+        if (sbn.isGroup() && sbn.getNotification().suppressAlertingDueToGrouping()) {
+            // b/231322873: Detect and report an event when a notification has both an FSI and a
+            // suppressive groupAlertBehavior, and now correctly block the FSI from firing.
+            final int uid = entry.getSbn().getUid();
+            android.util.EventLog.writeEvent(0x534e4554, "231322873", uid, "groupAlertBehavior");
+            mLogger.logNoFullscreenWarning(entry, "GroupAlertBehavior will prevent HUN");
+            return false;
+        }
+
+        // If the screen is off, then launch the FullScreenIntent
+        if (!mPowerManager.isInteractive()) {
+            mLogger.logFullscreen(entry, "Device is not interactive");
+            return true;
+        }
+
+        // If the device is currently dreaming, then launch the FullScreenIntent
+        if (isDreaming()) {
+            mLogger.logFullscreen(entry, "Device is dreaming");
+            return true;
+        }
+
+        // If the keyguard is showing, then launch the FullScreenIntent
+        if (mStatusBarStateController.getState() == StatusBarState.KEYGUARD) {
+            mLogger.logFullscreen(entry, "Keyguard is showing");
+            return true;
+        }
+
+        // If the notification should HUN, then we don't need FSI
+        if (shouldHeadsUp(entry)) {
+            mLogger.logNoFullscreen(entry, "Expected to HUN");
+            return false;
+        }
+
+        // If the notification won't HUN for some other reason (DND/snooze/etc), launch FSI.
+        mLogger.logFullscreen(entry, "Expected not to HUN");
+        return true;
+    }
+
+    private boolean isDreaming() {
+        try {
+            return mDreamManager.isDreaming();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to query dream manager.", e);
+            return false;
+        }
     }
 
     private boolean shouldHeadsUpWhenAwake(NotificationEntry entry) {
@@ -223,13 +283,7 @@
             return false;
         }
 
-        boolean isDreaming = false;
-        try {
-            isDreaming = mDreamManager.isDreaming();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to query dream manager.", e);
-        }
-        boolean inUse = mPowerManager.isScreenOn() && !isDreaming;
+        boolean inUse = mPowerManager.isScreenOn() && !isDreaming();
 
         if (!inUse) {
             mLogger.logNoHeadsUpNotInUse(entry);
@@ -294,11 +348,6 @@
      * @return true if these checks pass, false if the notification should not alert
      */
     private boolean canAlertCommon(NotificationEntry entry) {
-        if (!mFlags.isNewPipelineEnabled() && mNotificationFilter.shouldFilterOut(entry)) {
-            mLogger.logNoAlertingFilteredOut(entry);
-            return false;
-        }
-
         for (int i = 0; i < mSuppressors.size(); i++) {
             if (mSuppressors.get(i).suppressInterruptions(entry)) {
                 mLogger.logNoAlertingSuppressedBy(entry, mSuppressors.get(i), /* awake */ false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
index 9fbd5c3..6391877 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
@@ -22,7 +22,6 @@
 import android.os.SystemClock;
 import android.os.Trace;
 import android.service.notification.NotificationListenerService;
-import android.service.notification.StatusBarNotification;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
@@ -39,9 +38,6 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
 import com.android.systemui.statusbar.NotificationListener;
 import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.notification.NotifPipelineFlags;
-import com.android.systemui.statusbar.notification.NotificationEntryListener;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -80,7 +76,6 @@
     private final Executor mUiBgExecutor;
     private final NotifLiveDataStore mNotifLiveDataStore;
     private final NotificationVisibilityProvider mVisibilityProvider;
-    private final NotificationEntryManager mEntryManager;
     private final NotifPipeline mNotifPipeline;
     private final NotificationPanelLogger mNotificationPanelLogger;
     private final ExpansionStateLogger mExpansionStateLogger;
@@ -220,10 +215,8 @@
      */
     public NotificationLogger(NotificationListener notificationListener,
             @UiBackground Executor uiBgExecutor,
-            NotifPipelineFlags notifPipelineFlags,
             NotifLiveDataStore notifLiveDataStore,
             NotificationVisibilityProvider visibilityProvider,
-            NotificationEntryManager entryManager,
             NotifPipeline notifPipeline,
             StatusBarStateController statusBarStateController,
             ExpansionStateLogger expansionStateLogger,
@@ -232,7 +225,6 @@
         mUiBgExecutor = uiBgExecutor;
         mNotifLiveDataStore = notifLiveDataStore;
         mVisibilityProvider = visibilityProvider;
-        mEntryManager = entryManager;
         mNotifPipeline = notifPipeline;
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
@@ -241,36 +233,7 @@
         // Not expected to be destroyed, don't need to unsubscribe
         statusBarStateController.addCallback(this);
 
-        if (notifPipelineFlags.isNewPipelineEnabled()) {
-            registerNewPipelineListener();
-        } else {
-            registerLegacyListener();
-        }
-    }
-
-    private void registerLegacyListener() {
-        mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
-            @Override
-            public void onEntryRemoved(
-                    NotificationEntry entry,
-                    NotificationVisibility visibility,
-                    boolean removedByUser,
-                    int reason) {
-                mExpansionStateLogger.onEntryRemoved(entry.getKey());
-            }
-
-            @Override
-            public void onPreEntryUpdated(NotificationEntry entry) {
-                mExpansionStateLogger.onEntryUpdated(entry.getKey());
-            }
-
-            @Override
-            public void onInflationError(
-                    StatusBarNotification notification,
-                    Exception exception) {
-                logNotificationError(notification, exception);
-            }
-        });
+        registerNewPipelineListener();
     }
 
     private void registerNewPipelineListener() {
@@ -333,26 +296,6 @@
         }
     }
 
-    /**
-     * Logs Notification inflation error
-     */
-    private void logNotificationError(
-            StatusBarNotification notification,
-            Exception exception) {
-        try {
-            mBarService.onNotificationError(
-                    notification.getPackageName(),
-                    notification.getTag(),
-                    notification.getId(),
-                    notification.getUid(),
-                    notification.getInitialPid(),
-                    exception.getMessage(),
-                    notification.getUserId());
-        } catch (RemoteException ex) {
-            // The end is nigh.
-        }
-    }
-
     private void logNotificationVisibilityChanges(
             Collection<NotificationVisibility> newlyVisible,
             Collection<NotificationVisibility> noLongerVisible) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index cd4a44e..94341ba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -141,7 +141,9 @@
     public static final float DEFAULT_HEADER_VISIBLE_AMOUNT = 1.0f;
     private static final long RECENTLY_ALERTED_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(30);
 
-    private boolean mUpdateSelfBackgroundOnUpdate;
+    // We don't correctly track dark mode until the content views are inflated, so always update
+    // the background on first content update just in case it happens to be during a theme change.
+    private boolean mUpdateSelfBackgroundOnUpdate = true;
     private boolean mNotificationTranslationFinished = false;
     private boolean mIsSnoozed;
     private boolean mIsFaded;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 2fd02d9..defae5b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.notification.stack;
 
 import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_SCROLL_FLING;
+import static com.android.internal.jank.InteractionJankMonitor.CUJ_SHADE_CLEAR_ALL;
 import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_SILENT;
 import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_SWIPE;
 import static com.android.systemui.util.DumpUtilsKt.println;
@@ -5246,6 +5247,7 @@
         setClearAllInProgress(true);
         mShadeNeedsToClose = closeShade;
 
+        InteractionJankMonitor.getInstance().begin(this, CUJ_SHADE_CLEAR_ALL);
         // Decrease the delay for every row we animate to give the sense of
         // accelerating the swipes
         final int rowDelayDecrement = 5;
@@ -6158,6 +6160,7 @@
     private void onClearAllAnimationsEnd(
             List<ExpandableNotificationRow> viewsToRemove,
             @SelectedRows int selectedRows) {
+        InteractionJankMonitor.getInstance().end(CUJ_SHADE_CLEAR_ALL);
         if (mClearAllAnimationListener != null) {
             mClearAllAnimationListener.onAnimationEnd(viewsToRemove, selectedRows);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index b302ba6..b8b7ebe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -28,7 +28,6 @@
 import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_GENTLE;
 import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_HIGH_PRIORITY;
 import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.SelectedRows;
-import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.canChildBeCleared;
 import static com.android.systemui.statusbar.phone.NotificationIconAreaController.HIGH_PRIORITY;
 
 import android.content.res.Configuration;
@@ -38,12 +37,10 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
 import android.util.Log;
 import android.util.Pair;
 import android.view.Display;
-import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
@@ -53,20 +50,17 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.colorextraction.ColorExtractor;
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.UiEvent;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.ExpandHelper;
 import com.android.systemui.Gefingerpoken;
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
 import com.android.systemui.classifier.Classifier;
 import com.android.systemui.classifier.FalsingCollector;
-import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.media.KeyguardMediaController;
@@ -75,6 +69,7 @@
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shade.transition.ShadeTransitionController;
 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener;
@@ -85,9 +80,7 @@
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
 import com.android.systemui.statusbar.notification.LaunchAnimationParameters;
-import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.NotificationActivityStarter;
-import com.android.systemui.statusbar.notification.NotificationEntryListener;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.NotifCollection;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
@@ -120,7 +113,6 @@
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
-import com.android.systemui.statusbar.phone.shade.transition.ShadeTransitionController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -165,13 +157,10 @@
     private final Resources mResources;
     private final NotificationSwipeHelper.Builder mNotificationSwipeHelperBuilder;
     private final ScrimController mScrimController;
-    private final NotifPipelineFlags mNotifPipelineFlags;
     private final NotifPipeline mNotifPipeline;
     private final NotifCollection mNotifCollection;
     private final NotificationEntryManager mNotificationEntryManager;
-    private final IStatusBarService mIStatusBarService;
     private final UiEventLogger mUiEventLogger;
-    private final LayoutInflater mLayoutInflater;
     private final NotificationRemoteInputManager mRemoteInputManager;
     private final VisualStabilityManager mVisualStabilityManager;
     private final ShadeController mShadeController;
@@ -208,8 +197,6 @@
     @Nullable
     private NotificationActivityStarter mNotificationActivityStarter;
 
-    private ColorExtractor.OnColorsChangedListener mOnColorsChangedListener;
-
     @VisibleForTesting
     final View.OnAttachStateChangeListener mOnAttachStateChangeListener =
             new View.OnAttachStateChangeListener() {
@@ -258,10 +245,7 @@
             mView.setAnimateBottomOnLayout(true);
         }
         // Let's update the footer once the notifications have been updated (in the next frame)
-        mView.post(() -> {
-            updateFooter();
-            updateSectionBoundaries("dynamic privacy changed");
-        });
+        mView.post(this::updateFooter);
     };
 
     @VisibleForTesting
@@ -636,7 +620,6 @@
             KeyguardMediaController keyguardMediaController,
             KeyguardBypassController keyguardBypassController,
             ZenModeController zenModeController,
-            SysuiColorExtractor colorExtractor,
             NotificationLockscreenUserManager lockscreenUserManager,
             MetricsLogger metricsLogger,
             DumpManager dumpManager,
@@ -649,15 +632,12 @@
             NotificationGroupManagerLegacy legacyGroupManager,
             GroupExpansionManager groupManager,
             @SilentHeader SectionHeaderController silentHeaderController,
-            NotifPipelineFlags notifPipelineFlags,
             NotifPipeline notifPipeline,
             NotifCollection notifCollection,
             NotificationEntryManager notificationEntryManager,
             LockscreenShadeTransitionController lockscreenShadeTransitionController,
             ShadeTransitionController shadeTransitionController,
-            IStatusBarService iStatusBarService,
             UiEventLogger uiEventLogger,
-            LayoutInflater layoutInflater,
             NotificationRemoteInputManager remoteInputManager,
             VisualStabilityManager visualStabilityManager,
             ShadeController shadeController,
@@ -700,14 +680,11 @@
                 mCentralSurfaces.requestNotificationUpdate("onGroupsChanged");
             }
         });
-        mNotifPipelineFlags = notifPipelineFlags;
         mSilentHeaderController = silentHeaderController;
         mNotifPipeline = notifPipeline;
         mNotifCollection = notifCollection;
         mNotificationEntryManager = notificationEntryManager;
-        mIStatusBarService = iStatusBarService;
         mUiEventLogger = uiEventLogger;
-        mLayoutInflater = layoutInflater;
         mRemoteInputManager = remoteInputManager;
         mVisualStabilityManager = visualStabilityManager;
         mShadeController = shadeController;
@@ -747,21 +724,12 @@
                 .setOnMenuEventListener(mMenuEventListener)
                 .build();
 
-        if (mNotifPipelineFlags.isNewPipelineEnabled()) {
-            mNotifPipeline.addCollectionListener(new NotifCollectionListener() {
-                @Override
-                public void onEntryUpdated(NotificationEntry entry) {
-                    mView.onEntryUpdated(entry);
-                }
-            });
-        } else {
-            mNotificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
-                @Override
-                public void onPreEntryUpdated(NotificationEntry entry) {
-                    mView.onEntryUpdated(entry);
-                }
-            });
-        }
+        mNotifPipeline.addCollectionListener(new NotifCollectionListener() {
+            @Override
+            public void onEntryUpdated(NotificationEntry entry) {
+                mView.onEntryUpdated(entry);
+            }
+        });
 
         mView.initView(mView.getContext(), mSwipeHelper, mNotificationStackSizeCalculator);
         mView.setKeyguardBypassEnabled(mKeyguardBypassController.getBypassEnabled());
@@ -1233,10 +1201,6 @@
         Trace.endSection();
     }
 
-    public boolean areNotificationsHiddenInShade() {
-        return mZenModeController.areNotificationsHiddenInShade();
-    }
-
     public boolean isShowingEmptyShadeView() {
         return mShowEmptyShadeView;
     }
@@ -1341,15 +1305,6 @@
         };
     }
 
-    public void updateSectionBoundaries(String reason) {
-        if (mNotifPipelineFlags.isNewPipelineEnabled()) {
-            return;
-        }
-        Trace.beginSection("NSSLC.updateSectionBoundaries");
-        mView.updateSectionBoundaries(reason);
-        Trace.endSection();
-    }
-
     public void updateFooter() {
         Trace.beginSection("NSSLC.updateFooter");
         mView.updateFooter();
@@ -1465,39 +1420,18 @@
 
     private void onAnimationEnd(List<ExpandableNotificationRow> viewsToRemove,
             @SelectedRows int selectedRows) {
-        if (mNotifPipelineFlags.isNewPipelineEnabled()) {
-            if (selectedRows == ROWS_ALL) {
-                mNotifCollection.dismissAllNotifications(
-                        mLockscreenUserManager.getCurrentUserId());
-            } else {
-                final List<Pair<NotificationEntry, DismissedByUserStats>>
-                        entriesWithRowsDismissedFromShade = new ArrayList<>();
-                for (ExpandableNotificationRow row : viewsToRemove) {
-                    final NotificationEntry entry = row.getEntry();
-                    entriesWithRowsDismissedFromShade.add(
-                            new Pair<>(entry, getDismissedByUserStats(entry)));
-                }
-                mNotifCollection.dismissNotifications(entriesWithRowsDismissedFromShade);
-            }
+        if (selectedRows == ROWS_ALL) {
+            mNotifCollection.dismissAllNotifications(
+                    mLockscreenUserManager.getCurrentUserId());
         } else {
-            for (ExpandableNotificationRow rowToRemove : viewsToRemove) {
-                if (canChildBeCleared(rowToRemove)) {
-                    mNotificationEntryManager.performRemoveNotification(
-                            rowToRemove.getEntry().getSbn(),
-                            getDismissedByUserStats(rowToRemove.getEntry()),
-                            NotificationListenerService.REASON_CANCEL_ALL);
-                } else {
-                    rowToRemove.resetTranslation();
-                }
+            final List<Pair<NotificationEntry, DismissedByUserStats>>
+                    entriesWithRowsDismissedFromShade = new ArrayList<>();
+            for (ExpandableNotificationRow row : viewsToRemove) {
+                final NotificationEntry entry = row.getEntry();
+                entriesWithRowsDismissedFromShade.add(
+                        new Pair<>(entry, getDismissedByUserStats(entry)));
             }
-            if (selectedRows == ROWS_ALL) {
-                try {
-                    // TODO(b/169585328): Do not clear media player notifications
-                    mIStatusBarService.onClearAllNotifications(
-                            mLockscreenUserManager.getCurrentUserId());
-                } catch (Exception ignored) {
-                }
-            }
+            mNotifCollection.dismissNotifications(entriesWithRowsDismissedFromShade);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index b7a605a7..602971a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -47,6 +47,9 @@
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.qs.QSPanelController;
+import com.android.systemui.shade.NotificationPanelViewController;
+import com.android.systemui.shade.NotificationShadeWindowView;
+import com.android.systemui.shade.NotificationShadeWindowViewController;
 import com.android.systemui.statusbar.GestureRecorder;
 import com.android.systemui.statusbar.LightRevealScrim;
 import com.android.systemui.statusbar.NotificationPresenter;
@@ -265,9 +268,6 @@
 
     boolean isPulsing();
 
-    @Nullable
-    View getAmbientIndicationContainer();
-
     boolean isOccluded();
 
     //TODO: These can / should probably be moved to NotificationPresenter or ShadeController
@@ -560,8 +560,6 @@
 
     void setLaunchEmergencyActionOnFinishedWaking(boolean launch);
 
-    void setTopHidesStatusBar(boolean hides);
-
     QSPanelController getQSPanelController();
 
     boolean areNotificationAlertsDisabled();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
index cb9afe8..53b5b0c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
@@ -55,6 +55,9 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.qs.QSPanelController;
+import com.android.systemui.shade.NotificationPanelView;
+import com.android.systemui.shade.NotificationPanelViewController;
+import com.android.systemui.shade.NotificationShadeWindowView;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.DisableFlagsLogger;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index f627c5b..dbeb4c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -147,7 +147,6 @@
 import com.android.systemui.dagger.qualifiers.UiBackground;
 import com.android.systemui.demomode.DemoMode;
 import com.android.systemui.demomode.DemoModeController;
-import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.emergency.EmergencyGesture;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
@@ -174,6 +173,9 @@
 import com.android.systemui.recents.ScreenPinningRequest;
 import com.android.systemui.scrim.ScrimView;
 import com.android.systemui.settings.brightness.BrightnessSliderController;
+import com.android.systemui.shade.NotificationPanelViewController;
+import com.android.systemui.shade.NotificationShadeWindowView;
+import com.android.systemui.shade.NotificationShadeWindowViewController;
 import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.statusbar.AutoHideUiElement;
 import com.android.systemui.statusbar.BackDropView;
@@ -197,7 +199,6 @@
 import com.android.systemui.statusbar.PulseExpansionHandler;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
-import com.android.systemui.statusbar.connectivity.NetworkController;
 import com.android.systemui.statusbar.core.StatusBarInitializer;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
 import com.android.systemui.statusbar.notification.NotifPipelineFlags;
@@ -206,7 +207,6 @@
 import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
 import com.android.systemui.statusbar.notification.init.NotificationsController;
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
@@ -237,7 +237,6 @@
 import com.android.systemui.util.concurrency.DelayableExecutor;
 import com.android.systemui.util.concurrency.MessageRouter;
 import com.android.systemui.volume.VolumeComponent;
-import com.android.systemui.wmshell.BubblesManager;
 import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.startingsurface.SplashscreenContentDrawer;
 import com.android.wm.shell.startingsurface.StartingSurface;
@@ -291,7 +290,6 @@
     private static final UiEventLogger sUiEventLogger = new UiEventLoggerImpl();
 
     private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
-    private final DreamOverlayStateController mDreamOverlayStateController;
     private CentralSurfacesCommandQueueCallbacks mCommandQueueCallbacks;
     private float mTransitionToFullShadeProgress = 0f;
     private NotificationListContainer mNotifListContainer;
@@ -389,11 +387,6 @@
     }
 
     @Override
-    public void setTopHidesStatusBar(boolean hides) {
-        mTopHidesStatusBar = hides;
-    }
-
-    @Override
     public QSPanelController getQSPanelController() {
         return mQSPanelController;
     }
@@ -436,7 +429,6 @@
     private BiometricUnlockController mBiometricUnlockController;
     private final LightBarController mLightBarController;
     private final Lazy<LockscreenWallpaper> mLockscreenWallpaperLazy;
-    private final LockscreenGestureLogger mLockscreenGestureLogger;
     @Nullable
     protected LockscreenWallpaper mLockscreenWallpaper;
     private final AutoHideController mAutoHideController;
@@ -503,9 +495,6 @@
 
     private boolean mExpandedVisible;
 
-    private final int[] mAbsPos = new int[2];
-
-    private final NotifShadeEventSource mNotifShadeEventSource;
     protected final NotificationEntryManager mEntryManager;
     private final NotificationGutsManager mGutsManager;
     private final NotificationLogger mNotificationLogger;
@@ -587,7 +576,6 @@
         }
     }
 
-    private Handler mMainHandler;
     private final DelayableExecutor mMainExecutor;
 
     private int mInteractingWindows;
@@ -621,12 +609,9 @@
 
     // Fingerprint (as computed by getLoggingFingerprint() of the last logged state.
     private int mLastLoggedStateFingerprint;
-    private boolean mTopHidesStatusBar;
-    private boolean mStatusBarWindowHidden;
     private boolean mIsLaunchingActivityOverLockscreen;
 
     private final UserSwitcherController mUserSwitcherController;
-    private final NetworkController mNetworkController;
     private final LifecycleRegistry mLifecycle = new LifecycleRegistry(this);
     protected final BatteryController mBatteryController;
     protected boolean mPanelExpanded;
@@ -646,7 +631,6 @@
     protected NotificationPresenter mPresenter;
     private NotificationActivityStarter mNotificationActivityStarter;
     private final Lazy<NotificationShadeDepthController> mNotificationShadeDepthControllerLazy;
-    private final Optional<BubblesManager> mBubblesManagerOptional;
     private final Optional<Bubbles> mBubblesOptional;
     private final Bubbles.BubbleExpandListener mBubbleExpandListener;
     private final Optional<StartingSurface> mStartingSurfaceOptional;
@@ -688,7 +672,6 @@
             FalsingManager falsingManager,
             FalsingCollector falsingCollector,
             BroadcastDispatcher broadcastDispatcher,
-            NotifShadeEventSource notifShadeEventSource,
             NotificationEntryManager notificationEntryManager,
             NotificationGutsManager notificationGutsManager,
             NotificationLogger notificationLogger,
@@ -703,13 +686,11 @@
             NotificationLockscreenUserManager lockScreenUserManager,
             NotificationRemoteInputManager remoteInputManager,
             UserSwitcherController userSwitcherController,
-            NetworkController networkController,
             BatteryController batteryController,
             SysuiColorExtractor colorExtractor,
             ScreenLifecycle screenLifecycle,
             WakefulnessLifecycle wakefulnessLifecycle,
             SysuiStatusBarStateController statusBarStateController,
-            Optional<BubblesManager> bubblesManagerOptional,
             Optional<Bubbles> bubblesOptional,
             VisualStabilityManager visualStabilityManager,
             DeviceProvisionedController deviceProvisionedController,
@@ -721,7 +702,6 @@
             DozeParameters dozeParameters,
             ScrimController scrimController,
             Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
-            LockscreenGestureLogger lockscreenGestureLogger,
             Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
             DozeServiceHost dozeServiceHost,
             PowerManager powerManager,
@@ -754,7 +734,6 @@
             LockscreenShadeTransitionController lockscreenShadeTransitionController,
             FeatureFlags featureFlags,
             KeyguardUnlockAnimationController keyguardUnlockAnimationController,
-            @Main Handler mainHandler,
             @Main DelayableExecutor delayableExecutor,
             @Main MessageRouter messageRouter,
             WallpaperManager wallpaperManager,
@@ -763,7 +742,6 @@
             NotifPipelineFlags notifPipelineFlags,
             InteractionJankMonitor jankMonitor,
             DeviceStateManager deviceStateManager,
-            DreamOverlayStateController dreamOverlayStateController,
             WiredChargingRippleController wiredChargingRippleController,
             IDreamManager dreamManager) {
         super(context);
@@ -784,7 +762,6 @@
         mFalsingCollector = falsingCollector;
         mFalsingManager = falsingManager;
         mBroadcastDispatcher = broadcastDispatcher;
-        mNotifShadeEventSource = notifShadeEventSource;
         mEntryManager = notificationEntryManager;
         mGutsManager = notificationGutsManager;
         mNotificationLogger = notificationLogger;
@@ -799,13 +776,11 @@
         mLockscreenUserManager = lockScreenUserManager;
         mRemoteInputManager = remoteInputManager;
         mUserSwitcherController = userSwitcherController;
-        mNetworkController = networkController;
         mBatteryController = batteryController;
         mColorExtractor = colorExtractor;
         mScreenLifecycle = screenLifecycle;
         mWakefulnessLifecycle = wakefulnessLifecycle;
         mStatusBarStateController = statusBarStateController;
-        mBubblesManagerOptional = bubblesManagerOptional;
         mBubblesOptional = bubblesOptional;
         mVisualStabilityManager = visualStabilityManager;
         mDeviceProvisionedController = deviceProvisionedController;
@@ -819,7 +794,6 @@
         mDozeParameters = dozeParameters;
         mScrimController = scrimController;
         mLockscreenWallpaperLazy = lockscreenWallpaperLazy;
-        mLockscreenGestureLogger = lockscreenGestureLogger;
         mScreenPinningRequest = screenPinningRequest;
         mDozeScrimController = dozeScrimController;
         mBiometricUnlockControllerLazy = biometricUnlockControllerLazy;
@@ -846,12 +820,10 @@
         mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager;
         mFeatureFlags = featureFlags;
         mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
-        mMainHandler = mainHandler;
         mMainExecutor = delayableExecutor;
         mMessageRouter = messageRouter;
         mWallpaperManager = wallpaperManager;
         mJankMonitor = jankMonitor;
-        mDreamOverlayStateController = dreamOverlayStateController;
 
         mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
         mStartingSurfaceOptional = startingSurfaceOptional;
@@ -1181,9 +1153,6 @@
 
         mStatusBarTouchableRegionManager.setup(this, mNotificationShadeWindowView);
         mHeadsUpManager.addListener(mNotificationPanelViewController.getOnHeadsUpChangedListener());
-        if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
-            mHeadsUpManager.addListener(mVisualStabilityManager);
-        }
         mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager);
 
         createNavigationBar(result);
@@ -1468,12 +1437,16 @@
             mPowerManager.wakeUp(
                     time, PowerManager.WAKE_REASON_GESTURE, "com.android.systemui:" + why);
             mWakeUpComingFromTouch = true;
-            where.getLocationInWindow(mTmpInt2);
 
             // NOTE, the incoming view can sometimes be the entire container... unsure if
             // this location is valuable enough
-            mWakeUpTouchLocation = new PointF(mTmpInt2[0] + where.getWidth() / 2,
-                    mTmpInt2[1] + where.getHeight() / 2);
+            if (where != null) {
+                where.getLocationInWindow(mTmpInt2);
+                mWakeUpTouchLocation = new PointF(mTmpInt2[0] + where.getWidth() / 2,
+                        mTmpInt2[1] + where.getHeight() / 2);
+            } else {
+                mWakeUpTouchLocation = new PointF(-1, -1);
+            }
             mFalsingCollector.onScreenOnFromTouch();
         }
     }
@@ -1719,7 +1692,7 @@
             // Wrap the animation controller to dismiss the shade and set
             // mIsLaunchingActivityOverLockscreen during the animation.
             ActivityLaunchAnimator.Controller delegate = wrapAnimationController(
-                    animationController, dismissShade);
+                    animationController, dismissShade, /* isLaunchForActivity= */ true);
             controller = new DelegateLaunchAnimatorController(delegate) {
                 @Override
                 public void onIntentStarted(boolean willAnimate) {
@@ -1871,12 +1844,6 @@
         return mDozeServiceHost.isPulsing();
     }
 
-    @androidx.annotation.Nullable
-    @Override
-    public View getAmbientIndicationContainer() {
-        return mAmbientIndicationContainer;
-    }
-
     /**
      * When the keyguard is showing and covered by a "showWhenLocked" activity it
      * is occluded. This is controlled by {@link com.android.server.policy.PhoneWindowManager}
@@ -2256,8 +2223,7 @@
     public void updateBubblesVisibility() {
         mBubblesOptional.ifPresent(bubbles -> bubbles.onStatusBarVisibilityChanged(
                 mStatusBarMode != MODE_LIGHTS_OUT
-                        && mStatusBarMode != MODE_LIGHTS_OUT_TRANSPARENT
-                        && !mStatusBarWindowHidden));
+                        && mStatusBarMode != MODE_LIGHTS_OUT_TRANSPARENT));
     }
 
     void checkBarMode(@TransitionMode int mode, @WindowVisibleState int windowState,
@@ -2474,7 +2440,7 @@
                         true /* isActivityIntent */);
         ActivityLaunchAnimator.Controller animController =
                 animationController != null ? wrapAnimationController(animationController,
-                        dismissShade) : null;
+                        dismissShade, /* isLaunchForActivity= */ true) : null;
 
         // If we animate, we will dismiss the shade only once the animation is done. This is taken
         // care of by the StatusBarLaunchAnimationController.
@@ -2543,13 +2509,34 @@
                 callback.onActivityStarted(ActivityManager.START_CANCELED);
             }
         };
+        // Do not deferKeyguard when occluded because, when keyguard is occluded,
+        // we do not launch the activity until keyguard is done.
+        boolean occluded = mStatusBarKeyguardViewManager.isShowing()
+                && mStatusBarKeyguardViewManager.isOccluded();
+        boolean deferred = !occluded;
         executeRunnableDismissingKeyguard(runnable, cancelRunnable, dismissShadeDirectly,
-                willLaunchResolverActivity, true /* deferred */, animate);
+                willLaunchResolverActivity, deferred /* deferred */, animate);
     }
 
+    /**
+     * Return a {@link ActivityLaunchAnimator.Controller} wrapping {@code animationController} so
+     * that:
+     *  - if it launches in the notification shade window and {@code dismissShade} is true, then
+     *    the shade will be instantly dismissed at the end of the animation.
+     *  - if it launches in status bar window, it will make the status bar window match the device
+     *    size during the animation (that way, the animation won't be clipped by the status bar
+     *    size).
+     *
+     * @param animationController the controller that is wrapped and will drive the main animation.
+     * @param dismissShade whether the notification shade will be dismissed at the end of the
+     *                     animation. This is ignored if {@code animationController} is not
+     *                     animating in the shade window.
+     * @param isLaunchForActivity whether the launch is for an activity.
+     */
     @Nullable
     private ActivityLaunchAnimator.Controller wrapAnimationController(
-            ActivityLaunchAnimator.Controller animationController, boolean dismissShade) {
+            ActivityLaunchAnimator.Controller animationController, boolean dismissShade,
+            boolean isLaunchForActivity) {
         View rootView = animationController.getLaunchContainer().getRootView();
 
         Optional<ActivityLaunchAnimator.Controller> controllerFromStatusBar =
@@ -2563,7 +2550,7 @@
             // If the view is not in the status bar, then we are animating a view in the shade.
             // We have to make sure that we collapse it when the animation ends or is cancelled.
             return new StatusBarLaunchAnimatorController(animationController, this,
-                    true /* isLaunchForActivity */);
+                    isLaunchForActivity);
         }
 
         return animationController;
@@ -2704,7 +2691,8 @@
     @Override
     public void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
             boolean afterKeyguardGone) {
-        if (mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_ASLEEP
+        if (!action.willRunAnimationOnKeyguard()
+                && mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_ASLEEP
                 && mKeyguardStateController.canDismissLockScreen()
                 && !mStatusBarStateController.leaveOpenOnKeyguardHide()
                 && mDozeServiceHost.isPulsing()) {
@@ -3519,6 +3507,9 @@
         setBouncerShowingForStatusBarComponents(bouncerShowing);
         mStatusBarHideIconsForBouncerManager.setBouncerShowingAndTriggerUpdate(bouncerShowing);
         mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
+        if (mBouncerShowing) {
+            wakeUpIfDozing(SystemClock.uptimeMillis(), null, "BOUNCER_VISIBLE");
+        }
         updateScrimController();
         if (!mBouncerShowing) {
             updatePanelExpansionForKeyguard();
@@ -4091,8 +4082,9 @@
                 // We wrap animationCallback with a StatusBarLaunchAnimatorController so that the
                 // shade is collapsed after the animation (or when it is cancelled, aborted, etc).
                 ActivityLaunchAnimator.Controller controller =
-                        animationController != null ? new StatusBarLaunchAnimatorController(
-                                animationController, this, intent.isActivity()) : null;
+                        animationController != null ? wrapAnimationController(
+                                animationController, /* dismissShade= */ true, intent.isActivity())
+                                : null;
 
                 mActivityLaunchAnimator.startPendingIntentWithAnimation(
                         controller, animate, intent.getCreatorPackage(),
@@ -4338,9 +4330,6 @@
                 Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
             }
 
-            if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
-                mViewHierarchyManager.updateRowStates();
-            }
             mScreenPinningRequest.onConfigurationChanged();
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
index 55b310f..80c3e6c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
@@ -40,6 +40,8 @@
 import com.android.systemui.doze.DozeReceiver;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.shade.NotificationPanelViewController;
+import com.android.systemui.shade.NotificationShadeWindowViewController;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.PulseExpansionHandler;
 import com.android.systemui.statusbar.StatusBarState;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index 9863a0e..484441a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -26,6 +26,7 @@
 import com.android.systemui.R;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.CrossFadeHelper;
 import com.android.systemui.statusbar.HeadsUpStatusBarView;
@@ -40,8 +41,8 @@
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
 import com.android.systemui.util.ViewController;
 
-import java.util.Optional;
 import java.util.ArrayList;
+import java.util.Optional;
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index 0195e45..b99b4ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -221,8 +221,9 @@
      * Notify that the status bar panel gets expanded or collapsed.
      *
      * @param isExpanded True to notify expanded, false to notify collapsed.
+     * TODO(b/237811427) replace with a listener
      */
-    void setIsPanelExpanded(boolean isExpanded) {
+    public void setIsPanelExpanded(boolean isExpanded) {
         if (isExpanded != mIsExpanded) {
             mIsExpanded = isExpanded;
             if (isExpanded) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
index 42f301d..6bfb0da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -21,6 +21,7 @@
 import android.view.ViewConfiguration;
 
 import com.android.systemui.Gefingerpoken;
+import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 52c04b9..ff3d122 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -39,6 +39,7 @@
 import android.util.TypedValue;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewPropertyAnimator;
 import android.view.WindowInsets;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
@@ -62,6 +63,9 @@
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.wallet.controller.QuickAccessWalletController;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Implementation for the bottom area of the Keyguard, including camera/phone affordance and status
  * text.
@@ -89,7 +93,6 @@
 
     private ActivityStarter mActivityStarter;
     private KeyguardStateController mKeyguardStateController;
-    private CentralSurfaces mCentralSurfaces;
     private FalsingManager mFalsingManager;
 
     private boolean mDozing;
@@ -139,9 +142,38 @@
         super(context, attrs, defStyleAttr, defStyleRes);
     }
 
-    public void initFrom(KeyguardBottomAreaView oldBottomArea) {
-        setCentralSurfaces(oldBottomArea.mCentralSurfaces);
+    /** Initializes the {@link KeyguardBottomAreaView} with the given dependencies */
+    public void init(
+            FalsingManager falsingManager,
+            QuickAccessWalletController controller,
+            ControlsComponent controlsComponent,
+            QRCodeScannerController qrCodeScannerController) {
+        mFalsingManager = falsingManager;
+        mQuickAccessWalletController = controller;
+        mQuickAccessWalletController.setupWalletChangeObservers(
+                mCardRetriever, WALLET_PREFERENCE_CHANGE, DEFAULT_PAYMENT_APP_CHANGE);
+        mQuickAccessWalletController.updateWalletPreference();
+        mQuickAccessWalletController.queryWalletCards(mCardRetriever);
+        updateWalletVisibility();
 
+        mControlsComponent = controlsComponent;
+        mControlsComponent.getControlsListingController().ifPresent(
+                c -> c.addCallback(mListingCallback));
+
+        mQRCodeScannerController = qrCodeScannerController;
+        mQRCodeScannerController.registerQRCodeScannerChangeObservers(
+                QRCodeScannerController.DEFAULT_QR_CODE_SCANNER_CHANGE,
+                QRCodeScannerController.QR_CODE_SCANNER_PREFERENCE_CHANGE);
+        updateQRCodeButtonVisibility();
+
+        updateAffordanceColors();
+    }
+
+    /**
+     * Initializes this instance of {@link KeyguardBottomAreaView} based on the given instance of
+     * another {@link KeyguardBottomAreaView}
+     */
+    public void initFrom(KeyguardBottomAreaView oldBottomArea) {
         // if it exists, continue to use the original ambient indication container
         // instead of the newly inflated one
         if (mAmbientIndicationArea != null) {
@@ -268,10 +300,6 @@
         updateAffordanceColors();
     }
 
-    public void setCentralSurfaces(CentralSurfaces centralSurfaces) {
-        mCentralSurfaces = centralSurfaces;
-    }
-
     private void updateWalletVisibility() {
         if (mDozing
                 || mQuickAccessWalletController == null
@@ -323,8 +351,17 @@
         dozeTimeTick();
     }
 
-    public View getIndicationArea() {
-        return mIndicationArea;
+    /**
+     * Returns a list of animators to use to animate the indication areas.
+     */
+    public List<ViewPropertyAnimator> getIndicationAreaAnimators() {
+        List<ViewPropertyAnimator> animators =
+                new ArrayList<>(mAmbientIndicationArea != null ? 2 : 1);
+        animators.add(mIndicationArea.animate());
+        if (mAmbientIndicationArea != null) {
+            animators.add(mAmbientIndicationArea.animate());
+        }
+        return animators;
     }
 
     @Override
@@ -332,7 +369,7 @@
         return false;
     }
 
-    public void startFinishDozeAnimation() {
+    private void startFinishDozeAnimation() {
         long delay = 0;
         if (mWalletButton.getVisibility() == View.VISIBLE) {
             startFinishDozeAnimationElement(mWalletButton, delay);
@@ -394,9 +431,17 @@
     }
 
     /**
-     * Sets the alpha of the indication areas and affordances, excluding the lock icon.
+     * Sets the alpha of various sub-components, for example the indication areas and bottom quick
+     * action buttons. Does not set the alpha of the lock icon.
      */
-    public void setAffordanceAlpha(float alpha) {
+    public void setComponentAlphas(float alpha) {
+        setImportantForAccessibility(
+                alpha == 0f
+                        ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
+                        : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+        if (mAmbientIndicationArea != null) {
+            mAmbientIndicationArea.setAlpha(alpha);
+        }
         mIndicationArea.setAlpha(alpha);
         mWalletButton.setAlpha(alpha);
         mQRCodeScannerButton.setAlpha(alpha);
@@ -415,38 +460,6 @@
         return insets;
     }
 
-    /** Set the falsing manager */
-    public void setFalsingManager(FalsingManager falsingManager) {
-        mFalsingManager = falsingManager;
-    }
-
-    /**
-     * Initialize the wallet feature, only enabling if the feature is enabled within the platform.
-     */
-    public void initWallet(
-            QuickAccessWalletController controller) {
-        mQuickAccessWalletController = controller;
-        mQuickAccessWalletController.setupWalletChangeObservers(
-                mCardRetriever, WALLET_PREFERENCE_CHANGE, DEFAULT_PAYMENT_APP_CHANGE);
-        mQuickAccessWalletController.updateWalletPreference();
-        mQuickAccessWalletController.queryWalletCards(mCardRetriever);
-
-        updateWalletVisibility();
-        updateAffordanceColors();
-    }
-
-    /**
-     * Initialize the qr code scanner feature, controlled by QRCodeScannerController.
-     */
-    public void initQRCodeScanner(QRCodeScannerController qrCodeScannerController) {
-        mQRCodeScannerController = qrCodeScannerController;
-        mQRCodeScannerController.registerQRCodeScannerChangeObservers(
-                QRCodeScannerController.DEFAULT_QR_CODE_SCANNER_CHANGE,
-                QRCodeScannerController.QR_CODE_SCANNER_PREFERENCE_CHANGE);
-        updateQRCodeButtonVisibility();
-        updateAffordanceColors();
-    }
-
     private void updateQRCodeButtonVisibility() {
         if (mQuickAccessWalletController != null
                 && mQuickAccessWalletController.isWalletEnabled()) {
@@ -502,17 +515,6 @@
         mQRCodeScannerButton.setBackgroundTintList(bgColor);
     }
 
-    /**
-      * Initialize controls via the ControlsComponent
-      */
-    public void initControls(ControlsComponent controlsComponent) {
-        mControlsComponent = controlsComponent;
-        mControlsComponent.getControlsListingController().ifPresent(
-                c -> c.addCallback(mListingCallback));
-
-        updateAffordanceColors();
-    }
-
     private void onWalletClick(View v) {
         // More coming here; need to inform the user about how to proceed
         if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 8e65541..e63c383 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -266,6 +266,9 @@
 
     private void setVisibility(@View.Visibility int visibility) {
         mContainer.setVisibility(visibility);
+        if (mKeyguardViewController != null) {
+            mKeyguardViewController.onBouncerVisibilityChanged(visibility);
+        }
         dispatchVisibilityChanged();
     }
 
@@ -397,10 +400,6 @@
         return mShowingSoon || mExpansion != EXPANSION_HIDDEN && mExpansion != EXPANSION_VISIBLE;
     }
 
-    public boolean getShowingSoon() {
-        return mShowingSoon;
-    }
-
     /**
      * @return {@code true} when bouncer's pre-hide animation already started but isn't completely
      *         hidden yet, {@code false} otherwise.
@@ -644,6 +643,10 @@
     public interface BouncerExpansionCallback {
         /**
          * Invoked when the bouncer expansion reaches {@link KeyguardBouncer#EXPANSION_VISIBLE}.
+         * This is NOT called each time the bouncer is shown, but rather only when the fully
+         * shown amount has changed based on the panel expansion. The bouncer's visibility
+         * can still change when the expansion amount hasn't changed.
+         * See {@link KeyguardBouncer#isShowing()} for the checks for the bouncer showing state.
          */
         default void onFullyShown() {
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index dde6b16..01af486 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -27,6 +27,7 @@
 import com.android.keyguard.KeyguardStatusView;
 import com.android.systemui.R;
 import com.android.systemui.animation.Interpolators;
+import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcherListView;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
index def574c..f06b346 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
@@ -42,6 +42,7 @@
 import com.android.systemui.battery.BatteryMeterViewController;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.events.SystemStatusAnimationCallback;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 2dc3261..a2140c6ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License
  */
-
 package com.android.systemui.statusbar.phone;
 
 import static com.android.systemui.statusbar.phone.HeadsUpAppearanceController.CONTENT_FADE_DELAY;
@@ -31,6 +30,7 @@
 import android.util.Property;
 import android.view.ContextThemeWrapper;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.animation.Interpolator;
 
 import androidx.annotation.VisibleForTesting;
@@ -40,7 +40,6 @@
 import com.android.settingslib.Utils;
 import com.android.systemui.R;
 import com.android.systemui.animation.Interpolators;
-import com.android.systemui.statusbar.AlphaOptimizedFrameLayout;
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.notification.stack.AnimationFilter;
 import com.android.systemui.statusbar.notification.stack.AnimationProperties;
@@ -54,7 +53,7 @@
  * A container for notification icons. It handles overflowing icons properly and positions them
  * correctly on the screen.
  */
-public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
+public class NotificationIconContainer extends ViewGroup {
     /**
      * A float value indicating how much before the overflow start the icons should transform into
      * a dot. A value of 0 means that they are exactly at the end and a value of 1 means it starts
@@ -232,6 +231,31 @@
     }
 
     @Override
+    public boolean hasOverlappingRendering() {
+        // Does the same as "AlphaOptimizedFrameLayout".
+        return false;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        final int childCount = getChildCount();
+        final int maxVisibleIcons = getMaxVisibleIcons(childCount);
+        final int width = MeasureSpec.getSize(widthMeasureSpec);
+        final int childWidthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.UNSPECIFIED);
+        int totalWidth = (int) (getActualPaddingStart() + getActualPaddingEnd());
+        for (int i = 0; i < childCount; i++) {
+            View child = getChildAt(i);
+            measureChild(child, childWidthSpec, heightMeasureSpec);
+            if (i <= maxVisibleIcons) {
+                totalWidth += child.getMeasuredWidth();
+            }
+        }
+        final int measuredWidth = resolveSize(totalWidth, widthMeasureSpec);
+        final int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
+        setMeasuredDimension(measuredWidth, measuredHeight);
+    }
+
+    @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         float centerY = getHeight() / 2.0f;
         // we layout all our children on the left at the top
@@ -408,8 +432,7 @@
         float translationX = getActualPaddingStart();
         int firstOverflowIndex = -1;
         int childCount = getChildCount();
-        int maxVisibleIcons = mOnLockScreen ? MAX_ICONS_ON_AOD :
-                mIsStaticLayout ? MAX_STATIC_ICONS : childCount;
+        int maxVisibleIcons = getMaxVisibleIcons(childCount);
         float layoutEnd = getLayoutEnd();
         mVisualOverflowStart = 0;
         mFirstVisibleIconState = null;
@@ -493,6 +516,11 @@
         }
     }
 
+    private int getMaxVisibleIcons(int childCount) {
+        return mOnLockScreen ? MAX_ICONS_ON_AOD :
+                mIsStaticLayout ? MAX_STATIC_ICONS : childCount;
+    }
+
     private float getLayoutEnd() {
         return getActualWidth() - getActualPaddingEnd();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
index a8da554..905a5f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
@@ -44,6 +44,8 @@
 import android.view.WindowManager.LayoutParams;
 import android.view.WindowManagerGlobal;
 
+import androidx.lifecycle.ViewTreeLifecycleOwner;
+
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.Dumpable;
 import com.android.systemui.R;
@@ -52,6 +54,7 @@
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.lifecycle.WindowAddedViewLifecycleOwner;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
@@ -241,6 +244,16 @@
         mLp.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
 
         mWindowManager.addView(mNotificationShadeView, mLp);
+
+        // Set up and "inject" a LifecycleOwner bound to the Window-View relationship such that all
+        // views in the sub-tree rooted under this view can access the LifecycleOwner using
+        // ViewTreeLifecycleOwner.get(...).
+        if (ViewTreeLifecycleOwner.get(mNotificationShadeView) == null) {
+            ViewTreeLifecycleOwner.set(
+                    mNotificationShadeView,
+                    new WindowAddedViewLifecycleOwner(mNotificationShadeView));
+        }
+
         mLpChanged.copyFrom(mLp);
         onThemeChanged();
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/OWNERS b/packages/SystemUI/src/com/android/systemui/statusbar/phone/OWNERS
index f5828f9..4657e9b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/OWNERS
@@ -3,14 +3,4 @@
 
 per-file NotificationIcon* = ccassidy@google.com, evanlaird@google.com, pixel@google.com
 
-per-file NotificationsQuickSettingsContainer.java = kozynski@google.com, asc@google.com
-per-file NotificationsQSContainerController.kt = kozynski@google.com, asc@google.com
-
 per-file NotificationShadeWindowControllerImpl.java = dupin@google.com, cinek@google.com, beverlyt@google.com, pixel@google.com, juliacr@google.com
-per-file NotificationShadeWindowViewController.java = pixel@google.com, cinek@google.com, juliacr@google.com
-per-file NotificationShadeWindowView.java = pixel@google.com, cinek@google.com, juliacr@google.com
-
-per-file NotificationPanelUnfoldAnimationController.kt = alexflo@google.com, jeffdq@google.com, juliacr@google.com
-
-per-file NotificationPanelView.java = pixel@google.com, cinek@google.com, juliacr@google.com
-per-file NotificationPanelViewController.java = pixel@google.com, cinek@google.com, juliacr@google.com
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index d2fc1af..3a85a3e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -41,6 +41,7 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
+import android.view.ViewPropertyAnimator;
 import android.view.ViewTreeObserver;
 import android.view.animation.Interpolator;
 
@@ -66,6 +67,7 @@
 import com.android.wm.shell.animation.FlingAnimationUtils;
 
 import java.io.PrintWriter;
+import java.util.List;
 
 public abstract class PanelViewController {
     public static final boolean DEBUG = PanelView.DEBUG;
@@ -599,9 +601,7 @@
             float collapseSpeedUpFactor, boolean expandBecauseOfFalsing) {
         if (target == mExpandedHeight && mOverExpansion == 0.0f) {
             // We're at the target and didn't fling and there's no overshoot
-            endJankMonitoring(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
-            mKeyguardStateController.notifyPanelFlingEnd();
-            notifyExpandingFinished();
+            onFlingEnd(false /* cancelled */);
             return;
         }
         mIsFlinging = true;
@@ -717,7 +717,7 @@
         animator.start();
     }
 
-    void onFlingEnd(boolean cancelled) {
+    protected void onFlingEnd(boolean cancelled) {
         mIsFlinging = false;
         // No overshoot when the animation ends
         setOverExpansionInternal(0, false /* isFromGesture */);
@@ -1034,16 +1034,19 @@
         animator.start();
         setAnimator(animator);
 
-        View[] viewsToAnimate = {
-                mKeyguardBottomArea.getIndicationArea(),
-                mCentralSurfaces.getAmbientIndicationContainer()};
-        for (View v : viewsToAnimate) {
-            if (v == null) {
-                continue;
-            }
-            v.animate().translationY(-mHintDistance).setDuration(250).setInterpolator(
-                    Interpolators.FAST_OUT_SLOW_IN).withEndAction(() -> v.animate().translationY(
-                    0).setDuration(450).setInterpolator(mBounceInterpolator).start()).start();
+        final List<ViewPropertyAnimator> indicationAnimators =
+                mKeyguardBottomArea.getIndicationAreaAnimators();
+        for (final ViewPropertyAnimator indicationAreaAnimator : indicationAnimators) {
+            indicationAreaAnimator
+                    .translationY(-mHintDistance)
+                    .setDuration(250)
+                    .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                    .withEndAction(() -> indicationAreaAnimator
+                            .translationY(0)
+                            .setDuration(450)
+                            .setInterpolator(mBounceInterpolator)
+                            .start())
+                    .start();
         }
     }
 
@@ -1110,7 +1113,7 @@
     }
 
     /** Returns true if {@link PanelView} should be visible. */
-    abstract boolean shouldPanelBeVisible();
+    abstract protected boolean shouldPanelBeVisible();
 
     /**
      * Updates the panel expansion and {@link PanelView} visibility if necessary.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
index 2052ee6..15c6dcf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
@@ -31,7 +31,7 @@
 
     private final float mIconAlphaWhenOpaque;
 
-    private View mLeftSide, mStatusIcons, mBattery;
+    private View mStartSide, mStatusIcons, mBattery;
     private Animator mCurrentAnimation;
 
     /**
@@ -41,7 +41,7 @@
         super(backgroundView, R.drawable.status_background);
         final Resources res = statusBarView.getContext().getResources();
         mIconAlphaWhenOpaque = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
-        mLeftSide = statusBarView.findViewById(R.id.status_bar_left_side);
+        mStartSide = statusBarView.findViewById(R.id.status_bar_start_side_except_heads_up);
         mStatusIcons = statusBarView.findViewById(R.id.statusIcons);
         mBattery = statusBarView.findViewById(R.id.battery);
         applyModeBackground(-1, getMode(), false /*animate*/);
@@ -75,7 +75,7 @@
     }
 
     private void applyMode(int mode, boolean animate) {
-        if (mLeftSide == null) return; // pre-init
+        if (mStartSide == null) return; // pre-init
         float newAlpha = getNonBatteryClockAlphaFor(mode);
         float newAlphaBC = getBatteryClockAlpha(mode);
         if (mCurrentAnimation != null) {
@@ -84,7 +84,7 @@
         if (animate) {
             AnimatorSet anims = new AnimatorSet();
             anims.playTogether(
-                    animateTransitionTo(mLeftSide, newAlpha),
+                    animateTransitionTo(mStartSide, newAlpha),
                     animateTransitionTo(mStatusIcons, newAlpha),
                     animateTransitionTo(mBattery, newAlphaBC)
                     );
@@ -94,7 +94,7 @@
             anims.start();
             mCurrentAnimation = anims;
         } else {
-            mLeftSide.setAlpha(newAlpha);
+            mStartSide.setAlpha(newAlpha);
             mStatusIcons.setAlpha(newAlpha);
             mBattery.setAlpha(newAlphaBC);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
index 9da2ef73..f9c4c8f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
@@ -21,7 +21,6 @@
 import android.view.View
 import android.view.ViewGroup
 import android.view.ViewTreeObserver
-
 import com.android.systemui.R
 import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator
 import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherController
@@ -32,9 +31,7 @@
 import com.android.systemui.util.ViewController
 import com.android.systemui.util.kotlin.getOrNull
 import com.android.systemui.util.view.ViewUtil
-
 import java.util.Optional
-
 import javax.inject.Inject
 import javax.inject.Named
 
@@ -58,8 +55,8 @@
     override fun onViewAttached() {
         if (moveFromCenterAnimationController == null) return
 
-        val statusBarLeftSide: View = mView.findViewById(R.id.status_bar_left_side)
-        val systemIconArea: ViewGroup = mView.findViewById(R.id.system_icon_area)
+        val statusBarLeftSide: View = mView.findViewById(R.id.status_bar_start_side_except_heads_up)
+        val systemIconArea: ViewGroup = mView.findViewById(R.id.status_bar_end_side_content)
 
         val viewsToAnimate = arrayOf(
             statusBarLeftSide,
@@ -126,11 +123,11 @@
     class StatusBarViewsCenterProvider : UnfoldMoveFromCenterAnimator.ViewCenterProvider {
         override fun getViewCenter(view: View, outPoint: Point) =
             when (view.id) {
-                R.id.status_bar_left_side -> {
+                R.id.status_bar_start_side_except_heads_up -> {
                     // items aligned to the start, return start center point
                     getViewEdgeCenter(view, outPoint, isStart = true)
                 }
-                R.id.system_icon_area -> {
+                R.id.status_bar_end_side_content -> {
                     // items aligned to the end, return end center point
                     getViewEdgeCenter(view, outPoint, isStart = false)
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 0cf9a53..cb0a148 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -54,6 +54,7 @@
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
 import com.android.systemui.scrim.ScrimView;
+import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.statusbar.notification.stack.ViewState;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -783,7 +784,8 @@
                 mInFrontAlpha = 0;
             }
 
-            if (mBouncerHiddenFraction != KeyguardBouncer.EXPANSION_HIDDEN) {
+            if (mState == ScrimState.DREAMING
+                    && mBouncerHiddenFraction != KeyguardBouncer.EXPANSION_HIDDEN) {
                 final float interpolatedFraction =
                         BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(
                                 mBouncerHiddenFraction);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java
index cee8b33..d37ecbc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java
@@ -23,6 +23,8 @@
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shade.NotificationPanelViewController;
+import com.android.systemui.shade.NotificationShadeWindowView;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java
index 50f2169..ebfbf54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.phone;
 
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.StatusBarState;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
index a94c2b7..7c31366 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static com.android.systemui.statusbar.phone.StatusBarIconList.Slot;
+
 import android.annotation.NonNull;
 import android.content.Context;
 import android.graphics.drawable.Icon;
@@ -56,11 +58,12 @@
  * registered with it.
  */
 @SysUISingleton
-public class StatusBarIconControllerImpl extends StatusBarIconList implements Tunable,
+public class StatusBarIconControllerImpl implements Tunable,
         ConfigurationListener, Dumpable, CommandQueue.Callbacks, StatusBarIconController, DemoMode {
 
     private static final String TAG = "StatusBarIconController";
 
+    private final StatusBarIconList mStatusBarIconList;
     private final ArrayList<IconManager> mIconGroups = new ArrayList<>();
     private final ArraySet<String> mIconHideList = new ArraySet<>();
 
@@ -74,15 +77,12 @@
             DemoModeController demoModeController,
             ConfigurationController configurationController,
             TunerService tunerService,
-            DumpManager dumpManager) {
-        super(context.getResources().getStringArray(
-                com.android.internal.R.array.config_statusBarIcons));
-        configurationController.addCallback(this);
-
+            DumpManager dumpManager,
+            StatusBarIconList statusBarIconList) {
+        mStatusBarIconList = statusBarIconList;
         mContext = context;
 
-        loadDimens();
-
+        configurationController.addCallback(this);
         commandQueue.addCallback(this);
         tunerService.addTunable(this, ICON_HIDE_LIST);
         demoModeController.addCallback(this);
@@ -101,15 +101,14 @@
 
         group.setController(this);
         mIconGroups.add(group);
-        List<Slot> allSlots = getSlots();
+        List<Slot> allSlots = mStatusBarIconList.getSlots();
         for (int i = 0; i < allSlots.size(); i++) {
             Slot slot = allSlots.get(i);
             List<StatusBarIconHolder> holders = slot.getHolderListInViewOrder();
             boolean hidden = mIconHideList.contains(slot.getName());
 
             for (StatusBarIconHolder holder : holders) {
-                int tag = holder.getTag();
-                int viewIndex = getViewIndex(getSlotIndex(slot.getName()), holder.getTag());
+                int viewIndex = mStatusBarIconList.getViewIndex(slot.getName(), holder.getTag());
                 group.onIconAdded(viewIndex, slot.getName(), hidden, holder);
             }
         }
@@ -144,7 +143,7 @@
         }
         mIconHideList.clear();
         mIconHideList.addAll(StatusBarIconController.getIconHideList(mContext, newValue));
-        ArrayList<Slot> currentSlots = getSlots();
+        List<Slot> currentSlots = mStatusBarIconList.getSlots();
         ArrayMap<Slot, List<StatusBarIconHolder>> slotsToReAdd = new ArrayMap<>();
 
         // This is a little hacky... Peel off all of the holders on all of the slots
@@ -163,17 +162,13 @@
             List<StatusBarIconHolder> iconsForSlot = slotsToReAdd.get(item);
             if (iconsForSlot == null) continue;
             for (StatusBarIconHolder holder : iconsForSlot) {
-                setIcon(getSlotIndex(item.getName()), holder);
+                setIcon(item.getName(), holder);
             }
         }
     }
 
-    private void loadDimens() {
-    }
-
-    private void addSystemIcon(int index, StatusBarIconHolder holder) {
-        String slot = getSlotName(index);
-        int viewIndex = getViewIndex(index, holder.getTag());
+    private void addSystemIcon(String slot, StatusBarIconHolder holder) {
+        int viewIndex = mStatusBarIconList.getViewIndex(slot, holder.getTag());
         boolean hidden = mIconHideList.contains(slot);
 
         mIconGroups.forEach(l -> l.onIconAdded(viewIndex, slot, hidden, holder));
@@ -182,18 +177,17 @@
     /** */
     @Override
     public void setIcon(String slot, int resourceId, CharSequence contentDescription) {
-        int index = getSlotIndex(slot);
-        StatusBarIconHolder holder = getIcon(index, 0);
+        StatusBarIconHolder holder = mStatusBarIconList.getIconHolder(slot, 0);
         if (holder == null) {
             StatusBarIcon icon = new StatusBarIcon(UserHandle.SYSTEM, mContext.getPackageName(),
                     Icon.createWithResource(
                             mContext, resourceId), 0, 0, contentDescription);
             holder = StatusBarIconHolder.fromIcon(icon);
-            setIcon(index, holder);
+            setIcon(slot, holder);
         } else {
             holder.getIcon().icon = Icon.createWithResource(mContext, resourceId);
             holder.getIcon().contentDescription = contentDescription;
-            handleSet(index, holder);
+            handleSet(slot, holder);
         }
     }
 
@@ -203,21 +197,18 @@
      */
     @Override
     public void setSignalIcon(String slot, WifiIconState state) {
-
-        int index = getSlotIndex(slot);
-
         if (state == null) {
-            removeIcon(index, 0);
+            removeIcon(slot, 0);
             return;
         }
 
-        StatusBarIconHolder holder = getIcon(index, 0);
+        StatusBarIconHolder holder = mStatusBarIconList.getIconHolder(slot, 0);
         if (holder == null) {
             holder = StatusBarIconHolder.fromWifiIconState(state);
-            setIcon(index, holder);
+            setIcon(slot, holder);
         } else {
             holder.setWifiState(state);
-            handleSet(index, holder);
+            handleSet(slot, holder);
         }
     }
 
@@ -229,8 +220,7 @@
      */
     @Override
     public void setMobileIcons(String slot, List<MobileIconState> iconStates) {
-        Slot mobileSlot = getSlot(slot);
-        int slotIndex = getSlotIndex(slot);
+        Slot mobileSlot = mStatusBarIconList.getSlot(slot);
 
         // Reverse the sort order to show icons with left to right([Slot1][Slot2]..).
         // StatusBarIconList has UI design that first items go to the right of second items.
@@ -241,10 +231,10 @@
             StatusBarIconHolder holder = mobileSlot.getHolderForTag(state.subId);
             if (holder == null) {
                 holder = StatusBarIconHolder.fromMobileIconState(state);
-                setIcon(slotIndex, holder);
+                setIcon(slot, holder);
             } else {
                 holder.setMobileState(state);
-                handleSet(slotIndex, holder);
+                handleSet(slot, holder);
             }
         }
     }
@@ -256,21 +246,19 @@
      */
     @Override
     public void setCallStrengthIcons(String slot, List<CallIndicatorIconState> states) {
-        Slot callStrengthSlot = getSlot(slot);
-        int callStrengthSlotIndex = getSlotIndex(slot);
+        Slot callStrengthSlot = mStatusBarIconList.getSlot(slot);
         Collections.reverse(states);
         for (CallIndicatorIconState state : states) {
             if (!state.isNoCalling) {
                 StatusBarIconHolder holder = callStrengthSlot.getHolderForTag(state.subId);
                 if (holder == null) {
                     holder = StatusBarIconHolder.fromCallIndicatorState(mContext, state);
-                    setIcon(callStrengthSlotIndex, holder);
                 } else {
                     holder.setIcon(new StatusBarIcon(UserHandle.SYSTEM, mContext.getPackageName(),
                             Icon.createWithResource(mContext, state.callStrengthResId), 0, 0,
                             state.callStrengthDescription));
-                    setIcon(callStrengthSlotIndex, holder);
                 }
+                setIcon(slot, holder);
             }
             setIconVisibility(slot, !state.isNoCalling, state.subId);
         }
@@ -283,21 +271,19 @@
      */
     @Override
     public void setNoCallingIcons(String slot, List<CallIndicatorIconState> states) {
-        Slot noCallingSlot = getSlot(slot);
-        int noCallingSlotIndex = getSlotIndex(slot);
+        Slot noCallingSlot = mStatusBarIconList.getSlot(slot);
         Collections.reverse(states);
         for (CallIndicatorIconState state : states) {
             if (state.isNoCalling) {
                 StatusBarIconHolder holder = noCallingSlot.getHolderForTag(state.subId);
                 if (holder == null) {
                     holder = StatusBarIconHolder.fromCallIndicatorState(mContext, state);
-                    setIcon(noCallingSlotIndex, holder);
                 } else {
                     holder.setIcon(new StatusBarIcon(UserHandle.SYSTEM, mContext.getPackageName(),
                             Icon.createWithResource(mContext, state.noCallingResId), 0, 0,
                             state.noCallingDescription));
-                    setIcon(noCallingSlotIndex, holder);
                 }
+                setIcon(slot, holder);
             }
             setIconVisibility(slot, state.isNoCalling, state.subId);
         }
@@ -305,42 +291,31 @@
 
     @Override
     public void setExternalIcon(String slot) {
-        int viewIndex = getViewIndex(getSlotIndex(slot), 0);
+        int viewIndex = mStatusBarIconList.getViewIndex(slot, 0);
         int height = mContext.getResources().getDimensionPixelSize(
                 R.dimen.status_bar_icon_drawing_size);
         mIconGroups.forEach(l -> l.onIconExternal(viewIndex, height));
     }
 
     //TODO: remove this (used in command queue and for 3rd party tiles?)
-    @Override
     public void setIcon(String slot, StatusBarIcon icon) {
-        setIcon(getSlotIndex(slot), icon);
-    }
-
-    /**
-     * For backwards compatibility, in the event that someone gives us a slot and a status bar icon
-     */
-    private void setIcon(int index, StatusBarIcon icon) {
-        String slot = getSlotName(index);
         if (icon == null) {
             removeAllIconsForSlot(slot);
             return;
         }
 
         StatusBarIconHolder holder = StatusBarIconHolder.fromIcon(icon);
-        setIcon(index, holder);
+        setIcon(slot, holder);
     }
 
-    /** */
-    @Override
-    public void setIcon(int index, @NonNull StatusBarIconHolder holder) {
-        boolean isNew = getIcon(index, holder.getTag()) == null;
-        super.setIcon(index, holder);
+    private void setIcon(String slot, @NonNull StatusBarIconHolder holder) {
+        boolean isNew = mStatusBarIconList.getIconHolder(slot, holder.getTag()) == null;
+        mStatusBarIconList.setIcon(slot, holder);
 
         if (isNew) {
-            addSystemIcon(index, holder);
+            addSystemIcon(slot, holder);
         } else {
-            handleSet(index, holder);
+            handleSet(slot, holder);
         }
     }
 
@@ -351,34 +326,33 @@
 
     /** */
     public void setIconVisibility(String slot, boolean visibility, int tag) {
-        int index = getSlotIndex(slot);
-        StatusBarIconHolder holder = getIcon(index, tag);
+        StatusBarIconHolder holder = mStatusBarIconList.getIconHolder(slot, tag);
         if (holder == null || holder.isVisible() == visibility) {
             return;
         }
 
         holder.setVisible(visibility);
-        handleSet(index, holder);
+        handleSet(slot, holder);
     }
 
     /** */
     @Override
     public void setIconAccessibilityLiveRegion(String slotName, int accessibilityLiveRegion) {
-        Slot slot = getSlot(slotName);
+        Slot slot = mStatusBarIconList.getSlot(slotName);
         if (!slot.hasIconsInSlot()) {
             return;
         }
 
-        int slotIndex = getSlotIndex(slotName);
         List<StatusBarIconHolder> iconsToUpdate = slot.getHolderListInViewOrder();
         for (StatusBarIconHolder holder : iconsToUpdate) {
-            int viewIndex = getViewIndex(slotIndex, holder.getTag());
+            int viewIndex = mStatusBarIconList.getViewIndex(slotName, holder.getTag());
             mIconGroups.forEach(l -> l.mGroup.getChildAt(viewIndex)
                     .setAccessibilityLiveRegion(accessibilityLiveRegion));
         }
     }
 
     /** */
+    @Override
     public void removeIcon(String slot) {
         removeAllIconsForSlot(slot);
     }
@@ -386,39 +360,34 @@
     /** */
     @Override
     public void removeIcon(String slot, int tag) {
-        removeIcon(getSlotIndex(slot), tag);
+        if (mStatusBarIconList.getIconHolder(slot, tag) == null) {
+            return;
+        }
+        int viewIndex = mStatusBarIconList.getViewIndex(slot, tag);
+        mStatusBarIconList.removeIcon(slot, tag);
+        mIconGroups.forEach(l -> l.onRemoveIcon(viewIndex));
     }
 
     /** */
     @Override
     public void removeAllIconsForSlot(String slotName) {
-        Slot slot = getSlot(slotName);
+        Slot slot = mStatusBarIconList.getSlot(slotName);
         if (!slot.hasIconsInSlot()) {
             return;
         }
 
-        int slotIndex = getSlotIndex(slotName);
         List<StatusBarIconHolder> iconsToRemove = slot.getHolderListInViewOrder();
         for (StatusBarIconHolder holder : iconsToRemove) {
-            int viewIndex = getViewIndex(slotIndex, holder.getTag());
+            int viewIndex = mStatusBarIconList.getViewIndex(slotName, holder.getTag());
             slot.removeForTag(holder.getTag());
             mIconGroups.forEach(l -> l.onRemoveIcon(viewIndex));
         }
     }
 
-    /** */
-    @Override
-    public void removeIcon(int index, int tag) {
-        if (getIcon(index, tag) == null) {
-            return;
-        }
-        super.removeIcon(index, tag);
-        int viewIndex = getViewIndex(index, 0);
-        mIconGroups.forEach(l -> l.onRemoveIcon(viewIndex));
-    }
 
-    private void handleSet(int index, StatusBarIconHolder holder) {
-        int viewIndex = getViewIndex(index, holder.getTag());
+
+    private void handleSet(String slotName, StatusBarIconHolder holder) {
+        int viewIndex = mStatusBarIconList.getViewIndex(slotName, holder.getTag());
         mIconGroups.forEach(l -> l.onSetIconHolder(viewIndex, holder));
     }
 
@@ -438,7 +407,7 @@
             }
         }
 
-        super.dump(pw);
+        mStatusBarIconList.dump(pw);
     }
 
     /** */
@@ -482,7 +451,6 @@
     /** */
     @Override
     public void onDensityOrFontScaleChanged() {
-        loadDimens();
         refreshIconGroups();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
index c876c32..8800b05 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
@@ -25,60 +25,72 @@
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
+/** A class holding the list of all the system icons that could be shown in the status bar. */
 public class StatusBarIconList {
-    private ArrayList<Slot> mSlots = new ArrayList<>();
+    private final ArrayList<Slot> mSlots = new ArrayList<>();
+    private final List<Slot> mViewOnlySlots = Collections.unmodifiableList(mSlots);
 
     public StatusBarIconList(String[] slots) {
         final int N = slots.length;
-        for (int i=0; i < N; i++) {
+        for (int i = 0; i < N; i++) {
             mSlots.add(new Slot(slots[i], null));
         }
     }
 
-    public int getSlotIndex(String slot) {
-        final int N = mSlots.size();
-        for (int i=0; i<N; i++) {
-            Slot item = mSlots.get(i);
-            if (item.getName().equals(slot)) {
-                return i;
-            }
-        }
-        // Auto insert new items at the beginning.
-        mSlots.add(0, new Slot(slot, null));
-        return 0;
+    /** Returns the list of current slots. */
+    public List<Slot> getSlots() {
+        return mViewOnlySlots;
     }
 
-    protected ArrayList<Slot> getSlots() {
-        return new ArrayList<>(mSlots);
+    /**
+     * Gets the slot with the given {@code name}, or creates a new slot if we don't already have a
+     * slot by that name.
+     *
+     * If a new slot is created, that slot will be inserted at the front of the list.
+     *
+     * TODO(b/237533036): Rename this to getOrCreateSlot to make it more clear that it could create
+     *   a new slot. Other methods in this class will also create a new slot if we don't have one,
+     *   should those be re-named too?
+     */
+    public Slot getSlot(String name) {
+        return mSlots.get(findOrInsertSlot(name));
     }
 
-    protected Slot getSlot(String name) {
-        return mSlots.get(getSlotIndex(name));
+    /**
+     * Sets the icon in {@code holder} to be associated with the slot with the given
+     * {@code slotName}.
+     */
+    public void setIcon(String slotName, @NonNull StatusBarIconHolder holder) {
+        mSlots.get(findOrInsertSlot(slotName)).addHolder(holder);
     }
 
-    public int size() {
-        return mSlots.size();
+    /**
+     * Removes the icon holder that we had associated with {@code slotName}'s slot at the given
+     * {@code tag}.
+     */
+    public void removeIcon(String slotName, int tag) {
+        mSlots.get(findOrInsertSlot(slotName)).removeForTag(tag);
     }
 
-    public void setIcon(int index, @NonNull StatusBarIconHolder holder) {
-        mSlots.get(index).addHolder(holder);
+    /**
+     * Returns the icon holder currently associated with {@code slotName}'s slot at the given
+     * {@code tag}, or null if we don't have one.
+     */
+    @Nullable
+    public StatusBarIconHolder getIconHolder(String slotName, int tag) {
+        return mSlots.get(findOrInsertSlot(slotName)).getHolderForTag(tag);
     }
 
-    public void removeIcon(int index, int tag) {
-        mSlots.get(index).removeForTag(tag);
-    }
-
-    public String getSlotName(int index) {
-        return mSlots.get(index).getName();
-    }
-
-    public StatusBarIconHolder getIcon(int index, int tag) {
-        return mSlots.get(index).getHolderForTag(tag);
-    }
-
-    public int getViewIndex(int slotIndex, int tag) {
+    /**
+     * Returns the index of the icon in {@code slotName}'s slot at the given {@code tag}.
+     *
+     * Note that a single slot can have multiple icons, and this function takes that into account.
+     */
+    public int getViewIndex(String slotName, int tag) {
+        int slotIndex = findOrInsertSlot(slotName);
         int count = 0;
         for (int i = 0; i < slotIndex; i++) {
             Slot item = mSlots.get(i);
@@ -100,6 +112,25 @@
         }
     }
 
+    private int findOrInsertSlot(String slot) {
+        final int N = mSlots.size();
+        for (int i = 0; i < N; i++) {
+            Slot item = mSlots.get(i);
+            if (item.getName().equals(slot)) {
+                return i;
+            }
+        }
+        // Auto insert new items at the beginning.
+        mSlots.add(0, new Slot(slot, null));
+        return 0;
+    }
+
+
+    /**
+     * A class representing one slot in the status bar system icons view.
+     *
+     * Note that one slot can have multiple icons associated with it.
+     */
     public static class Slot {
         private final String mName;
         private StatusBarIconHolder mHolder;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index c90383f..2a2529a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -55,6 +55,7 @@
 import com.android.systemui.navigationbar.NavigationBarView;
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.shared.system.SysUiStatsLog;
 import com.android.systemui.statusbar.NotificationMediaManager;
@@ -129,8 +130,6 @@
         public void onFullyShown() {
             mBouncerAnimating = false;
             updateStates();
-            mCentralSurfaces.wakeUpIfDozing(SystemClock.uptimeMillis(),
-                    mCentralSurfaces.getBouncerContainer(), "BOUNCER_VISIBLE");
         }
 
         @Override
@@ -966,7 +965,7 @@
 
     @Override
     public boolean bouncerIsOrWillBeShowing() {
-        return isBouncerShowing() || mBouncer.getShowingSoon();
+        return isBouncerShowing() || mBouncer.inTransit();
     }
 
     public boolean isFullscreenBouncer() {
@@ -1042,7 +1041,6 @@
         }
 
         if (occluded != mLastOccluded || mFirstUpdate) {
-            mKeyguardUpdateManager.onKeyguardOccludedChanged(occluded);
             mKeyguardStateController.notifyKeyguardState(showing, occluded);
         }
         if ((showing && !occluded) != (mLastShowing && !mLastOccluded) || mFirstUpdate) {
@@ -1071,11 +1069,6 @@
         mCentralSurfaces.onKeyguardViewManagerStatesUpdated();
     }
 
-    private View getCurrentNavBarView() {
-        final NavigationBarView navBarView = mCentralSurfaces.getNavigationBarView();
-        return navBarView != null ? navBarView.getCurrentView() : null;
-    }
-
     /**
      * Updates the visibility of the nav bar window (which will cause insets changes).
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index cf776e3..451612a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -52,21 +52,16 @@
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.statusbar.NotificationClickNotifier;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
-import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.NotificationActivityStarter;
-import com.android.systemui.statusbar.notification.NotificationEntryListener;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
-import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -92,24 +87,19 @@
 
     private final Context mContext;
 
-    private final CommandQueue mCommandQueue;
     private final Handler mMainThreadHandler;
     private final Executor mUiBgExecutor;
 
-    private final NotificationEntryManager mEntryManager;
-    private final NotifPipeline mNotifPipeline;
     private final NotificationVisibilityProvider mVisibilityProvider;
     private final HeadsUpManagerPhone mHeadsUpManager;
     private final ActivityStarter mActivityStarter;
     private final NotificationClickNotifier mClickNotifier;
-    private final StatusBarStateController mStatusBarStateController;
     private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private final KeyguardManager mKeyguardManager;
     private final IDreamManager mDreamManager;
     private final Optional<BubblesManager> mBubblesManagerOptional;
     private final Lazy<AssistManager> mAssistManagerLazy;
     private final NotificationRemoteInputManager mRemoteInputManager;
-    private final GroupMembershipManager mGroupMembershipManager;
     private final NotificationLockscreenUserManager mLockscreenUserManager;
     private final ShadeController mShadeController;
     private final KeyguardStateController mKeyguardStateController;
@@ -118,7 +108,6 @@
     private final StatusBarRemoteInputCallback mStatusBarRemoteInputCallback;
     private final ActivityIntentHelper mActivityIntentHelper;
 
-    private final NotifPipelineFlags mNotifPipelineFlags;
     private final MetricsLogger mMetricsLogger;
     private final StatusBarNotificationActivityStarterLogger mLogger;
 
@@ -134,23 +123,19 @@
     @Inject
     StatusBarNotificationActivityStarter(
             Context context,
-            CommandQueue commandQueue,
             Handler mainThreadHandler,
             Executor uiBgExecutor,
-            NotificationEntryManager entryManager,
             NotifPipeline notifPipeline,
             NotificationVisibilityProvider visibilityProvider,
             HeadsUpManagerPhone headsUpManager,
             ActivityStarter activityStarter,
             NotificationClickNotifier clickNotifier,
-            StatusBarStateController statusBarStateController,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
             KeyguardManager keyguardManager,
             IDreamManager dreamManager,
             Optional<BubblesManager> bubblesManagerOptional,
             Lazy<AssistManager> assistManagerLazy,
             NotificationRemoteInputManager remoteInputManager,
-            GroupMembershipManager groupMembershipManager,
             NotificationLockscreenUserManager lockscreenUserManager,
             ShadeController shadeController,
             KeyguardStateController keyguardStateController,
@@ -158,7 +143,6 @@
             LockPatternUtils lockPatternUtils,
             StatusBarRemoteInputCallback remoteInputCallback,
             ActivityIntentHelper activityIntentHelper,
-            NotifPipelineFlags notifPipelineFlags,
             MetricsLogger metricsLogger,
             StatusBarNotificationActivityStarterLogger logger,
             OnUserInteractionCallback onUserInteractionCallback,
@@ -168,23 +152,18 @@
             ActivityLaunchAnimator activityLaunchAnimator,
             NotificationLaunchAnimatorControllerProvider notificationAnimationProvider) {
         mContext = context;
-        mCommandQueue = commandQueue;
         mMainThreadHandler = mainThreadHandler;
         mUiBgExecutor = uiBgExecutor;
-        mEntryManager = entryManager;
-        mNotifPipeline = notifPipeline;
         mVisibilityProvider = visibilityProvider;
         mHeadsUpManager = headsUpManager;
         mActivityStarter = activityStarter;
         mClickNotifier = clickNotifier;
-        mStatusBarStateController = statusBarStateController;
         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
         mKeyguardManager = keyguardManager;
         mDreamManager = dreamManager;
         mBubblesManagerOptional = bubblesManagerOptional;
         mAssistManagerLazy = assistManagerLazy;
         mRemoteInputManager = remoteInputManager;
-        mGroupMembershipManager = groupMembershipManager;
         mLockscreenUserManager = lockscreenUserManager;
         mShadeController = shadeController;
         mKeyguardStateController = keyguardStateController;
@@ -192,7 +171,6 @@
         mLockPatternUtils = lockPatternUtils;
         mStatusBarRemoteInputCallback = remoteInputCallback;
         mActivityIntentHelper = activityIntentHelper;
-        mNotifPipelineFlags = notifPipelineFlags;
         mMetricsLogger = metricsLogger;
         mLogger = logger;
         mOnUserInteractionCallback = onUserInteractionCallback;
@@ -203,21 +181,12 @@
         mActivityLaunchAnimator = activityLaunchAnimator;
         mNotificationAnimationProvider = notificationAnimationProvider;
 
-        if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
-            mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
-                @Override
-                public void onPendingEntryAdded(NotificationEntry entry) {
-                    handleFullScreenIntent(entry);
-                }
-            });
-        } else {
-            mNotifPipeline.addCollectionListener(new NotifCollectionListener() {
-                @Override
-                public void onEntryAdded(NotificationEntry entry) {
-                    handleFullScreenIntent(entry);
-                }
-            });
-        }
+        notifPipeline.addCollectionListener(new NotifCollectionListener() {
+            @Override
+            public void onEntryAdded(NotificationEntry entry) {
+                handleFullScreenIntent(entry);
+            }
+        });
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index 55b7e7b..a637161 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -30,19 +30,17 @@
 import android.util.Slog;
 import android.view.View;
 import android.view.accessibility.AccessibilityManager;
-import android.widget.TextView;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.statusbar.IStatusBarService;
-import com.android.internal.widget.MessagingGroup;
-import com.android.internal.widget.MessagingMessage;
-import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.Dependency;
 import com.android.systemui.ForegroundServiceNotificationListener;
 import com.android.systemui.InitController;
 import com.android.systemui.R;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
+import com.android.systemui.shade.NotificationPanelViewController;
+import com.android.systemui.shade.NotificationShadeWindowView;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
@@ -56,7 +54,6 @@
 import com.android.systemui.statusbar.notification.AboveShelfObserver;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
 import com.android.systemui.statusbar.notification.NotifPipelineFlags;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
 import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
@@ -71,16 +68,12 @@
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
 import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent;
 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
-import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
-import java.util.List;
-
 import javax.inject.Inject;
 
 @CentralSurfacesComponent.CentralSurfacesScope
 class StatusBarNotificationPresenter implements NotificationPresenter,
-        ConfigurationController.ConfigurationListener,
         NotificationRowBinderImpl.BindRowCallback,
         CommandQueue.Callbacks {
     private static final String TAG = "StatusBarNotificationPresenter";
@@ -90,10 +83,8 @@
     private final NotificationLockscreenUserManager mLockscreenUserManager;
     private final SysuiStatusBarStateController mStatusBarStateController;
     private final NotifShadeEventSource mNotifShadeEventSource;
-    private final NotificationEntryManager mEntryManager;
     private final NotificationMediaManager mMediaManager;
     private final NotificationGutsManager mGutsManager;
-    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private final LockscreenGestureLogger mLockscreenGestureLogger;
 
     private final NotificationPanelViewController mNotificationPanel;
@@ -114,9 +105,6 @@
     private final IStatusBarService mBarService;
     private final DynamicPrivacyController mDynamicPrivacyController;
     private final NotificationListContainer mNotifListContainer;
-    private boolean mReinflateNotificationsOnUserSwitched;
-    private boolean mDispatchUiModeChangeOnUserSwitched;
-    private TextView mNotificationPanelDebugText;
 
     protected boolean mVrMode;
 
@@ -140,15 +128,12 @@
             NotificationLockscreenUserManager lockscreenUserManager,
             SysuiStatusBarStateController sysuiStatusBarStateController,
             NotifShadeEventSource notifShadeEventSource,
-            NotificationEntryManager notificationEntryManager,
             NotificationMediaManager notificationMediaManager,
             NotificationGutsManager notificationGutsManager,
-            KeyguardUpdateMonitor keyguardUpdateMonitor,
             LockscreenGestureLogger lockscreenGestureLogger,
             InitController initController,
             NotificationInterruptStateProvider notificationInterruptStateProvider,
             NotificationRemoteInputManager remoteInputManager,
-            ConfigurationController configurationController,
             NotifPipelineFlags notifPipelineFlags,
             NotificationRemoteInputManager.Callback remoteInputManagerCallback,
             NotificationListContainer notificationListContainer) {
@@ -166,10 +151,8 @@
         mLockscreenUserManager = lockscreenUserManager;
         mStatusBarStateController = sysuiStatusBarStateController;
         mNotifShadeEventSource = notifShadeEventSource;
-        mEntryManager = notificationEntryManager;
         mMediaManager = notificationMediaManager;
         mGutsManager = notificationGutsManager;
-        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mLockscreenGestureLogger = lockscreenGestureLogger;
         mAboveShelfObserver = new AboveShelfObserver(stackScrollerController.getView());
         mNotificationShadeWindowController = notificationShadeWindowController;
@@ -212,7 +195,6 @@
 
             onUserSwitched(mLockscreenUserManager.getCurrentUserId());
         });
-        configurationController.addCallback(this);
     }
 
     /** Called when the shade has been emptied to attempt to close the shade */
@@ -227,65 +209,6 @@
     }
 
     @Override
-    public void onDensityOrFontScaleChanged() {
-        // TODO(b/145659174): Remove legacy pipeline code
-        if (mNotifPipelineFlags.isNewPipelineEnabled()) return;
-        MessagingMessage.dropCache();
-        MessagingGroup.dropCache();
-        if (!mKeyguardUpdateMonitor.isSwitchingUser()) {
-            updateNotificationsOnDensityOrFontScaleChanged();
-        } else {
-            mReinflateNotificationsOnUserSwitched = true;
-        }
-    }
-
-    @Override
-    public void onUiModeChanged() {
-        // TODO(b/145659174): Remove legacy pipeline code
-        if (mNotifPipelineFlags.isNewPipelineEnabled()) return;
-        if (!mKeyguardUpdateMonitor.isSwitchingUser()) {
-            updateNotificationsOnUiModeChanged();
-        } else {
-            mDispatchUiModeChangeOnUserSwitched = true;
-        }
-    }
-
-    @Override
-    public void onThemeChanged() {
-        onDensityOrFontScaleChanged();
-    }
-
-    private void updateNotificationsOnUiModeChanged() {
-        // TODO(b/145659174): Remove legacy pipeline code
-        if (mNotifPipelineFlags.isNewPipelineEnabled()) return;
-        List<NotificationEntry> userNotifications =
-                mEntryManager.getActiveNotificationsForCurrentUser();
-        for (int i = 0; i < userNotifications.size(); i++) {
-            NotificationEntry entry = userNotifications.get(i);
-            ExpandableNotificationRow row = entry.getRow();
-            if (row != null) {
-                row.onUiModeChanged();
-            }
-        }
-    }
-
-    private void updateNotificationsOnDensityOrFontScaleChanged() {
-        // TODO(b/145659174): Remove legacy pipeline code
-        if (mNotifPipelineFlags.isNewPipelineEnabled()) return;
-        List<NotificationEntry> userNotifications =
-                mEntryManager.getActiveNotificationsForCurrentUser();
-        for (int i = 0; i < userNotifications.size(); i++) {
-            NotificationEntry entry = userNotifications.get(i);
-            entry.onDensityOrFontScaleChanged();
-            boolean exposedGuts = entry.areGutsExposed();
-            if (exposedGuts) {
-                mGutsManager.onDensityOrFontScaleChanged(entry);
-            }
-        }
-    }
-
-
-    @Override
     public boolean isCollapsing() {
         return mNotificationPanel.isCollapsing()
                 || mNotificationShadeWindowController.isLaunchingActivity();
@@ -324,17 +247,6 @@
         // End old BaseStatusBar.userSwitched
         if (MULTIUSER_DEBUG) mNotificationPanel.setHeaderDebugInfo("USER " + newUserId);
         mCommandQueue.animateCollapsePanels();
-        if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
-            if (mReinflateNotificationsOnUserSwitched) {
-                updateNotificationsOnDensityOrFontScaleChanged();
-                mReinflateNotificationsOnUserSwitched = false;
-            }
-            if (mDispatchUiModeChangeOnUserSwitched) {
-                updateNotificationsOnUiModeChanged();
-                mDispatchUiModeChangeOnUserSwitched = false;
-            }
-            updateNotificationViews("user switched");
-        }
         mMediaManager.clearCurrentMediaNotification();
         mCentralSurfaces.setLockscreenUser(newUserId);
         updateMediaMetaData(true, false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
index 4e90900..75dac1a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
@@ -136,8 +136,9 @@
      * Notify that the status bar panel gets expanded or collapsed.
      *
      * @param isExpanded True to notify expanded, false to notify collapsed.
+     * TODO(b/237811427) replace with a listener
      */
-    void setPanelExpanded(boolean isExpanded) {
+    public void setPanelExpanded(boolean isExpanded) {
         if (isExpanded != mIsStatusBarExpanded) {
             mIsStatusBarExpanded = isExpanded;
             if (isExpanded) {
@@ -153,7 +154,7 @@
      * any existing display cutouts (notch)
      * @return the heads up notification touch area
      */
-    Region calculateTouchableRegion() {
+    public Region calculateTouchableRegion() {
         // Update touchable region for HeadsUp notifications
         final Region headsUpTouchableRegion = mHeadsUpManager.getTouchableRegion();
         if (headsUpTouchableRegion != null) {
@@ -222,7 +223,7 @@
         }
     }
 
-    void updateRegionForNotch(Region touchableRegion) {
+    public void updateRegionForNotch(Region touchableRegion) {
         WindowInsets windowInsets = mNotificationShadeWindowView.getRootWindowInsets();
         if (windowInsets == null) {
             Log.w(TAG, "StatusBarWindowView is not attached.");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
index c5e5297..84b2797 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
@@ -22,6 +22,9 @@
 
 import com.android.keyguard.LockIconViewController;
 import com.android.systemui.biometrics.AuthRippleController;
+import com.android.systemui.shade.NotificationPanelViewController;
+import com.android.systemui.shade.NotificationShadeWindowView;
+import com.android.systemui.shade.NotificationShadeWindowViewController;
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.NotificationShelfController;
 import com.android.systemui.statusbar.core.StatusBarInitializer;
@@ -33,9 +36,6 @@
 import com.android.systemui.statusbar.phone.CentralSurfacesCommandQueueCallbacks;
 import com.android.systemui.statusbar.phone.CentralSurfacesImpl;
 import com.android.systemui.statusbar.phone.LargeScreenShadeHeaderController;
-import com.android.systemui.statusbar.phone.NotificationPanelViewController;
-import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
-import com.android.systemui.statusbar.phone.NotificationShadeWindowViewController;
 import com.android.systemui.statusbar.phone.StatusBarHeadsUpChangeListener;
 import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarterModule;
 import com.android.systemui.statusbar.phone.StatusBarNotificationPresenterModule;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
index 449bac6..5013736 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
@@ -34,6 +34,10 @@
 import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.privacy.OngoingPrivacyChip;
+import com.android.systemui.shade.NotificationPanelView;
+import com.android.systemui.shade.NotificationPanelViewController;
+import com.android.systemui.shade.NotificationShadeWindowView;
+import com.android.systemui.shade.NotificationsQuickSettingsContainer;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.NotificationShelfController;
@@ -43,10 +47,6 @@
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
 import com.android.systemui.statusbar.phone.NotificationIconAreaController;
-import com.android.systemui.statusbar.phone.NotificationPanelView;
-import com.android.systemui.statusbar.phone.NotificationPanelViewController;
-import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
-import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
 import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarLocationPublisher;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
index 25892d9..8332f99 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
@@ -47,6 +47,7 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.DisableFlagsLogger.DisableState;
 import com.android.systemui.statusbar.OperatorNameView;
@@ -55,7 +56,6 @@
 import com.android.systemui.statusbar.events.SystemStatusAnimationCallback;
 import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
 import com.android.systemui.statusbar.phone.NotificationIconAreaController;
-import com.android.systemui.statusbar.phone.NotificationPanelViewController;
 import com.android.systemui.statusbar.phone.PhoneStatusBarView;
 import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
@@ -96,7 +96,7 @@
     private final StatusBarStateController mStatusBarStateController;
     private final KeyguardStateController mKeyguardStateController;
     private final NotificationPanelViewController mNotificationPanelViewController;
-    private LinearLayout mSystemIconArea;
+    private LinearLayout mEndSideContent;
     private View mClockView;
     private View mOngoingCallChip;
     private View mNotificationIconAreaInner;
@@ -217,15 +217,15 @@
         mDarkIconManager.setShouldLog(true);
         updateBlockedIcons();
         mStatusBarIconController.addIconGroup(mDarkIconManager);
-        mSystemIconArea = mStatusBar.findViewById(R.id.system_icon_area);
+        mEndSideContent = mStatusBar.findViewById(R.id.status_bar_end_side_content);
         mClockView = mStatusBar.findViewById(R.id.clock);
         mOngoingCallChip = mStatusBar.findViewById(R.id.ongoing_call_chip);
-        showSystemIconArea(false);
+        showEndSideContent(false);
         showClock(false);
         initOperatorName();
         initNotificationIconArea();
         mSystemEventAnimator =
-                new StatusBarSystemEventAnimator(mSystemIconArea, getResources());
+                new StatusBarSystemEventAnimator(mEndSideContent, getResources());
         mCarrierConfigTracker.addCallback(mCarrierConfigCallback);
         mCarrierConfigTracker.addDefaultDataSubscriptionChangedListener(mDefaultDataListener);
     }
@@ -351,10 +351,10 @@
         mDisabled2 = state2;
         if ((diff1 & DISABLE_SYSTEM_INFO) != 0 || ((diff2 & DISABLE2_SYSTEM_ICONS) != 0)) {
             if ((state1 & DISABLE_SYSTEM_INFO) != 0 || ((state2 & DISABLE2_SYSTEM_ICONS) != 0)) {
-                hideSystemIconArea(animate);
+                hideEndSideContent(animate);
                 hideOperatorName(animate);
             } else {
-                showSystemIconArea(animate);
+                showEndSideContent(animate);
                 showOperatorName(animate);
             }
         }
@@ -438,15 +438,15 @@
         return mStatusBarHideIconsForBouncerManager.getShouldHideStatusBarIconsForBouncer();
     }
 
-    private void hideSystemIconArea(boolean animate) {
-        animateHide(mSystemIconArea, animate);
+    private void hideEndSideContent(boolean animate) {
+        animateHide(mEndSideContent, animate);
     }
 
-    private void showSystemIconArea(boolean animate) {
+    private void showEndSideContent(boolean animate) {
         // Only show the system icon area if we are not currently animating
         int state = mAnimationScheduler.getAnimationState();
         if (state == IDLE || state == SHOWING_PERSISTENT_DOT) {
-            animateShow(mSystemIconArea, animate);
+            animateShow(mEndSideContent, animate);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java
index d5f5362..7252dfb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java
@@ -21,8 +21,8 @@
 import com.android.systemui.R;
 import com.android.systemui.battery.BatteryMeterView;
 import com.android.systemui.dagger.qualifiers.RootView;
+import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.statusbar.HeadsUpStatusBarView;
-import com.android.systemui.statusbar.phone.NotificationPanelViewController;
 import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions;
 import com.android.systemui.statusbar.phone.PhoneStatusBarView;
 import com.android.systemui.statusbar.phone.PhoneStatusBarViewController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
index 5bd20ff..337ffdf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -28,9 +28,9 @@
 import com.android.systemui.R;
 import com.android.systemui.settings.brightness.BrightnessSliderController;
 import com.android.systemui.settings.brightness.ToggleSlider;
+import com.android.systemui.shade.NotificationPanelViewController;
+import com.android.systemui.shade.NotificationShadeWindowView;
 import com.android.systemui.statusbar.NotificationShadeDepthController;
-import com.android.systemui.statusbar.phone.NotificationPanelViewController;
-import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
 
 import java.util.Objects;
 import java.util.function.Consumer;
@@ -68,6 +68,7 @@
             mBrightnessMirror.setVisibility(View.INVISIBLE);
         });
         mVisibilityCallback = visibilityCallback;
+        updateResources();
     }
 
     public void showMirror() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
index 2fb16ee..bdac888 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
@@ -424,11 +424,6 @@
         }
 
         @Override
-        public void onFaceUnlockStateChanged(boolean running, int userId) {
-            update(false /* updateAlways */);
-        }
-
-        @Override
         public void onStrongAuthStateChanged(int userId) {
             update(false /* updateAlways */);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 6af8e9e..2e66648 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -68,6 +68,7 @@
 import com.android.systemui.GuestResumeSessionReceiver;
 import com.android.systemui.R;
 import com.android.systemui.SystemUISecondaryUserService;
+import com.android.systemui.animation.DialogCuj;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.broadcast.BroadcastSender;
@@ -116,6 +117,9 @@
     private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
     private static final long MULTI_USER_JOURNEY_TIMEOUT = 20000l;
 
+    private static final String INTERACTION_JANK_ADD_NEW_USER_TAG = "add_new_user";
+    private static final String INTERACTION_JANK_EXIT_GUEST_MODE_TAG = "exit_guest_mode";
+
     protected final Context mContext;
     protected final UserTracker mUserTracker;
     protected final UserManager mUserManager;
@@ -597,7 +601,9 @@
         }
         mExitGuestDialog = new ExitGuestDialog(mContext, id, isGuestEphemeral, targetId);
         if (dialogShower != null) {
-            dialogShower.showDialog(mExitGuestDialog);
+            dialogShower.showDialog(mExitGuestDialog, new DialogCuj(
+                    InteractionJankMonitor.CUJ_USER_DIALOG_OPEN,
+                    INTERACTION_JANK_EXIT_GUEST_MODE_TAG));
         } else {
             mExitGuestDialog.show();
         }
@@ -609,7 +615,11 @@
         }
         mAddUserDialog = new AddUserDialog(mContext);
         if (dialogShower != null) {
-            dialogShower.showDialog(mAddUserDialog);
+            dialogShower.showDialog(mAddUserDialog,
+                    new DialogCuj(
+                            InteractionJankMonitor.CUJ_USER_DIALOG_OPEN,
+                            INTERACTION_JANK_ADD_NEW_USER_TAG
+                    ));
         } else {
             mAddUserDialog.show();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIInitializer.java
similarity index 73%
rename from packages/SystemUI/src/com/android/systemui/tv/TvSystemUIFactory.java
rename to packages/SystemUI/src/com/android/systemui/tv/TvSystemUIInitializer.java
index 0b5594b..fabbb2c 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIInitializer.java
@@ -16,14 +16,20 @@
 
 package com.android.systemui.tv;
 
-import com.android.systemui.SystemUIFactory;
+import android.content.Context;
+
+import com.android.systemui.SystemUIInitializer;
 import com.android.systemui.dagger.GlobalRootComponent;
 
 /**
- * TV variant {@link SystemUIFactory}, that substitutes default {@link GlobalRootComponent} for
+ * TV variant {@link SystemUIInitializer}, that substitutes default {@link GlobalRootComponent} for
  * {@link TvGlobalRootComponent}
  */
-public class TvSystemUIFactory extends SystemUIFactory {
+public class TvSystemUIInitializer extends SystemUIInitializer {
+    public TvSystemUIInitializer(Context context) {
+        super(context);
+    }
+
     @Override
     protected GlobalRootComponent.Builder getGlobalRootComponentBuilder() {
         return DaggerTvGlobalRootComponent.builder();
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt b/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt
index 7350b37..13ac39c 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt
@@ -18,7 +18,7 @@
 
 import com.android.keyguard.KeyguardUnfoldTransition
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.statusbar.phone.NotificationPanelUnfoldAnimationController
+import com.android.systemui.shade.NotificationPanelUnfoldAnimationController
 import com.android.systemui.statusbar.phone.StatusBarMoveFromCenterAnimationController
 import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider
 import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
diff --git a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
index ad73491..74d5111 100644
--- a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
@@ -28,6 +28,7 @@
 import android.os.UserManager
 import android.provider.Settings
 import android.view.LayoutInflater
+import android.view.MotionEvent
 import android.view.View
 import android.view.ViewGroup
 import android.widget.AdapterView
@@ -38,8 +39,10 @@
 import com.android.internal.annotations.VisibleForTesting
 import com.android.internal.util.UserIcons
 import com.android.settingslib.Utils
+import com.android.systemui.Gefingerpoken
 import com.android.systemui.R
 import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.plugins.FalsingManager.LOW_PENALTY
 import com.android.systemui.settings.UserTracker
@@ -61,12 +64,13 @@
     private val userSwitcherController: UserSwitcherController,
     private val broadcastDispatcher: BroadcastDispatcher,
     private val layoutInflater: LayoutInflater,
+    private val falsingCollector: FalsingCollector,
     private val falsingManager: FalsingManager,
     private val userManager: UserManager,
     private val userTracker: UserTracker
 ) : LifecycleActivity() {
 
-    private lateinit var parent: ViewGroup
+    private lateinit var parent: UserSwitcherRootView
     private lateinit var broadcastReceiver: BroadcastReceiver
     private var popupMenu: UserSwitcherPopupMenu? = null
     private lateinit var addButton: View
@@ -202,7 +206,14 @@
             or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
             or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)
 
-        parent = requireViewById<ViewGroup>(R.id.user_switcher_root)
+        parent = requireViewById<UserSwitcherRootView>(R.id.user_switcher_root)
+
+        parent.touchHandler = object : Gefingerpoken {
+            override fun onTouchEvent(ev: MotionEvent?): Boolean {
+                falsingCollector.onTouchEvent(ev)
+                return false
+            }
+        }
 
         requireViewById<View>(R.id.cancel).apply {
             setOnClickListener {
@@ -241,7 +252,7 @@
         )
         popupMenuAdapter.addAll(items)
 
-        popupMenu = UserSwitcherPopupMenu(this, falsingManager).apply {
+        popupMenu = UserSwitcherPopupMenu(this).apply {
             setAnchorView(addButton)
             setAdapter(popupMenuAdapter)
             setOnItemClickListener {
diff --git a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt
index 754a934..ee785b6 100644
--- a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt
@@ -23,16 +23,13 @@
 import android.widget.ListAdapter
 import android.widget.ListPopupWindow
 import android.widget.ListView
-
 import com.android.systemui.R
-import com.android.systemui.plugins.FalsingManager
 
 /**
  * Popup menu for displaying items on the fullscreen user switcher.
  */
 class UserSwitcherPopupMenu(
-    private val context: Context,
-    private val falsingManager: FalsingManager
+    private val context: Context
 ) : ListPopupWindow(context) {
 
     private val res = context.resources
diff --git a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherRootView.kt b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherRootView.kt
new file mode 100644
index 0000000..66a3017
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherRootView.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.user
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.MotionEvent
+import androidx.constraintlayout.widget.ConstraintLayout
+import com.android.systemui.Gefingerpoken
+
+/** A simple subclass that allows for observing touch events as they happen. */
+class UserSwitcherRootView(
+    context: Context,
+    attrs: AttributeSet?
+) : ConstraintLayout(context, attrs) {
+
+    /** Assign this field to observer touch events. */
+    var touchHandler: Gefingerpoken? = null
+
+    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
+        touchHandler?.onTouchEvent(ev)
+        return super.dispatchTouchEvent(ev)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/AsyncActivityLauncher.kt b/packages/SystemUI/src/com/android/systemui/util/AsyncActivityLauncher.kt
new file mode 100644
index 0000000..80d0e4b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/AsyncActivityLauncher.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util
+
+import android.app.IActivityTaskManager
+import android.app.WaitResult
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.os.UserHandle
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dagger.qualifiers.UiBackground
+import java.util.concurrent.Executor
+import javax.inject.Inject
+
+/**
+ * Helper class that allows to launch an activity and asynchronously wait
+ * for it to be launched. This class uses application context, so the intent
+ * will be launched with FLAG_ACTIVITY_NEW_TASK.
+ */
+class AsyncActivityLauncher @Inject constructor(
+    private val context: Context,
+    private val activityTaskManager: IActivityTaskManager,
+    @UiBackground private val backgroundExecutor: Executor,
+    @Main private val mainExecutor: Executor
+) {
+
+    private var pendingCallback: ((WaitResult) -> Unit)? = null
+
+    /**
+     * Starts activity and notifies about the result using the provided [callback].
+     * If there is already pending activity launch the call will be ignored.
+     *
+     * @return true if launch has started, false otherwise
+     */
+    fun startActivityAsUser(intent: Intent, userHandle: UserHandle,
+                            activityOptions: Bundle? = null,
+                            callback: (WaitResult) -> Unit): Boolean {
+        if (pendingCallback != null) return false
+
+        pendingCallback = callback
+
+        intent.flags = intent.flags or Intent.FLAG_ACTIVITY_NEW_TASK
+
+        backgroundExecutor.execute {
+            val waitResult = activityTaskManager.startActivityAndWait(
+                /* caller = */ null,
+                /* callingPackage = */ context.packageName,
+                /* callingFeatureId = */ context.attributionTag,
+                /* intent = */ intent,
+                /* resolvedType = */ null,
+                /* resultTo = */ null,
+                /* resultWho = */ null,
+                /* requestCode = */ 0,
+                /* flags = */ 0,
+                /* profilerInfo = */ null,
+                /* options = */ activityOptions,
+                /* userId = */ userHandle.identifier
+            )
+            mainExecutor.execute {
+                pendingCallback?.invoke(waitResult)
+            }
+        }
+
+        return true
+    }
+
+    /**
+     * Cancels pending activity launches. It guarantees that the callback won't be fired
+     * but the activity will be launched anyway.
+     */
+    fun destroy() {
+        pendingCallback = null
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt
new file mode 100644
index 0000000..05d087e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt
@@ -0,0 +1,41 @@
+package com.android.systemui.util.kotlin
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.Main
+import dagger.Module
+import dagger.Provides
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+
+/** Providers for various coroutines-related constructs. */
+@Module
+object CoroutinesModule {
+    @Provides
+    @SysUISingleton
+    @Application
+    fun applicationScope(
+        @Main dispatcher: CoroutineDispatcher,
+    ): CoroutineScope = CoroutineScope(dispatcher)
+
+    @Provides
+    @SysUISingleton
+    @Main
+    fun mainDispatcher(): CoroutineDispatcher = Dispatchers.Main.immediate
+
+    /**
+     * Provide a [CoroutineDispatcher] backed by a thread pool containing at most X threads, where
+     * X is the number of CPU cores available.
+     *
+     * Because there are multiple threads at play, there is no serialization order guarantee. You
+     * should use a [kotlinx.coroutines.channels.Channel] for serialization if necessary.
+     *
+     * @see Dispatchers.Default
+     */
+    @Provides
+    @SysUISingleton
+    @Background
+    fun bgDispatcher(): CoroutineDispatcher = Dispatchers.Default
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/service/ObservableServiceConnection.java b/packages/SystemUI/src/com/android/systemui/util/service/ObservableServiceConnection.java
index c57dbe3..064c224 100644
--- a/packages/SystemUI/src/com/android/systemui/util/service/ObservableServiceConnection.java
+++ b/packages/SystemUI/src/com/android/systemui/util/service/ObservableServiceConnection.java
@@ -155,11 +155,6 @@
      * Disconnect from the service if bound.
      */
     public void unbind() {
-        if (!mBoundCalled) {
-            return;
-        }
-        mBoundCalled = false;
-        mContext.unbindService(this);
         onDisconnected(DISCONNECT_REASON_UNBIND);
     }
 
@@ -210,12 +205,15 @@
             Log.d(TAG, "onDisconnected:" + reason);
         }
 
+        // If not bound or already unbound, do not proceed setting reason, unbinding, and
+        // notifying
         if (!mBoundCalled) {
             return;
         }
 
+        mBoundCalled = false;
         mLastDisconnectReason = Optional.of(reason);
-        unbind();
+        mContext.unbindService(this);
         mProxy = null;
 
         applyToCallbacksLocked(callback-> callback.onDisconnected(this,
diff --git a/packages/SystemUI/src/com/android/systemui/util/service/PersistentConnectionManager.java b/packages/SystemUI/src/com/android/systemui/util/service/PersistentConnectionManager.java
index 292c062..6e19bed 100644
--- a/packages/SystemUI/src/com/android/systemui/util/service/PersistentConnectionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/util/service/PersistentConnectionManager.java
@@ -72,6 +72,11 @@
 
         @Override
         public void onDisconnected(ObservableServiceConnection connection, int reason) {
+            // Do not attempt to reconnect if we were manually unbound
+            if (reason == ObservableServiceConnection.DISCONNECT_REASON_UNBIND) {
+                return;
+            }
+
             if (mSystemClock.currentTimeMillis() - mStartTime > mMinConnectionDuration) {
                 initiateConnectionAttempt();
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
index bca2a24..708a8ab 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
@@ -34,7 +34,6 @@
 import android.app.NotificationManager;
 import android.content.Context;
 import android.content.pm.UserInfo;
-import android.content.res.Configuration;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
@@ -72,7 +71,6 @@
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
-import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.wm.shell.bubbles.Bubble;
@@ -126,7 +124,6 @@
             NotificationShadeWindowController notificationShadeWindowController,
             KeyguardStateController keyguardStateController,
             ShadeController shadeController,
-            ConfigurationController configurationController,
             @Nullable IStatusBarService statusBarService,
             INotificationManager notificationManager,
             NotificationVisibilityProvider visibilityProvider,
@@ -145,7 +142,6 @@
                     notificationShadeWindowController,
                     keyguardStateController,
                     shadeController,
-                    configurationController,
                     statusBarService,
                     notificationManager,
                     visibilityProvider,
@@ -169,7 +165,6 @@
             NotificationShadeWindowController notificationShadeWindowController,
             KeyguardStateController keyguardStateController,
             ShadeController shadeController,
-            ConfigurationController configurationController,
             @Nullable IStatusBarService statusBarService,
             INotificationManager notificationManager,
             NotificationVisibilityProvider visibilityProvider,
@@ -213,23 +208,6 @@
             }
         });
 
-        configurationController.addCallback(new ConfigurationController.ConfigurationListener() {
-            @Override
-            public void onConfigChanged(Configuration newConfig) {
-                mBubbles.onConfigChanged(newConfig);
-            }
-
-            @Override
-            public void onUiModeChanged() {
-                mBubbles.updateForThemeChanges();
-            }
-
-            @Override
-            public void onThemeChanged() {
-                mBubbles.updateForThemeChanges();
-            }
-        });
-
         zenModeController.addCallback(new ZenModeController.Callback() {
             @Override
             public void onZenChanged(int zen) {
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index a6db2aa..83b0022 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -47,7 +47,6 @@
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.model.SysUiState;
-import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.shared.tracing.ProtoTraceable;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -56,9 +55,6 @@
 import com.android.systemui.tracing.ProtoTracer;
 import com.android.systemui.tracing.nano.SystemUiTraceProto;
 import com.android.wm.shell.ShellCommandHandler;
-import com.android.wm.shell.compatui.CompatUI;
-import com.android.wm.shell.draganddrop.DragAndDrop;
-import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
 import com.android.wm.shell.nano.WmShellTraceProto;
 import com.android.wm.shell.onehanded.OneHanded;
 import com.android.wm.shell.onehanded.OneHandedEventCallback;
@@ -67,6 +63,7 @@
 import com.android.wm.shell.pip.Pip;
 import com.android.wm.shell.protolog.ShellProtoLogImpl;
 import com.android.wm.shell.splitscreen.SplitScreen;
+import com.android.wm.shell.sysui.ShellInterface;
 
 import java.io.PrintWriter;
 import java.util.Arrays;
@@ -106,19 +103,16 @@
                     | SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
 
     // Shell interfaces
+    private final ShellInterface mShell;
     private final Optional<Pip> mPipOptional;
     private final Optional<SplitScreen> mSplitScreenOptional;
     private final Optional<OneHanded> mOneHandedOptional;
-    private final Optional<HideDisplayCutout> mHideDisplayCutoutOptional;
     private final Optional<ShellCommandHandler> mShellCommandHandler;
-    private final Optional<CompatUI> mCompatUIOptional;
-    private final Optional<DragAndDrop> mDragAndDropOptional;
 
     private final CommandQueue mCommandQueue;
     private final ConfigurationController mConfigurationController;
     private final KeyguardStateController mKeyguardStateController;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
-    private final NavigationModeController mNavigationModeController;
     private final ScreenLifecycle mScreenLifecycle;
     private final SysUiState mSysUiState;
     private final WakefulnessLifecycle mWakefulnessLifecycle;
@@ -127,26 +121,20 @@
     private final Executor mSysUiMainExecutor;
 
     private boolean mIsSysUiStateValid;
-    private KeyguardUpdateMonitorCallback mSplitScreenKeyguardCallback;
-    private KeyguardUpdateMonitorCallback mPipKeyguardCallback;
     private KeyguardUpdateMonitorCallback mOneHandedKeyguardCallback;
-    private KeyguardStateController.Callback mCompatUIKeyguardCallback;
     private WakefulnessLifecycle.Observer mWakefulnessObserver;
 
     @Inject
     public WMShell(Context context,
+            ShellInterface shell,
             Optional<Pip> pipOptional,
             Optional<SplitScreen> splitScreenOptional,
             Optional<OneHanded> oneHandedOptional,
-            Optional<HideDisplayCutout> hideDisplayCutoutOptional,
             Optional<ShellCommandHandler> shellCommandHandler,
-            Optional<CompatUI> sizeCompatUIOptional,
-            Optional<DragAndDrop> dragAndDropOptional,
             CommandQueue commandQueue,
             ConfigurationController configurationController,
             KeyguardStateController keyguardStateController,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
-            NavigationModeController navigationModeController,
             ScreenLifecycle screenLifecycle,
             SysUiState sysUiState,
             ProtoTracer protoTracer,
@@ -154,28 +142,50 @@
             UserInfoController userInfoController,
             @Main Executor sysUiMainExecutor) {
         super(context);
+        mShell = shell;
         mCommandQueue = commandQueue;
         mConfigurationController = configurationController;
         mKeyguardStateController = keyguardStateController;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
-        mNavigationModeController = navigationModeController;
         mScreenLifecycle = screenLifecycle;
         mSysUiState = sysUiState;
         mPipOptional = pipOptional;
         mSplitScreenOptional = splitScreenOptional;
         mOneHandedOptional = oneHandedOptional;
-        mHideDisplayCutoutOptional = hideDisplayCutoutOptional;
         mWakefulnessLifecycle = wakefulnessLifecycle;
         mProtoTracer = protoTracer;
         mShellCommandHandler = shellCommandHandler;
-        mCompatUIOptional = sizeCompatUIOptional;
-        mDragAndDropOptional = dragAndDropOptional;
         mUserInfoController = userInfoController;
         mSysUiMainExecutor = sysUiMainExecutor;
     }
 
     @Override
     public void start() {
+        // Notify with the initial configuration and subscribe for new config changes
+        mShell.onConfigurationChanged(mContext.getResources().getConfiguration());
+        mConfigurationController.addCallback(new ConfigurationController.ConfigurationListener() {
+            @Override
+            public void onConfigChanged(Configuration newConfig) {
+                mShell.onConfigurationChanged(newConfig);
+            }
+        });
+
+        // Subscribe to keyguard changes
+        mKeyguardStateController.addCallback(new KeyguardStateController.Callback() {
+            @Override
+            public void onKeyguardShowingChanged() {
+                mShell.onKeyguardVisibilityChanged(mKeyguardStateController.isShowing(),
+                        mKeyguardStateController.isOccluded(),
+                        mKeyguardStateController.isAnimatingBetweenKeyguardAndSurfaceBehind());
+            }
+        });
+        mKeyguardUpdateMonitor.registerCallback(new KeyguardUpdateMonitorCallback() {
+            @Override
+            public void onKeyguardDismissAnimationFinished() {
+                mShell.onKeyguardDismissAnimationFinished();
+            }
+        });
+
         // TODO: Consider piping config change and other common calls to a shell component to
         //  delegate internally
         mProtoTracer.add(this);
@@ -183,9 +193,6 @@
         mPipOptional.ifPresent(this::initPip);
         mSplitScreenOptional.ifPresent(this::initSplitScreen);
         mOneHandedOptional.ifPresent(this::initOneHanded);
-        mHideDisplayCutoutOptional.ifPresent(this::initHideDisplayCutout);
-        mCompatUIOptional.ifPresent(this::initCompatUi);
-        mDragAndDropOptional.ifPresent(this::initDragAndDrop);
     }
 
     @VisibleForTesting
@@ -197,42 +204,11 @@
             }
         });
 
-        mPipKeyguardCallback = new KeyguardUpdateMonitorCallback() {
-            @Override
-            public void onKeyguardVisibilityChanged(boolean showing) {
-                pip.onKeyguardVisibilityChanged(showing,
-                        mKeyguardStateController.isAnimatingBetweenKeyguardAndSurfaceBehind());
-            }
-
-            @Override
-            public void onKeyguardDismissAnimationFinished() {
-                pip.onKeyguardDismissAnimationFinished();
-            }
-        };
-        mKeyguardUpdateMonitor.registerCallback(mPipKeyguardCallback);
-
         mSysUiState.addCallback(sysUiStateFlag -> {
             mIsSysUiStateValid = (sysUiStateFlag & INVALID_SYSUI_STATE_MASK) == 0;
             pip.onSystemUiStateChanged(mIsSysUiStateValid, sysUiStateFlag);
         });
 
-        mConfigurationController.addCallback(new ConfigurationController.ConfigurationListener() {
-            @Override
-            public void onConfigChanged(Configuration newConfig) {
-                pip.onConfigurationChanged(newConfig);
-            }
-
-            @Override
-            public void onDensityOrFontScaleChanged() {
-                pip.onDensityOrFontScaleChanged();
-            }
-
-            @Override
-            public void onThemeChanged() {
-                pip.onOverlayChanged();
-            }
-        });
-
         // The media session listener needs to be re-registered when switching users
         mUserInfoController.addCallback((String name, Drawable picture, String userAccount) ->
                 pip.registerSessionListenerForCurrentUser());
@@ -240,14 +216,6 @@
 
     @VisibleForTesting
     void initSplitScreen(SplitScreen splitScreen) {
-        mSplitScreenKeyguardCallback = new KeyguardUpdateMonitorCallback() {
-            @Override
-            public void onKeyguardVisibilityChanged(boolean showing) {
-                splitScreen.onKeyguardVisibilityChanged(showing);
-            }
-        };
-        mKeyguardUpdateMonitor.registerCallback(mSplitScreenKeyguardCallback);
-
         mWakefulnessLifecycle.addObserver(new WakefulnessLifecycle.Observer() {
             @Override
             public void onFinishedWakingUp() {
@@ -293,14 +261,9 @@
             }
         });
 
+        // TODO: Either move into ShellInterface or register a receiver on the Shell side directly
         mOneHandedKeyguardCallback = new KeyguardUpdateMonitorCallback() {
             @Override
-            public void onKeyguardVisibilityChanged(boolean showing) {
-                oneHanded.onKeyguardVisibilityChanged(showing);
-                oneHanded.stopOneHanded();
-            }
-
-            @Override
             public void onUserSwitchComplete(int userId) {
                 oneHanded.onUserSwitch(userId);
             }
@@ -348,48 +311,6 @@
                 }
             }
         });
-
-        mConfigurationController.addCallback(new ConfigurationController.ConfigurationListener() {
-            @Override
-            public void onConfigChanged(Configuration newConfig) {
-                oneHanded.onConfigChanged(newConfig);
-            }
-        });
-    }
-
-    @VisibleForTesting
-    void initHideDisplayCutout(HideDisplayCutout hideDisplayCutout) {
-        mConfigurationController.addCallback(new ConfigurationController.ConfigurationListener() {
-            @Override
-            public void onConfigChanged(Configuration newConfig) {
-                hideDisplayCutout.onConfigurationChanged(newConfig);
-            }
-        });
-    }
-
-    @VisibleForTesting
-    void initCompatUi(CompatUI sizeCompatUI) {
-        mCompatUIKeyguardCallback = new KeyguardStateController.Callback() {
-            @Override
-            public void onKeyguardShowingChanged() {
-                sizeCompatUI.onKeyguardShowingChanged(mKeyguardStateController.isShowing());
-            }
-        };
-        mKeyguardStateController.addCallback(mCompatUIKeyguardCallback);
-    }
-
-    void initDragAndDrop(DragAndDrop dragAndDrop) {
-        mConfigurationController.addCallback(new ConfigurationController.ConfigurationListener() {
-            @Override
-            public void onConfigChanged(Configuration newConfig) {
-                dragAndDrop.onConfigChanged(newConfig);
-            }
-
-            @Override
-            public void onThemeChanged() {
-                dragAndDrop.onThemeChanged();
-            }
-        });
     }
 
     @Override
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
index 4f39952..0ac4eda 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
@@ -21,6 +21,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.plugins.Clock
 import com.android.systemui.plugins.ClockAnimations
 import com.android.systemui.plugins.ClockEvents
@@ -33,6 +34,7 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.mock
 import java.util.TimeZone
+import java.util.concurrent.Executor
 import org.junit.Assert.assertEquals
 import org.junit.Before
 import org.junit.Rule
@@ -60,6 +62,9 @@
     @Mock private lateinit var animations: ClockAnimations
     @Mock private lateinit var events: ClockEvents
     @Mock private lateinit var clock: Clock
+    @Mock private lateinit var mainExecutor: Executor
+    @Mock private lateinit var bgExecutor: Executor
+    @Mock private lateinit var featureFlags: FeatureFlags
 
     private lateinit var clockEventController: ClockEventController
 
@@ -77,7 +82,10 @@
             keyguardUpdateMonitor,
             configurationController,
             context.resources,
-            context
+            context,
+            mainExecutor,
+            bgExecutor,
+            featureFlags
         )
     }
 
@@ -99,13 +107,15 @@
     @Test
     fun themeChanged_verifyClockPaletteUpdated() {
         clockEventController.clock = clock
+        verify(events).onColorPaletteChanged(any(), any(), any())
+
         clockEventController.registerListeners()
 
         val captor = argumentCaptor<ConfigurationController.ConfigurationListener>()
         verify(configurationController).addCallback(capture(captor))
         captor.value.onThemeChanged()
 
-        verify(events).onColorPaletteChanged(any())
+        verify(events, times(2)).onColorPaletteChanged(any(), any(), any())
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java
index ac1a83c..4021652 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java
@@ -20,6 +20,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -31,6 +32,7 @@
 import android.testing.TestableLooper;
 import android.testing.TestableResources;
 import android.view.Gravity;
+import android.view.View;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 
@@ -42,6 +44,7 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
@@ -104,6 +107,17 @@
     }
 
     @Test
+    public void onBouncerVisible_propagatesToKeyguardSecurityContainerController() {
+        mKeyguardHostViewController.onBouncerVisibilityChanged(ViewGroup.VISIBLE);
+        mKeyguardHostViewController.onBouncerVisibilityChanged(ViewGroup.INVISIBLE);
+
+        InOrder order = inOrder(mKeyguardSecurityContainerController);
+        order.verify(mKeyguardSecurityContainerController).onBouncerVisibilityChanged(View.VISIBLE);
+        order.verify(mKeyguardSecurityContainerController).onBouncerVisibilityChanged(
+                View.INVISIBLE);
+    }
+
+    @Test
     public void testGravityReappliedOnConfigurationChange() {
         FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
                 ViewGroup.LayoutParams.MATCH_PARENT,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
index b1e2012..ad6d146 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
@@ -92,7 +92,6 @@
     keyguardAwake = false,
     keyguardGoingAway = false,
     listeningForFaceAssistant = false,
-    lockIconPressed = false,
     occludingAppRequestingFaceAuth = false,
     primaryUser = false,
     scanningAllowedByStrongAuth = false,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
index bc35142..68e49c0 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
@@ -25,17 +25,21 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.hardware.biometrics.BiometricSourceType;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.MotionEvent;
+import android.view.View;
 import android.view.WindowInsetsController;
 
 import androidx.test.filters.SmallTest;
@@ -46,6 +50,7 @@
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.biometrics.SidefpsController;
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.log.SessionTracker;
@@ -59,10 +64,14 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
+import java.util.Optional;
+
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper()
@@ -124,6 +133,14 @@
     private SessionTracker mSessionTracker;
     @Mock
     private KeyguardViewController mKeyguardViewController;
+    @Mock
+    private SidefpsController mSidefpsController;
+    @Mock
+    private KeyguardPasswordViewController mKeyguardPasswordViewControllerMock;
+
+    @Captor
+    private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallback;
+
     private Configuration mConfiguration;
 
     private KeyguardSecurityContainerController mKeyguardSecurityContainerController;
@@ -160,7 +177,7 @@
                 mKeyguardStateController, mKeyguardSecurityViewFlipperController,
                 mConfigurationController, mFalsingCollector, mFalsingManager,
                 mUserSwitcherController, mFeatureFlags, mGlobalSettings,
-                mSessionTracker).create(mSecurityCallback);
+                mSessionTracker, Optional.of(mSidefpsController)).create(mSecurityCallback);
     }
 
     @Test
@@ -258,9 +275,7 @@
     @Test
     public void showSecurityScreen_twoHandedMode_flagEnabled_noOneHandedMode() {
         when(mResources.getBoolean(R.bool.can_use_one_handed_bouncer)).thenReturn(true);
-        when(mKeyguardSecurityViewFlipperController.getSecurityView(
-                eq(SecurityMode.Password), any(KeyguardSecurityCallback.class)))
-                .thenReturn((KeyguardInputViewController) mKeyguardPasswordViewController);
+        setupGetSecurityView();
 
         mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.Password);
         verify(mView).initMode(MODE_DEFAULT, mGlobalSettings, mFalsingManager,
@@ -276,4 +291,126 @@
         verify(mUserSwitcherController)
                 .removeUserSwitchCallback(any(UserSwitcherController.UserSwitchCallback.class));
     }
+
+    @Test
+    public void onBouncerVisibilityChanged_allConditionsGood_sideFpsHintShown() {
+        setupConditionsToEnableSideFpsHint();
+        reset(mSidefpsController);
+
+        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
+
+        verify(mSidefpsController).show();
+        verify(mSidefpsController, never()).hide();
+    }
+
+    @Test
+    public void onBouncerVisibilityChanged_fpsSensorNotRunning_sideFpsHintHidden() {
+        setupConditionsToEnableSideFpsHint();
+        setFingerprintDetectionRunning(false);
+        reset(mSidefpsController);
+
+        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
+
+        verify(mSidefpsController).hide();
+        verify(mSidefpsController, never()).show();
+    }
+
+    @Test
+    public void onBouncerVisibilityChanged_withoutSidedSecurity_sideFpsHintHidden() {
+        setupConditionsToEnableSideFpsHint();
+        setSidedSecurityMode(false);
+        reset(mSidefpsController);
+
+        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
+
+        verify(mSidefpsController).hide();
+        verify(mSidefpsController, never()).show();
+    }
+
+    @Test
+    public void onBouncerVisibilityChanged_needsStrongAuth_sideFpsHintHidden() {
+        setupConditionsToEnableSideFpsHint();
+        setNeedsStrongAuth(true);
+        reset(mSidefpsController);
+
+        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
+
+        verify(mSidefpsController).hide();
+        verify(mSidefpsController, never()).show();
+    }
+
+    @Test
+    public void onBouncerVisibilityChanged_sideFpsHintShown_sideFpsHintHidden() {
+        setupGetSecurityView();
+        setupConditionsToEnableSideFpsHint();
+        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
+        verify(mSidefpsController, atLeastOnce()).show();
+        reset(mSidefpsController);
+
+        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.INVISIBLE);
+
+        verify(mSidefpsController).hide();
+        verify(mSidefpsController, never()).show();
+    }
+
+    @Test
+    public void onStartingToHide_sideFpsHintShown_sideFpsHintHidden() {
+        setupGetSecurityView();
+        setupConditionsToEnableSideFpsHint();
+        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
+        verify(mSidefpsController, atLeastOnce()).show();
+        reset(mSidefpsController);
+
+        mKeyguardSecurityContainerController.onStartingToHide();
+
+        verify(mSidefpsController).hide();
+        verify(mSidefpsController, never()).show();
+    }
+
+    @Test
+    public void onPause_sideFpsHintShown_sideFpsHintHidden() {
+        setupGetSecurityView();
+        setupConditionsToEnableSideFpsHint();
+        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
+        verify(mSidefpsController, atLeastOnce()).show();
+        reset(mSidefpsController);
+
+        mKeyguardSecurityContainerController.onPause();
+
+        verify(mSidefpsController).hide();
+        verify(mSidefpsController, never()).show();
+    }
+
+    private void setupConditionsToEnableSideFpsHint() {
+        attachView();
+        setSidedSecurityMode(true);
+        setFingerprintDetectionRunning(true);
+        setNeedsStrongAuth(false);
+    }
+
+    private void attachView() {
+        mKeyguardSecurityContainerController.onViewAttached();
+        verify(mKeyguardUpdateMonitor).registerCallback(mKeyguardUpdateMonitorCallback.capture());
+    }
+
+    private void setFingerprintDetectionRunning(boolean running) {
+        when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(running);
+        mKeyguardUpdateMonitorCallback.getValue().onBiometricRunningStateChanged(running,
+                BiometricSourceType.FINGERPRINT);
+    }
+
+    private void setSidedSecurityMode(boolean sided) {
+        when(mView.isSidedSecurityMode()).thenReturn(sided);
+    }
+
+    private void setNeedsStrongAuth(boolean needed) {
+        when(mKeyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(needed);
+        mKeyguardUpdateMonitorCallback.getValue().onStrongAuthStateChanged(/* userId= */ 0);
+    }
+
+    private void setupGetSecurityView() {
+        when(mKeyguardSecurityViewFlipperController.getSecurityView(
+                any(), any(KeyguardSecurityCallback.class)))
+                .thenReturn((KeyguardInputViewController) mKeyguardPasswordViewControllerMock);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 2dc066c..84903d1 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -1109,8 +1109,7 @@
 
         // THEN face unlock is not running b/c status bar state changes don't cause biometric
         // listening state to update
-        assertThat(mKeyguardUpdateMonitor.isFaceUnlockRunning(
-                KeyguardUpdateMonitor.getCurrentUser())).isEqualTo(false);
+        assertThat(mKeyguardUpdateMonitor.isFaceDetectionRunning()).isEqualTo(false);
 
         // WHEN biometric listening state is updated
         mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java b/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java
index 5d8e435..a0fdc8f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java
@@ -26,6 +26,8 @@
 import org.junit.Assert;
 import org.junit.Test;
 
+import java.util.concurrent.ExecutionException;
+
 @SmallTest
 public class DependencyTest extends SysuiTestCase {
 
@@ -44,10 +46,12 @@
     }
 
     @Test
-    public void testInitDependency() {
+    public void testInitDependency() throws ExecutionException, InterruptedException {
         Dependency.clearDependencies();
-        Dependency dependency =
-                SystemUIFactory.getInstance().getSysUIComponent().createDependency();
+        SystemUIInitializer initializer =
+                SystemUIInitializerFactory.createFromConfigNoAssert(mContext);
+        initializer.init(true);
+        Dependency dependency = initializer.getSysUIComponent().createDependency();
         dependency.start();
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
index df10dfe..64a7986 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
@@ -16,6 +16,7 @@
 
 import static android.view.DisplayCutout.BOUNDS_POSITION_BOTTOM;
 import static android.view.DisplayCutout.BOUNDS_POSITION_LEFT;
+import static android.view.DisplayCutout.BOUNDS_POSITION_LENGTH;
 import static android.view.DisplayCutout.BOUNDS_POSITION_RIGHT;
 import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
@@ -35,7 +36,6 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isA;
-import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -49,6 +49,7 @@
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
+import android.graphics.Insets;
 import android.graphics.Path;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
@@ -59,6 +60,7 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
+import android.util.RotationUtils;
 import android.util.Size;
 import android.view.Display;
 import android.view.DisplayCutout;
@@ -78,8 +80,6 @@
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.decor.CornerDecorProvider;
-import com.android.systemui.decor.CutoutDecorProviderFactory;
-import com.android.systemui.decor.CutoutDecorProviderImpl;
 import com.android.systemui.decor.DecorProvider;
 import com.android.systemui.decor.DecorProviderFactory;
 import com.android.systemui.decor.FaceScanningOverlayProviderImpl;
@@ -157,9 +157,6 @@
     @Mock
     private DisplayInfo mDisplayInfo;
     private PrivacyDotViewController.ShowingListener mPrivacyDotShowingListener;
-    @Mock
-    private CutoutDecorProviderFactory mCutoutFactory;
-    private List<DecorProvider> mMockCutoutList;
 
     @Before
     public void setup() {
@@ -209,11 +206,6 @@
                 DisplayCutout.BOUNDS_POSITION_RIGHT,
                 R.layout.privacy_dot_bottom_right));
 
-        // Default no cutout
-        mMockCutoutList = new ArrayList<>();
-        doAnswer(it -> !(mMockCutoutList.isEmpty())).when(mCutoutFactory).getHasProviders();
-        doReturn(mMockCutoutList).when(mCutoutFactory).getProviders();
-
         mFaceScanningDecorProvider = spy(new FaceScanningOverlayProviderImpl(
                 BOUNDS_POSITION_TOP,
                 mAuthController,
@@ -247,11 +239,6 @@
                 super.updateOverlayWindowVisibilityIfViewExists(view);
                 mExecutor.runAllReady();
             }
-
-            @Override
-            protected CutoutDecorProviderFactory getCutoutFactory() {
-                return ScreenDecorationsTest.this.mCutoutFactory;
-            }
         });
         mScreenDecorations.mDisplayInfo = mDisplayInfo;
         doReturn(1f).when(mScreenDecorations).getPhysicalPixelDisplaySizeRatio();
@@ -442,9 +429,11 @@
     public void testNoRounding_NoCutout_NoPrivacyDot_NoFaceScanning() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, false /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
-        // no cutout (default)
+        // no cutout
+        doReturn(null).when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         // No views added.
@@ -459,9 +448,11 @@
     public void testNoRounding_NoCutout_PrivacyDot_NoFaceScanning() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
-        // no cutout (default)
+        // no cutout
+        doReturn(null).when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
 
@@ -493,9 +484,11 @@
     public void testRounding_NoCutout_NoPrivacyDot_NoFaceScanning() {
         setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                20 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
+                20 /* roundedPadding */, false /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
-        // no cutout (default)
+        // no cutout
+        doReturn(null).when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
 
@@ -523,9 +516,11 @@
     public void testRounding_NoCutout_PrivacyDot_NoFaceScanning() {
         setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                20 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
+                20 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
-        // no cutout (default)
+        // no cutout
+        doReturn(null).when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
 
@@ -560,9 +555,10 @@
                 /* roundedTopDrawable */,
                 getTestsDrawable(com.android.systemui.tests.R.drawable.rounded3px)
                 /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
-
-        // no cutout (default)
+                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
+        // no cutout
+        doReturn(null).when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         // Size of corner view should same as rounded_corner_radius{_top|_bottom}
@@ -578,9 +574,11 @@
                 /* roundedTopDrawable */,
                 getTestsDrawable(com.android.systemui.tests.R.drawable.rounded3px)
                 /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
-        // no cutout (default)
+        // no cutout
+        doReturn(null).when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         View leftRoundedCorner = mScreenDecorations.mOverlays[BOUNDS_POSITION_TOP].getRootView()
@@ -613,10 +611,13 @@
                 /* roundedTopDrawable */,
                 getTestsDrawable(com.android.systemui.tests.R.drawable.rounded5px)
                 /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         // left cutout
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_LEFT));
+        final Rect[] bounds = {new Rect(0, 50, 1, 60), null, null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(1, 0, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         View topRoundedCorner = mScreenDecorations.mOverlays[BOUNDS_POSITION_LEFT].getRootView()
@@ -646,10 +647,13 @@
     public void testNoRounding_CutoutShortEdge_NoPrivacyDot() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         // top cutout
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
+        final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         // Top window is created for top cutout.
@@ -667,10 +671,13 @@
     public void testNoRounding_CutoutShortEdge_PrivacyDot() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         // top cutout
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
+        final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         // Top window is created for top cutout.
@@ -699,10 +706,13 @@
     public void testNoRounding_CutoutLongEdge_NoPrivacyDot() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         // left cutout
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_LEFT));
+        final Rect[] bounds = {new Rect(0, 50, 1, 60), null, null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(1, 0, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         // Left window is created for left cutout.
@@ -724,10 +734,13 @@
     public void testNoRounding_CutoutLongEdge_PrivacyDot() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         // left cutout
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_LEFT));
+        final Rect[] bounds = {new Rect(0, 50, 1, 60), null, null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(1, 0, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         // Left window is created for left cutout.
@@ -749,10 +762,13 @@
     public void testRounding_CutoutShortEdge_NoPrivacyDot() {
         setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                20 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
+                20 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         // top cutout
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
+        final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         // Top window is created for rounded corner and top cutout.
@@ -775,10 +791,13 @@
     public void testRounding_CutoutShortEdge_PrivacyDot() {
         setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                20 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
+                20 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         // top cutout
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
+        final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         // Top window is created for rounded corner and top cutout.
@@ -804,10 +823,13 @@
     public void testRounding_CutoutLongEdge_NoPrivacyDot() {
         setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                20 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
+                20 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         // left cutout
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_LEFT));
+        final Rect[] bounds = {new Rect(0, 50, 1, 60), null, null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(1, 0, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         // Left window is created for rounded corner and left cutout.
@@ -820,10 +842,13 @@
     public void testRounding_CutoutLongEdge_PrivacyDot() {
         setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                20 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
+                20 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         // left cutout
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_LEFT));
+        final Rect[] bounds = {new Rect(0, 50, 1, 60), null, null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(1, 0, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         // Left window is created for rounded corner, left cutout, and privacy.
@@ -838,11 +863,13 @@
     public void testRounding_CutoutShortAndLongEdge_NoPrivacyDot() {
         setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                20 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
+                20 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         // top and left cutout
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_LEFT));
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
+        final Rect[] bounds = {new Rect(0, 50, 1, 60), new Rect(9, 0, 10, 1), null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(1, 1, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         // Top window is created for rounded corner and top cutout.
@@ -856,11 +883,13 @@
     public void testRounding_CutoutShortAndLongEdge_PrivacyDot() {
         setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                20 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
+                20 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         // top and left cutout
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_LEFT));
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
+        final Rect[] bounds = {new Rect(0, 50, 1, 60), new Rect(9, 0, 10, 1), null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(1, 1, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         // Top window is created for rounded corner and top cutout.
@@ -876,16 +905,21 @@
     public void testNoRounding_SwitchFrom_ShortEdgeCutout_To_LongCutout_NoPrivacyDot() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         // Set to short edge cutout(top).
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
+        final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         verifyOverlaysExistAndAdded(false, true, false, false, View.VISIBLE);
 
         // Switch to long edge cutout(left).
-        mMockCutoutList.set(0, new CutoutDecorProviderImpl(BOUNDS_POSITION_LEFT));
+        final Rect[] newBounds = {new Rect(0, 50, 1, 60), null, null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(1, 0, 0, 0), newBounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.onConfigurationChanged(new Configuration());
         verifyOverlaysExistAndAdded(true, false, false, false, View.VISIBLE);
@@ -895,10 +929,13 @@
     public void testNoRounding_SwitchFrom_ShortEdgeCutout_To_LongCutout_PrivacyDot() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         // Set to short edge cutout(top).
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
+        final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         verifyOverlaysExistAndAdded(false, true, false, true, View.VISIBLE);
@@ -906,7 +943,9 @@
         verify(mDotViewController, times(1)).setShowingListener(null);
 
         // Switch to long edge cutout(left).
-        mMockCutoutList.set(0, new CutoutDecorProviderImpl(BOUNDS_POSITION_LEFT));
+        final Rect[] newBounds = {new Rect(0, 50, 1, 60), null, null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(1, 0, 0, 0), newBounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.onConfigurationChanged(new Configuration());
         verifyOverlaysExistAndAdded(true, false, true, false, View.VISIBLE);
@@ -934,16 +973,20 @@
     public void testDelayedCutout_NoPrivacyDot() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, false /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
-        // No cutout (default)
+        // top cutout
+        final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         verifyOverlaysExistAndAdded(false, false, false, false, null);
 
-        // top cutout
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
-
+        when(mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout))
+                .thenReturn(true);
         mScreenDecorations.onConfigurationChanged(new Configuration());
 
         // Only top windows should be added.
@@ -954,9 +997,13 @@
     public void testDelayedCutout_PrivacyDot() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
-        // no cutout (default)
+        // top cutout
+        final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         // Both top and bottom windows should be added with INVISIBLE because of only privacy dot,
@@ -968,9 +1015,9 @@
         verify(mDotViewController, times(1)).setShowingListener(
                 mScreenDecorations.mPrivacyDotShowingListener);
 
-        // top cutout
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
-
+        when(mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout))
+                .thenReturn(true);
         mScreenDecorations.onConfigurationChanged(new Configuration());
 
         // Both top and bottom windows should be added with VISIBLE because of privacy dot and
@@ -996,7 +1043,8 @@
                 /* roundedTopDrawable */,
                 getTestsDrawable(com.android.systemui.tests.R.drawable.rounded4px)
                 /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning*/);
+                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning*/);
         mDisplayInfo.rotation = Surface.ROTATION_0;
 
         mScreenDecorations.start();
@@ -1010,7 +1058,8 @@
                 /* roundedTopDrawable */,
                 getTestsDrawable(com.android.systemui.tests.R.drawable.rounded5px)
                 /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning*/);
+                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning*/);
         mDisplayInfo.rotation = Surface.ROTATION_270;
 
         mScreenDecorations.onConfigurationChanged(null);
@@ -1023,7 +1072,8 @@
     public void testOnlyRoundedCornerRadiusTop() {
         setupResources(0 /* radius */, 10 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         mScreenDecorations.start();
 
@@ -1044,7 +1094,8 @@
     public void testOnlyRoundedCornerRadiusBottom() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 20 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         mScreenDecorations.start();
 
@@ -1115,10 +1166,13 @@
     public void testSupportHwcLayer_SwitchFrom_NotSupport() {
         setupResources(0 /* radius */, 10 /* radiusTop */, 20 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         // top cutout
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
+        final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         // should only inflate mOverlays when the hwc doesn't support screen decoration
@@ -1141,13 +1195,16 @@
     public void testNotSupportHwcLayer_SwitchFrom_Support() {
         setupResources(0 /* radius */, 10 /* radiusTop */, 20 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
         final DisplayDecorationSupport decorationSupport = new DisplayDecorationSupport();
         decorationSupport.format = PixelFormat.R_8;
         doReturn(decorationSupport).when(mDisplay).getDisplayDecorationSupport();
 
         // top cutout
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
+        final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         // should only inflate hwc layer when the hwc supports screen decoration
@@ -1177,13 +1234,16 @@
                 /* roundedTopDrawable */,
                 getTestsDrawable(com.android.systemui.tests.R.drawable.rounded4px)
                 /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* privacyDot */, true /* faceScanning */);
+                0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
+                true /* faceScanning */);
         final DisplayDecorationSupport decorationSupport = new DisplayDecorationSupport();
         decorationSupport.format = PixelFormat.R_8;
         doReturn(decorationSupport).when(mDisplay).getDisplayDecorationSupport();
 
         // top cutout
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
+        final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         // Inflate top and bottom overlay with INVISIBLE because of only privacy dots on sw layer
@@ -1217,9 +1277,11 @@
     public void testAutoShowHideOverlayWindowWhenNoRoundedAndNoCutout() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* privacyDot */, true /* faceScanning */);
+                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                true /* faceScanning */);
 
-        // no cutout (default)
+        // no cutout
+        doReturn(null).when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
         // Inflate top and bottom overlay with INVISIBLE because of only privacy dots on sw layer
@@ -1253,13 +1315,16 @@
     public void testHwcLayer_noPrivacyDot_noFaceScanning() {
         setupResources(0 /* radius */, 10 /* radiusTop */, 20 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
         final DisplayDecorationSupport decorationSupport = new DisplayDecorationSupport();
         decorationSupport.format = PixelFormat.R_8;
         doReturn(decorationSupport).when(mDisplay).getDisplayDecorationSupport();
 
         // top cutout
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
+        final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
 
@@ -1272,13 +1337,16 @@
     public void testHwcLayer_PrivacyDot_FaceScanning() {
         setupResources(0 /* radius */, 10 /* radiusTop */, 20 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* privacyDot */, true /* faceScanning */);
+                0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
+                true /* faceScanning */);
         final DisplayDecorationSupport decorationSupport = new DisplayDecorationSupport();
         decorationSupport.format = PixelFormat.R_8;
         doReturn(decorationSupport).when(mDisplay).getDisplayDecorationSupport();
 
         // top cutout
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
+        final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
 
@@ -1296,13 +1364,16 @@
     public void testOnDisplayChanged_hwcLayer() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
         final DisplayDecorationSupport decorationSupport = new DisplayDecorationSupport();
         decorationSupport.format = PixelFormat.R_8;
         doReturn(decorationSupport).when(mDisplay).getDisplayDecorationSupport();
 
         // top cutout
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
+        final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
 
@@ -1319,16 +1390,18 @@
     public void testOnDisplayChanged_nonHwcLayer() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         // top cutout
-        mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
+        final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
+        doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
+                .when(mScreenDecorations).getCutout();
 
         mScreenDecorations.start();
 
-        final ScreenDecorations.DisplayCutoutView cutoutView = (ScreenDecorations.DisplayCutoutView)
-                mScreenDecorations.getOverlayView(R.id.display_cutout);
-        assertNotNull(cutoutView);
+        final ScreenDecorations.DisplayCutoutView cutoutView =
+                mScreenDecorations.mCutoutViews[BOUNDS_POSITION_TOP];
         spyOn(cutoutView);
         doReturn(mDisplay).when(cutoutView).getDisplay();
 
@@ -1341,7 +1414,8 @@
     public void testHasSameProvidersWithNullOverlays() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, false /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         mScreenDecorations.start();
 
@@ -1359,7 +1433,8 @@
     public void testHasSameProvidersWithPrivacyDots() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
+                0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         mScreenDecorations.start();
 
@@ -1396,7 +1471,7 @@
 
     private void setupResources(int radius, int radiusTop, int radiusBottom,
             @Nullable Drawable roundedTopDrawable, @Nullable Drawable roundedBottomDrawable,
-            int roundedPadding, boolean privacyDot, boolean faceScanning) {
+            int roundedPadding, boolean fillCutout, boolean privacyDot, boolean faceScanning) {
         mContext.getOrCreateTestableResources().addOverride(
                 com.android.internal.R.array.config_displayUniqueIdArray,
                 new String[]{});
@@ -1436,6 +1511,8 @@
         }
         mContext.getOrCreateTestableResources().addOverride(
                 R.dimen.rounded_corner_content_padding, roundedPadding);
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, fillCutout);
 
         mPrivacyDecorProviders = new ArrayList<>();
         if (privacyDot) {
@@ -1454,4 +1531,19 @@
         when(mFaceScanningProviderFactory.getProviders()).thenReturn(mFaceScanningProviders);
         when(mFaceScanningProviderFactory.getHasProviders()).thenReturn(faceScanning);
     }
+
+    private DisplayCutout getDisplayCutoutForRotation(Insets safeInsets, Rect[] cutoutBounds) {
+        final int rotation = mContext.getDisplay().getRotation();
+        final Insets insets = RotationUtils.rotateInsets(safeInsets, rotation);
+        final Rect[] sorted = new Rect[BOUNDS_POSITION_LENGTH];
+        for (int i = 0; i < BOUNDS_POSITION_LENGTH; i++) {
+            final int rotatedPos = ScreenDecorations.getBoundPositionFromRotation(i, rotation);
+            if (cutoutBounds[i] != null) {
+                RotationUtils.rotateBounds(cutoutBounds[i], new Rect(0, 0, 100, 200), rotation);
+            }
+            sorted[rotatedPos] = cutoutBounds[i];
+        }
+        return new DisplayCutout(insets, sorted[BOUNDS_POSITION_LEFT], sorted[BOUNDS_POSITION_TOP],
+                sorted[BOUNDS_POSITION_RIGHT], sorted[BOUNDS_POSITION_BOTTOM]);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
index 8c20b24..9179efc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
@@ -34,6 +34,8 @@
 import org.junit.Rule;
 import org.mockito.Mockito;
 
+import java.util.concurrent.ExecutionException;
+
 public abstract class SysuiBaseFragmentTest extends BaseFragmentTest {
 
     public static final Class<?>[] ALL_SUPPORTED_CLASSES = LeakCheckedTest.ALL_SUPPORTED_CLASSES;
@@ -54,10 +56,11 @@
     }
 
     @Before
-    public void SysuiSetup() {
-        SystemUIFactory.createFromConfig(mContext, true);
-        mDependency = new TestableDependency(
-                SystemUIFactory.getInstance().getSysUIComponent().createDependency());
+    public void sysuiSetup() throws ExecutionException, InterruptedException {
+        SystemUIInitializer initializer =
+                SystemUIInitializerFactory.createFromConfigNoAssert(mContext);
+        initializer.init(true);
+        mDependency = new TestableDependency(initializer.getSysUIComponent().createDependency());
         Dependency.setInstance(mDependency);
 
         // TODO: Figure out another way to give reference to a SysuiTestableContext.
@@ -77,7 +80,6 @@
     public void SysuiTeardown() {
         InstrumentationRegistry.registerInstance(mRealInstrumentation,
                 InstrumentationRegistry.getArguments());
-        SystemUIFactory.cleanup();
     }
 
     @AfterClass
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index 8c79277..c52ea60f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -76,9 +76,10 @@
 
     @Before
     public void SysuiSetup() throws Exception {
-        SystemUIFactory.createFromConfig(mContext, true);
-        mDependency = new TestableDependency(
-                SystemUIFactory.getInstance().getSysUIComponent().createDependency());
+        SystemUIInitializer initializer =
+                SystemUIInitializerFactory.createFromConfigNoAssert(mContext);
+        initializer.init(true);
+        mDependency = new TestableDependency(initializer.getSysUIComponent().createDependency());
         Dependency.setInstance(mDependency);
         mFakeBroadcastDispatcher = new FakeBroadcastDispatcher(mContext, mock(Looper.class),
                 mock(Executor.class), mock(DumpManager.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java
index 7e9f84c..bebd871 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java
@@ -191,6 +191,16 @@
     }
 
     @Test
+    public void hideMenuViewWhenStartingAnimation_animatorNotRunning() {
+        mMenuView.show();
+
+        mMenuView.mDragAnimator.start();
+        mMenuView.hide();
+
+        assertThat(mMenuView.mDragAnimator.isRunning()).isFalse();
+    }
+
+    @Test
     public void onTargetsChanged_singleTarget_expectedRadii() {
         final Position alignRightPosition = new Position(1.0f, 0.0f);
         final AccessibilityFloatingMenuView menuView = new AccessibilityFloatingMenuView(mContext,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt
index 1e2074b..4218e09 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt
@@ -170,19 +170,27 @@
     @Test
     fun testCujSpecificationLogsInteraction() {
         val touchSurface = createTouchSurface()
-        return runOnMainThreadAndWaitForIdleSync {
+        runOnMainThreadAndWaitForIdleSync {
             val dialog = TestDialog(context)
             dialogLaunchAnimator.showFromView(
-                dialog, touchSurface,
-                cuj = DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN)
-            )
+                dialog, touchSurface, cuj = DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN))
         }
 
-        verify(interactionJankMonitor).begin(
-            any()
-        )
-        verify(interactionJankMonitor)
-            .end(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN)
+        verify(interactionJankMonitor).begin(any())
+        verify(interactionJankMonitor).end(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN)
+    }
+
+    @Test
+    fun testShowFromDialogCujSpecificationLogsInteraction() {
+        val firstDialog = createAndShowDialog()
+        runOnMainThreadAndWaitForIdleSync {
+            val dialog = TestDialog(context)
+            dialogLaunchAnimator.showFromDialog(
+                dialog, firstDialog, cuj = DialogCuj(InteractionJankMonitor.CUJ_USER_DIALOG_OPEN))
+            dialog
+        }
+        verify(interactionJankMonitor).begin(any())
+        verify(interactionJankMonitor).end(InteractionJankMonitor.CUJ_USER_DIALOG_OPEN)
     }
 
     private fun createAndShowDialog(): TestDialog {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
index b61fbbe..273786d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
@@ -207,6 +207,25 @@
     }
 
     @Test
+    fun animatesInvisibleViews() {
+        rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
+        rootView.visibility = View.INVISIBLE
+
+        val success = ViewHierarchyAnimator.animate(rootView)
+        // Change all bounds.
+        rootView.layout(0 /* l */, 15 /* t */, 70 /* r */, 80 /* b */)
+
+        assertTrue(success)
+        assertNotNull(rootView.getTag(R.id.tag_animator))
+        // The initial values should be those of the previous layout.
+        checkBounds(rootView, l = 10, t = 10, r = 50, b = 50)
+        endAnimation(rootView)
+        assertNull(rootView.getTag(R.id.tag_animator))
+        // The end values should be those of the latest layout.
+        checkBounds(rootView, l = 0, t = 15, r = 70, b = 80)
+    }
+
+    @Test
     fun animatesAppearingViewsFromStartToEnd() {
         // Starting GONE.
         rootView.visibility = View.GONE
@@ -222,20 +241,6 @@
         assertNull(rootView.getTag(R.id.tag_animator))
         checkBounds(rootView, l = 0, t = 100, r = 100, b = 200)
 
-        // Starting INVISIBLE.
-        rootView.visibility = View.INVISIBLE
-        rootView.layout(0 /* l */, 50 /* t */, 50 /* r */, 100 /* b */)
-        success = ViewHierarchyAnimator.animateAddition(rootView)
-        rootView.visibility = View.VISIBLE
-        rootView.layout(0 /* l */, 100 /* t */, 100 /* r */, 200 /* b */)
-
-        assertTrue(success)
-        assertNotNull(rootView.getTag(R.id.tag_animator))
-        checkBounds(rootView, l = 50, t = 150, r = 50, b = 150)
-        endAnimation(rootView)
-        assertNull(rootView.getTag(R.id.tag_animator))
-        checkBounds(rootView, l = 0, t = 100, r = 100, b = 200)
-
         // Starting with nothing.
         rootView.layout(0 /* l */, 0 /* t */, 0 /* r */, 0 /* b */)
         success = ViewHierarchyAnimator.animateAddition(rootView)
@@ -937,7 +942,7 @@
     }
 
     @Test
-    fun doesNotAnimateInvisibleViews() {
+    fun doesNotAnimateGoneViews() {
         rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
 
         // GONE
@@ -948,15 +953,6 @@
         assertFalse(success)
         assertNull(rootView.getTag(R.id.tag_animator))
         checkBounds(rootView, l = 0, t = 15, r = 55, b = 80)
-
-        // INVISIBLE.
-        rootView.visibility = View.INVISIBLE
-        success = ViewHierarchyAnimator.animate(rootView)
-        rootView.layout(0 /* l */, 20 /* t */, 10 /* r */, 50 /* b */)
-
-        assertFalse(success)
-        assertNull(rootView.getTag(R.id.tag_animator))
-        checkBounds(rootView, l = 0, t = 20, r = 10, b = 50)
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
index bc5a4d3..bf3788e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -48,11 +48,12 @@
 import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.anyLong
 import org.mockito.Mockito.eq
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
-import org.mockito.junit.MockitoJUnit
 import org.mockito.Mockito.`when` as whenever
+import org.mockito.junit.MockitoJUnit
 
 @RunWith(AndroidTestingRunner::class)
 @RunWithLooper(setAsMainLooper = true)
@@ -87,7 +88,7 @@
     @Test
     fun testNotifiesAnimatedIn() {
         initializeFingerprintContainer()
-        verify(callback).onDialogAnimatedIn()
+        verify(callback).onDialogAnimatedIn(authContainer?.requestId ?: 0L)
     }
 
     @Test
@@ -96,13 +97,13 @@
         container.dismissFromSystemServer()
         waitForIdleSync()
 
-        verify(callback, never()).onDialogAnimatedIn()
+        verify(callback, never()).onDialogAnimatedIn(anyLong())
 
         container.addToView()
         waitForIdleSync()
 
         // attaching the view resets the state and allows this to happen again
-        verify(callback).onDialogAnimatedIn()
+        verify(callback).onDialogAnimatedIn(authContainer?.requestId ?: 0L)
     }
 
     @Test
@@ -110,14 +111,17 @@
         val container = initializeFingerprintContainer()
         waitForIdleSync()
 
-        verify(callback).onDialogAnimatedIn()
+        val requestID = authContainer?.requestId ?: 0L
+
+        verify(callback).onDialogAnimatedIn(requestID)
 
         container.onWindowFocusChanged(false)
         waitForIdleSync()
 
         verify(callback).onDismissed(
-            eq(AuthDialogCallback.DISMISSED_USER_CANCELED),
-            eq<ByteArray?>(null) /* credentialAttestation */
+                eq(AuthDialogCallback.DISMISSED_USER_CANCELED),
+                eq<ByteArray?>(null), /* credentialAttestation */
+                eq(requestID)
         )
         assertThat(container.parent).isNull()
     }
@@ -131,8 +135,9 @@
         waitForIdleSync()
 
         verify(callback).onDismissed(
-            eq(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED),
-            eq<ByteArray?>(null) /* credentialAttestation */
+                eq(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED),
+                eq<ByteArray?>(null), /* credentialAttestation */
+                eq(authContainer?.requestId ?: 0L)
         )
         assertThat(container.parent).isNull()
     }
@@ -146,11 +151,13 @@
         waitForIdleSync()
 
         verify(callback).onSystemEvent(
-            eq(BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL)
+                eq(BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL),
+                eq(authContainer?.requestId ?: 0L)
         )
         verify(callback).onDismissed(
-            eq(AuthDialogCallback.DISMISSED_USER_CANCELED),
-            eq<ByteArray?>(null) /* credentialAttestation */
+                eq(AuthDialogCallback.DISMISSED_USER_CANCELED),
+                eq<ByteArray?>(null), /* credentialAttestation */
+                eq(authContainer?.requestId ?: 0L)
         )
         assertThat(container.parent).isNull()
     }
@@ -164,8 +171,9 @@
         waitForIdleSync()
 
         verify(callback).onDismissed(
-            eq(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE),
-            eq<ByteArray?>(null) /* credentialAttestation */
+                eq(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE),
+                eq<ByteArray?>(null), /* credentialAttestation */
+                eq(authContainer?.requestId ?: 0L)
         )
         assertThat(container.parent).isNull()
     }
@@ -180,7 +188,7 @@
         )
         waitForIdleSync()
 
-        verify(callback).onTryAgainPressed()
+        verify(callback).onTryAgainPressed(authContainer?.requestId ?: 0L)
     }
 
     @Test
@@ -192,8 +200,9 @@
         waitForIdleSync()
 
         verify(callback).onDismissed(
-            eq(AuthDialogCallback.DISMISSED_ERROR),
-            eq<ByteArray?>(null) /* credentialAttestation */
+                eq(AuthDialogCallback.DISMISSED_ERROR),
+                eq<ByteArray?>(null), /* credentialAttestation */
+                eq(authContainer?.requestId ?: 0L)
         )
         assertThat(authContainer!!.parent).isNull()
     }
@@ -209,7 +218,7 @@
         )
         waitForIdleSync()
 
-        verify(callback).onDeviceCredentialPressed()
+        verify(callback).onDeviceCredentialPressed(authContainer?.requestId ?: 0L)
         assertThat(container.hasCredentialView()).isTrue()
     }
 
@@ -297,6 +306,16 @@
     }
 
     @Test
+    fun testLayoutParams_hasDimbehindWindowFlag() {
+        val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
+        val lpFlags = layoutParams.flags
+        val lpDimAmount = layoutParams.dimAmount
+
+        assertThat((lpFlags and WindowManager.LayoutParams.FLAG_DIM_BEHIND) != 0).isTrue()
+        assertThat(lpDimAmount).isGreaterThan(0f)
+    }
+
+    @Test
     fun testLayoutParams_excludesImeInsets() {
         val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
         assertThat((layoutParams.fitInsetsTypes and WindowInsets.Type.ime()) == 0).isTrue()
@@ -312,12 +331,12 @@
         container.onAuthenticationFailed(BiometricAuthenticator.TYPE_FACE, "failed")
         waitForIdleSync()
 
-        verify(callback, never()).onTryAgainPressed()
+        verify(callback, never()).onTryAgainPressed(anyLong())
 
         container.onPointerDown()
         waitForIdleSync()
 
-        verify(callback).onTryAgainPressed()
+        verify(callback).onTryAgainPressed(authContainer?.requestId ?: 0L)
     }
 
     private fun initializeFingerprintContainer(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index d948a99..d158892 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -291,7 +291,8 @@
     public void testSendsReasonUserCanceled_whenDismissedByUserCancel() throws Exception {
         showDialog(new int[]{1} /* sensorIds */, false /* credentialAllowed */);
         mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED,
-                null /* credentialAttestation */);
+                null, /* credentialAttestation */
+                mAuthController.mCurrentDialog.getRequestId());
         verify(mReceiver).onDialogDismissed(
                 eq(BiometricPrompt.DISMISSED_REASON_USER_CANCEL),
                 eq(null) /* credentialAttestation */);
@@ -301,7 +302,8 @@
     public void testSendsReasonNegative_whenDismissedByButtonNegative() throws Exception {
         showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
         mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE,
-                null /* credentialAttestation */);
+                null, /* credentialAttestation */
+                mAuthController.mCurrentDialog.getRequestId());
         verify(mReceiver).onDialogDismissed(
                 eq(BiometricPrompt.DISMISSED_REASON_NEGATIVE),
                 eq(null) /* credentialAttestation */);
@@ -311,7 +313,8 @@
     public void testSendsReasonConfirmed_whenDismissedByButtonPositive() throws Exception {
         showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
         mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BUTTON_POSITIVE,
-                null /* credentialAttestation */);
+                null, /* credentialAttestation */
+                mAuthController.mCurrentDialog.getRequestId());
         verify(mReceiver).onDialogDismissed(
                 eq(BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRMED),
                 eq(null) /* credentialAttestation */);
@@ -321,7 +324,8 @@
     public void testSendsReasonConfirmNotRequired_whenDismissedByAuthenticated() throws Exception {
         showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
         mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED,
-                null /* credentialAttestation */);
+                null, /* credentialAttestation */
+                mAuthController.mCurrentDialog.getRequestId());
         verify(mReceiver).onDialogDismissed(
                 eq(BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED),
                 eq(null) /* credentialAttestation */);
@@ -331,7 +335,8 @@
     public void testSendsReasonError_whenDismissedByError() throws Exception {
         showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
         mAuthController.onDismissed(AuthDialogCallback.DISMISSED_ERROR,
-                null /* credentialAttestation */);
+                null, /* credentialAttestation */
+                mAuthController.mCurrentDialog.getRequestId());
         verify(mReceiver).onDialogDismissed(
                 eq(BiometricPrompt.DISMISSED_REASON_ERROR),
                 eq(null) /* credentialAttestation */);
@@ -341,7 +346,8 @@
     public void testSendsReasonServerRequested_whenDismissedByServer() throws Exception {
         showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
         mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BY_SYSTEM_SERVER,
-                null /* credentialAttestation */);
+                null, /* credentialAttestation */
+                mAuthController.mCurrentDialog.getRequestId());
         verify(mReceiver).onDialogDismissed(
                 eq(BiometricPrompt.DISMISSED_REASON_SERVER_REQUESTED),
                 eq(null) /* credentialAttestation */);
@@ -355,7 +361,7 @@
         final byte[] credentialAttestation = generateRandomHAT();
 
         mAuthController.onDismissed(AuthDialogCallback.DISMISSED_CREDENTIAL_AUTHENTICATED,
-                credentialAttestation);
+                credentialAttestation, mAuthController.mCurrentDialog.getRequestId());
         verify(mReceiver).onDialogDismissed(
                 eq(BiometricPrompt.DISMISSED_REASON_CREDENTIAL_CONFIRMED),
                 AdditionalMatchers.aryEq(credentialAttestation));
@@ -531,7 +537,7 @@
         final byte[] credentialAttestation = generateRandomHAT();
 
         mAuthController.onDismissed(AuthDialogCallback.DISMISSED_CREDENTIAL_AUTHENTICATED,
-                credentialAttestation);
+                credentialAttestation, mAuthController.mCurrentDialog.getRequestId());
         verify(mReceiver).onDialogDismissed(
                 eq(BiometricPrompt.DISMISSED_REASON_CREDENTIAL_CONFIRMED),
                 AdditionalMatchers.aryEq(credentialAttestation));
@@ -640,17 +646,19 @@
     @Test
     public void testDoesNotCrash_whenTryAgainPressedAfterDismissal() {
         showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
+        final long requestID = mAuthController.mCurrentDialog.getRequestId();
         mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED,
-                null /* credentialAttestation */);
-        mAuthController.onTryAgainPressed();
+                null, /* credentialAttestation */requestID);
+        mAuthController.onTryAgainPressed(requestID);
     }
 
     @Test
     public void testDoesNotCrash_whenDeviceCredentialPressedAfterDismissal() {
         showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
+        final long requestID = mAuthController.mCurrentDialog.getRequestId();
         mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED,
-                null /* credentialAttestation */);
-        mAuthController.onDeviceCredentialPressed();
+                null /* credentialAttestation */, requestID);
+        mAuthController.onDeviceCredentialPressed(requestID);
     }
 
     @Test
@@ -708,7 +716,8 @@
         // WHEN dialog is shown and then dismissed
         showDialog(new int[]{1} /* sensorIds */, false /* credentialAllowed */);
         mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED,
-                null /* credentialAttestation */);
+                null /* credentialAttestation */,
+                mAuthController.mCurrentDialog.getRequestId());
 
         // THEN callback should be received
         verify(callback).onBiometricPromptDismissed();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/OWNERS b/packages/SystemUI/tests/src/com/android/systemui/biometrics/OWNERS
new file mode 100644
index 0000000..adb10f0
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/OWNERS
@@ -0,0 +1,4 @@
+set noparent
+
+include /services/core/java/com/android/server/biometrics/OWNERS
+beverlyt@google.com
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
index dec2b82..6157ccb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
@@ -62,7 +62,6 @@
 import org.mockito.ArgumentMatchers.eq
 import org.mockito.Captor
 import org.mockito.Mock
-import org.mockito.Mockito.`when`
 import org.mockito.Mockito.any
 import org.mockito.Mockito.anyFloat
 import org.mockito.Mockito.anyInt
@@ -72,6 +71,7 @@
 import org.mockito.Mockito.reset
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenEver
 import org.mockito.junit.MockitoJUnit
 
 private const val DISPLAY_ID = 2
@@ -126,15 +126,15 @@
         context.addMockSystemService(DisplayManager::class.java, displayManager)
         context.addMockSystemService(WindowManager::class.java, windowManager)
 
-        `when`(layoutInflater.inflate(R.layout.sidefps_view, null, false)).thenReturn(sidefpsView)
-        `when`(sidefpsView.findViewById<LottieAnimationView>(eq(R.id.sidefps_animation)))
+        whenEver(layoutInflater.inflate(R.layout.sidefps_view, null, false)).thenReturn(sidefpsView)
+        whenEver(sidefpsView.findViewById<LottieAnimationView>(eq(R.id.sidefps_animation)))
             .thenReturn(mock(LottieAnimationView::class.java))
         with(mock(ViewPropertyAnimator::class.java)) {
-            `when`(sidefpsView.animate()).thenReturn(this)
-            `when`(alpha(anyFloat())).thenReturn(this)
-            `when`(setStartDelay(anyLong())).thenReturn(this)
-            `when`(setDuration(anyLong())).thenReturn(this)
-            `when`(setListener(any())).thenAnswer {
+            whenEver(sidefpsView.animate()).thenReturn(this)
+            whenEver(alpha(anyFloat())).thenReturn(this)
+            whenEver(setStartDelay(anyLong())).thenReturn(this)
+            whenEver(setDuration(anyLong())).thenReturn(this)
+            whenEver(setListener(any())).thenAnswer {
                 (it.arguments[0] as Animator.AnimatorListener)
                     .onAnimationEnd(mock(Animator::class.java))
                 this
@@ -177,7 +177,7 @@
         displayBounds = Rect(0, 0, displayWidth, displayHeight)
         var locations = listOf(sensorLocation)
 
-        `when`(fingerprintManager.sensorPropertiesInternal).thenReturn(
+        whenEver(fingerprintManager.sensorPropertiesInternal).thenReturn(
             listOf(
                 FingerprintSensorPropertiesInternal(
                     SENSOR_ID,
@@ -196,12 +196,12 @@
         displayInfo.initInfo()
         val dmGlobal = mock(DisplayManagerGlobal::class.java)
         val display = Display(dmGlobal, DISPLAY_ID, displayInfo, DEFAULT_DISPLAY_ADJUSTMENTS)
-        `when`(dmGlobal.getDisplayInfo(eq(DISPLAY_ID))).thenReturn(displayInfo)
-        `when`(windowManager.defaultDisplay).thenReturn(display)
-        `when`(windowManager.maximumWindowMetrics).thenReturn(
+        whenEver(dmGlobal.getDisplayInfo(eq(DISPLAY_ID))).thenReturn(displayInfo)
+        whenEver(windowManager.defaultDisplay).thenReturn(display)
+        whenEver(windowManager.maximumWindowMetrics).thenReturn(
                 WindowMetrics(displayBounds, WindowInsets.CONSUMED)
         )
-        `when`(windowManager.currentWindowMetrics).thenReturn(
+        whenEver(windowManager.currentWindowMetrics).thenReturn(
             WindowMetrics(displayBounds, windowInsets)
         )
 
@@ -277,13 +277,13 @@
 
     @Test
     fun testShowsForMostSettings() = testWithDisplay {
-        `when`(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpEnrollTask()))
+        whenEver(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpEnrollTask()))
         testIgnoredFor(REASON_AUTH_SETTINGS, ignored = false)
     }
 
     @Test
     fun testIgnoredForVerySpecificSettings() = testWithDisplay {
-        `when`(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpSettingsTask()))
+        whenEver(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpSettingsTask()))
         testIgnoredFor(REASON_AUTH_SETTINGS)
     }
 
@@ -424,6 +424,20 @@
         assertThat(overlayViewParamsCaptor.value.x).isEqualTo(displayWidth - boundsWidth)
         assertThat(overlayViewParamsCaptor.value.y).isEqualTo(sensorLocation.sensorLocationY)
     }
+
+    @Test
+    fun hasSideFpsSensor_withSensorProps_returnsTrue() = testWithDisplay {
+        // By default all those tests assume the side fps sensor is available.
+
+        assertThat(fingerprintManager.hasSideFpsSensor()).isTrue()
+    }
+
+    @Test
+    fun hasSideFpsSensor_withoutSensorProps_returnsFalse() {
+        whenEver(fingerprintManager.sensorPropertiesInternal).thenReturn(null)
+
+        assertThat(fingerprintManager.hasSideFpsSensor()).isFalse()
+    }
 }
 
 private fun insetsForSmallNavbar() = insetsWithBottom(60)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index 638e6f3..d7a0a0a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -414,37 +414,43 @@
         final UdfpsOverlayParams oldParams = new UdfpsOverlayParams(sensorBounds[0],
                 displayWidth[0], displayHeight[0], scaleFactor[0], rotation[0]);
 
-        for (int i1 = 0; i1 <= 1; ++i1)
-        for (int i2 = 0; i2 <= 1; ++i2)
-        for (int i3 = 0; i3 <= 1; ++i3)
-        for (int i4 = 0; i4 <= 1; ++i4)
-        for (int i5 = 0; i5 <= 1; ++i5) {
-            final UdfpsOverlayParams newParams = new UdfpsOverlayParams(sensorBounds[i1],
-                    displayWidth[i2], displayHeight[i3], scaleFactor[i4], rotation[i5]);
+        for (int i1 = 0; i1 <= 1; ++i1) {
+            for (int i2 = 0; i2 <= 1; ++i2) {
+                for (int i3 = 0; i3 <= 1; ++i3) {
+                    for (int i4 = 0; i4 <= 1; ++i4) {
+                        for (int i5 = 0; i5 <= 1; ++i5) {
+                            final UdfpsOverlayParams newParams = new UdfpsOverlayParams(
+                                    sensorBounds[i1], displayWidth[i2], displayHeight[i3],
+                                    scaleFactor[i4], rotation[i5]);
 
-            if (newParams.equals(oldParams)) {
-                continue;
+                            if (newParams.equals(oldParams)) {
+                                continue;
+                            }
+
+                            // Initialize the overlay with old parameters.
+                            mUdfpsController.updateOverlayParams(TEST_UDFPS_SENSOR_ID, oldParams);
+
+                            // Show the overlay.
+                            reset(mWindowManager);
+                            mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID,
+                                    TEST_UDFPS_SENSOR_ID,
+                                    BiometricOverlayConstants.REASON_ENROLL_ENROLLING,
+                                    mUdfpsOverlayControllerCallback);
+                            mFgExecutor.runAllReady();
+                            verify(mWindowManager).addView(any(), any());
+
+                            // Update overlay parameters.
+                            reset(mWindowManager);
+                            mUdfpsController.updateOverlayParams(TEST_UDFPS_SENSOR_ID, newParams);
+                            mFgExecutor.runAllReady();
+
+                            // Ensure the overlay was recreated.
+                            verify(mWindowManager).removeView(any());
+                            verify(mWindowManager).addView(any(), any());
+                        }
+                    }
+                }
             }
-
-            // Initialize the overlay with old parameters.
-            mUdfpsController.updateOverlayParams(TEST_UDFPS_SENSOR_ID, oldParams);
-
-            // Show the overlay.
-            reset(mWindowManager);
-            mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID,
-                    BiometricOverlayConstants.REASON_ENROLL_ENROLLING,
-                    mUdfpsOverlayControllerCallback);
-            mFgExecutor.runAllReady();
-            verify(mWindowManager).addView(any(), any());
-
-            // Update overlay parameters.
-            reset(mWindowManager);
-            mUdfpsController.updateOverlayParams(TEST_UDFPS_SENSOR_ID, newParams);
-            mFgExecutor.runAllReady();
-
-            // Ensure the overlay was recreated.
-            verify(mWindowManager).removeView(any());
-            verify(mWindowManager).addView(any(), any());
         }
     }
 
@@ -740,12 +746,12 @@
                 anyString(),
                 any(),
                 eq("udfps-onStart-click"),
-                eq(UdfpsController.VIBRATION_ATTRIBUTES));
+                eq(UdfpsController.UDFPS_VIBRATION_ATTRIBUTES));
 
         // THEN make sure vibration attributes has so that it always will play the haptic,
         // even in battery saver mode
         assertEquals(VibrationAttributes.USAGE_COMMUNICATION_REQUEST,
-                UdfpsController.VIBRATION_ATTRIBUTES.getUsage());
+                UdfpsController.UDFPS_VIBRATION_ATTRIBUTES.getUsage());
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/camera/CameraGestureHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/camera/CameraGestureHelperTest.kt
new file mode 100644
index 0000000..ca94ea8
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/camera/CameraGestureHelperTest.kt
@@ -0,0 +1,311 @@
+/*
+ * 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 com.android.systemui.camera
+
+import android.app.ActivityManager
+import android.app.IActivityTaskManager
+import android.content.ComponentName
+import android.content.ContentResolver
+import android.content.Intent
+import android.content.pm.ActivityInfo
+import android.content.pm.PackageManager
+import android.content.pm.ResolveInfo
+import androidx.test.filters.SmallTest
+import com.android.systemui.ActivityIntentHelper
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.phone.CentralSurfaces
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.util.mockito.KotlinArgumentCaptor
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
+import com.google.common.truth.Truth.assertThat
+import com.google.common.util.concurrent.MoreExecutors
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.Mock
+import org.mockito.Mockito.any
+import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(JUnit4::class)
+class CameraGestureHelperTest : SysuiTestCase() {
+
+    @Mock
+    lateinit var centralSurfaces: CentralSurfaces
+    @Mock
+    lateinit var keyguardStateController: KeyguardStateController
+    @Mock
+    lateinit var packageManager: PackageManager
+    @Mock
+    lateinit var activityManager: ActivityManager
+    @Mock
+    lateinit var activityStarter: ActivityStarter
+    @Mock
+    lateinit var activityIntentHelper: ActivityIntentHelper
+    @Mock
+    lateinit var activityTaskManager: IActivityTaskManager
+    @Mock
+    lateinit var cameraIntents: CameraIntentsWrapper
+    @Mock
+    lateinit var contentResolver: ContentResolver
+
+    private lateinit var underTest: CameraGestureHelper
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        whenever(cameraIntents.getSecureCameraIntent()).thenReturn(
+            Intent(CameraIntents.DEFAULT_SECURE_CAMERA_INTENT_ACTION)
+        )
+        whenever(cameraIntents.getInsecureCameraIntent()).thenReturn(
+            Intent(CameraIntents.DEFAULT_INSECURE_CAMERA_INTENT_ACTION)
+        )
+
+        prepare()
+
+        underTest = CameraGestureHelper(
+            context = mock(),
+            centralSurfaces = centralSurfaces,
+            keyguardStateController = keyguardStateController,
+            packageManager = packageManager,
+            activityManager = activityManager,
+            activityStarter = activityStarter,
+            activityIntentHelper = activityIntentHelper,
+            activityTaskManager = activityTaskManager,
+            cameraIntents = cameraIntents,
+            contentResolver = contentResolver,
+            uiExecutor = MoreExecutors.directExecutor(),
+        )
+    }
+
+    /**
+     * Prepares for tests by setting up the various mocks to emulate a specific device state.
+     *
+     * <p>Safe to call multiple times in a single test (for example, once in [setUp] and once in the
+     * actual test case).
+     *
+     * @param isCameraAllowedByAdmin Whether the device administrator allows use of the camera app
+     * @param installedCameraAppCount The number of installed camera apps on the device
+     * @param isUsingSecureScreenLockOption Whether the user-controlled setting for Screen Lock is
+     * set with a "secure" option that requires the user to provide some secret/credentials to be
+     * able to unlock the device, for example "Face Unlock", "PIN", or "Password". Examples of
+     * non-secure options are "None" and "Swipe"
+     * @param isCameraActivityRunningOnTop Whether the camera activity is running at the top of the
+     * most recent/current task of activities
+     * @param isTaskListEmpty Whether there are no active activity tasks at all. Note that this is
+     * treated as `false` if [isCameraActivityRunningOnTop] is set to `true`
+     */
+    private fun prepare(
+        isCameraAllowedByAdmin: Boolean = true,
+        installedCameraAppCount: Int = 1,
+        isUsingSecureScreenLockOption: Boolean = true,
+        isCameraActivityRunningOnTop: Boolean = false,
+        isTaskListEmpty: Boolean = false,
+    ) {
+        whenever(centralSurfaces.isCameraAllowedByAdmin).thenReturn(isCameraAllowedByAdmin)
+
+        whenever(activityIntentHelper.wouldLaunchResolverActivity(any(), anyInt()))
+            .thenReturn(installedCameraAppCount > 1)
+
+        whenever(keyguardStateController.isMethodSecure).thenReturn(isUsingSecureScreenLockOption)
+        whenever(keyguardStateController.canDismissLockScreen())
+            .thenReturn(!isUsingSecureScreenLockOption)
+
+        if (installedCameraAppCount >= 1) {
+            val resolveInfo = ResolveInfo().apply {
+                this.activityInfo = ActivityInfo().apply {
+                    packageName = CAMERA_APP_PACKAGE_NAME
+                }
+            }
+            whenever(packageManager.resolveActivityAsUser(any(), anyInt(), anyInt())).thenReturn(
+                resolveInfo
+            )
+        } else {
+            whenever(packageManager.resolveActivityAsUser(any(), anyInt(), anyInt())).thenReturn(
+                null
+            )
+        }
+
+        when {
+            isCameraActivityRunningOnTop -> {
+                val runningTaskInfo = ActivityManager.RunningTaskInfo().apply {
+                    topActivity = ComponentName(CAMERA_APP_PACKAGE_NAME, "cameraActivity")
+                }
+                whenever(activityManager.getRunningTasks(anyInt())).thenReturn(
+                    listOf(
+                        runningTaskInfo
+                    )
+                )
+            }
+            isTaskListEmpty -> {
+                whenever(activityManager.getRunningTasks(anyInt())).thenReturn(emptyList())
+            }
+            else -> {
+                whenever(activityManager.getRunningTasks(anyInt())).thenReturn(listOf())
+            }
+        }
+    }
+
+    @Test
+    fun `canCameraGestureBeLaunched - status bar state is keyguard - returns true`() {
+        assertThat(underTest.canCameraGestureBeLaunched(StatusBarState.KEYGUARD)).isTrue()
+    }
+
+    @Test
+    fun `canCameraGestureBeLaunched - state is shade-locked - returns true`() {
+        assertThat(underTest.canCameraGestureBeLaunched(StatusBarState.SHADE_LOCKED)).isTrue()
+    }
+
+    @Test
+    fun `canCameraGestureBeLaunched - state is keyguard - camera activity on top - returns true`() {
+        prepare(isCameraActivityRunningOnTop = true)
+
+        assertThat(underTest.canCameraGestureBeLaunched(StatusBarState.KEYGUARD)).isTrue()
+    }
+
+    @Test
+    fun `canCameraGestureBeLaunched - state is shade-locked - camera activity on top - true`() {
+        prepare(isCameraActivityRunningOnTop = true)
+
+        assertThat(underTest.canCameraGestureBeLaunched(StatusBarState.SHADE_LOCKED)).isTrue()
+    }
+
+    @Test
+    fun `canCameraGestureBeLaunched - not allowed by admin - returns false`() {
+        prepare(isCameraAllowedByAdmin = false)
+
+        assertThat(underTest.canCameraGestureBeLaunched(StatusBarState.KEYGUARD)).isFalse()
+    }
+
+    @Test
+    fun `canCameraGestureBeLaunched - intent does not resolve to any app - returns false`() {
+        prepare(installedCameraAppCount = 0)
+
+        assertThat(underTest.canCameraGestureBeLaunched(StatusBarState.KEYGUARD)).isFalse()
+    }
+
+    @Test
+    fun `canCameraGestureBeLaunched - state is shade - no running tasks - returns true`() {
+        prepare(isCameraActivityRunningOnTop = false, isTaskListEmpty = true)
+
+        assertThat(underTest.canCameraGestureBeLaunched(StatusBarState.SHADE)).isTrue()
+    }
+
+    @Test
+    fun `canCameraGestureBeLaunched - state is shade - camera activity on top - returns false`() {
+        prepare(isCameraActivityRunningOnTop = true)
+
+        assertThat(underTest.canCameraGestureBeLaunched(StatusBarState.SHADE)).isFalse()
+    }
+
+    @Test
+    fun `canCameraGestureBeLaunched - state is shade - camera activity not on top - true`() {
+        assertThat(underTest.canCameraGestureBeLaunched(StatusBarState.SHADE)).isTrue()
+    }
+
+    @Test
+    fun `launchCamera - only one camera app installed - using secure screen lock option`() {
+        val source = 1337
+
+        underTest.launchCamera(source)
+
+        assertActivityStarting(isSecure = true, source = source)
+    }
+
+    @Test
+    fun `launchCamera - only one camera app installed - using non-secure screen lock option`() {
+        prepare(isUsingSecureScreenLockOption = false)
+        val source = 1337
+
+        underTest.launchCamera(source)
+
+        assertActivityStarting(isSecure = false, source = source)
+    }
+
+    @Test
+    fun `launchCamera - multiple camera apps installed - using secure screen lock option`() {
+        prepare(installedCameraAppCount = 2)
+        val source = 1337
+
+        underTest.launchCamera(source)
+
+        assertActivityStarting(
+            isSecure = true,
+            source = source,
+            moreThanOneCameraAppInstalled = true
+        )
+    }
+
+    @Test
+    fun `launchCamera - multiple camera apps installed - using non-secure screen lock option`() {
+        prepare(
+            isUsingSecureScreenLockOption = false,
+            installedCameraAppCount = 2,
+        )
+        val source = 1337
+
+        underTest.launchCamera(source)
+
+        assertActivityStarting(
+            isSecure = false,
+            moreThanOneCameraAppInstalled = true,
+            source = source
+        )
+    }
+
+    private fun assertActivityStarting(
+        isSecure: Boolean,
+        source: Int,
+        moreThanOneCameraAppInstalled: Boolean = false,
+    ) {
+        val intentCaptor = KotlinArgumentCaptor(Intent::class.java)
+        if (isSecure && !moreThanOneCameraAppInstalled) {
+            verify(activityTaskManager).startActivityAsUser(
+                any(),
+                any(),
+                any(),
+                intentCaptor.capture(),
+                any(),
+                any(),
+                any(),
+                anyInt(),
+                anyInt(),
+                any(),
+                any(),
+                anyInt()
+            )
+        } else {
+            verify(activityStarter).startActivity(intentCaptor.capture(), eq(false))
+        }
+        val intent = intentCaptor.value
+
+        assertThat(CameraIntents.isSecureCameraIntent(intent)).isEqualTo(isSecure)
+        assertThat(intent.getIntExtra(CameraGestureHelper.EXTRA_CAMERA_LAUNCH_SOURCE, -1))
+            .isEqualTo(source)
+    }
+
+    companion object {
+        private const val CAMERA_APP_PACKAGE_NAME = "cameraAppPackageName"
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt
index 3c7ea4f..c31fd82 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt
@@ -37,9 +37,14 @@
 import com.android.systemui.controls.management.ControlsListingController
 import com.android.systemui.controls.ui.ControlsUiController
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.settings.UserFileManager
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import java.io.File
+import java.util.Optional
+import java.util.function.Consumer
 import org.junit.After
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
@@ -50,20 +55,20 @@
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
 import org.mockito.ArgumentMatchers
+import org.mockito.ArgumentMatchers.anyString
 import org.mockito.Captor
 import org.mockito.Mock
 import org.mockito.Mockito
 import org.mockito.Mockito.anyInt
-import org.mockito.Mockito.`when`
 import org.mockito.Mockito.inOrder
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.reset
+import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
-import java.util.Optional
-import java.util.function.Consumer
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
@@ -85,6 +90,8 @@
     private lateinit var listingController: ControlsListingController
     @Mock(stubOnly = true)
     private lateinit var userTracker: UserTracker
+    @Mock
+    private lateinit var userFileManager: UserFileManager
 
     @Captor
     private lateinit var structureInfoCaptor: ArgumentCaptor<StructureInfo>
@@ -153,6 +160,9 @@
 
         canceller = DidRunRunnable()
         `when`(bindingController.bindAndLoad(any(), any())).thenReturn(canceller)
+        `when`(userFileManager.getFile(anyString(), anyInt())).thenReturn(mock(File::class.java))
+        `when`(userFileManager.getSharedPreferences(anyString(), anyInt(), anyInt()))
+            .thenReturn(context.getSharedPreferences("test", Context.MODE_PRIVATE))
 
         controller = ControlsControllerImpl(
                 wrapper,
@@ -161,6 +171,7 @@
                 bindingController,
                 listingController,
                 broadcastDispatcher,
+                userFileManager,
                 Optional.of(persistenceWrapper),
                 mock(DumpManager::class.java),
                 userTracker
@@ -217,6 +228,7 @@
                 bindingController,
                 listingController,
                 broadcastDispatcher,
+                userFileManager,
                 Optional.of(persistenceWrapper),
                 mock(DumpManager::class.java),
                 userTracker
@@ -911,6 +923,14 @@
 
         assertTrue(controller.getFavoritesForStructure(TEST_COMPONENT_2, TEST_STRUCTURE).isEmpty())
     }
+
+    @Test
+    fun testUserStructure() {
+        val userStructure = UserStructure(context, context.user, userFileManager)
+        verify(userFileManager, times(2))
+            .getFile(ControlsFavoritePersistenceWrapper.FILE_NAME, context.user.identifier)
+        assertThat(userStructure.file).isNotNull()
+    }
 }
 
 private class DidRunRunnable() : Runnable {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/CutoutDecorProviderFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/CutoutDecorProviderFactoryTest.kt
deleted file mode 100644
index 1040ec4..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/decor/CutoutDecorProviderFactoryTest.kt
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.decor
-
-import android.graphics.Insets
-import android.graphics.Rect
-import android.testing.AndroidTestingRunner
-import android.testing.TestableResources
-import android.util.RotationUtils
-import android.util.Size
-import android.view.Display
-import android.view.DisplayCutout
-import android.view.DisplayCutout.BOUNDS_POSITION_LENGTH
-import android.view.DisplayInfo
-import android.view.Surface
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.util.mockito.any
-import org.junit.Assert
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Mockito.doAnswer
-import org.mockito.MockitoAnnotations
-
-@RunWith(AndroidTestingRunner::class)
-@SmallTest
-class CutoutDecorProviderFactoryTest : SysuiTestCase() {
-
-    @Mock private lateinit var display: Display
-    private var testableRes: TestableResources? = null
-    private lateinit var factory: CutoutDecorProviderFactory
-
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-        testableRes = mContext.orCreateTestableResources
-        factory = CutoutDecorProviderFactory(testableRes!!.resources, display)
-    }
-
-    private fun setupFillCutout(fillCutout: Boolean) {
-        testableRes!!.addOverride(
-            com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, fillCutout
-        )
-    }
-
-    private fun setupDisplayInfo(
-        displayCutout: DisplayCutout? = null,
-        @Surface.Rotation rotation: Int = Surface.ROTATION_0,
-        displayId: Int = -1
-    ) {
-        doAnswer {
-            it.getArgument<DisplayInfo>(0).let { info ->
-                info.displayCutout = displayCutout
-                info.rotation = rotation
-                info.displayId = displayId
-            }
-            true
-        }.`when`(display).getDisplayInfo(any<DisplayInfo>())
-    }
-
-    private fun getCutout(
-        safeInsets: Insets,
-        cutoutBounds: Array<Rect?>,
-        @Surface.Rotation rotation: Int = Surface.ROTATION_0,
-        cutoutParentSizeForRotate: Size = Size(100, 200)
-    ): DisplayCutout {
-        val insets = RotationUtils.rotateInsets(safeInsets, rotation)
-        val sorted = arrayOfNulls<Rect>(BOUNDS_POSITION_LENGTH)
-        for (pos in 0 until BOUNDS_POSITION_LENGTH) {
-            val rotatedPos = (pos - rotation + BOUNDS_POSITION_LENGTH) % BOUNDS_POSITION_LENGTH
-            if (cutoutBounds[pos] != null) {
-                RotationUtils.rotateBounds(
-                    cutoutBounds[pos],
-                    cutoutParentSizeForRotate.width,
-                    cutoutParentSizeForRotate.height,
-                    rotation
-                )
-            }
-            sorted[rotatedPos] = cutoutBounds[pos]
-        }
-        return DisplayCutout(
-            insets,
-            sorted[DisplayCutout.BOUNDS_POSITION_LEFT],
-            sorted[DisplayCutout.BOUNDS_POSITION_TOP],
-            sorted[DisplayCutout.BOUNDS_POSITION_RIGHT],
-            sorted[DisplayCutout.BOUNDS_POSITION_BOTTOM]
-        )
-    }
-
-    @Test
-    fun testGetNothingIfNoCutout() {
-        setupFillCutout(false)
-
-        Assert.assertFalse(factory.hasProviders)
-        Assert.assertEquals(0, factory.providers.size)
-    }
-
-    @Test
-    fun testGetTopCutoutProvider() {
-        setupFillCutout(true)
-        setupDisplayInfo(
-            getCutout(
-                safeInsets = Insets.of(0, 1, 0, 0),
-                cutoutBounds = arrayOf(null, Rect(9, 0, 10, 1), null, null)
-            )
-        )
-
-        Assert.assertTrue(factory.hasProviders)
-
-        val providers = factory.providers
-        Assert.assertEquals(1, providers.size)
-        Assert.assertEquals(1, providers[0].numOfAlignedBound)
-        Assert.assertEquals(DisplayCutout.BOUNDS_POSITION_TOP, providers[0].alignedBounds[0])
-    }
-
-    @Test
-    fun testGetBottomCutoutProviderOnLandscape() {
-        setupFillCutout(true)
-        setupDisplayInfo(
-            getCutout(
-                safeInsets = Insets.of(0, 0, 0, 1),
-                cutoutBounds = arrayOf(null, null, null, Rect(45, 199, 55, 200)),
-                rotation = Surface.ROTATION_90
-            ),
-            Surface.ROTATION_90
-        )
-
-        Assert.assertTrue(factory.hasProviders)
-
-        val providers = factory.providers
-        Assert.assertEquals(1, providers.size)
-        Assert.assertEquals(1, providers[0].numOfAlignedBound)
-        Assert.assertEquals(DisplayCutout.BOUNDS_POSITION_BOTTOM, providers[0].alignedBounds[0])
-    }
-
-    @Test
-    fun testGetLeftCutoutProviderOnSeascape() {
-        setupFillCutout(true)
-        setupDisplayInfo(
-            getCutout(
-                safeInsets = Insets.of(1, 0, 0, 0),
-                cutoutBounds = arrayOf(Rect(0, 20, 1, 40), null, null, null),
-                rotation = Surface.ROTATION_270
-            ),
-            Surface.ROTATION_270
-        )
-
-        Assert.assertTrue(factory.hasProviders)
-
-        val providers = factory.providers
-        Assert.assertEquals(1, providers.size)
-        Assert.assertEquals(1, providers[0].numOfAlignedBound)
-        Assert.assertEquals(DisplayCutout.BOUNDS_POSITION_LEFT, providers[0].alignedBounds[0])
-    }
-
-    @Test
-    fun testGetTopRightCutoutProviderOnReverse() {
-        setupFillCutout(true)
-        setupDisplayInfo(
-            getCutout(
-                safeInsets = Insets.of(0, 1, 1, 0),
-                cutoutBounds = arrayOf(
-                    null,
-                    Rect(9, 0, 10, 1),
-                    Rect(99, 40, 100, 60),
-                    null
-                ),
-                rotation = Surface.ROTATION_180
-            ),
-            Surface.ROTATION_180
-        )
-
-        Assert.assertTrue(factory.hasProviders)
-
-        val providers = factory.providers
-        Assert.assertEquals(2, providers.size)
-        Assert.assertEquals(1, providers[0].numOfAlignedBound)
-        Assert.assertEquals(1, providers[1].numOfAlignedBound)
-        providers.sortedBy { it.alignedBounds[0] }.let {
-            Assert.assertEquals(DisplayCutout.BOUNDS_POSITION_TOP, it[0].alignedBounds[0])
-            Assert.assertEquals(DisplayCutout.BOUNDS_POSITION_RIGHT, it[1].alignedBounds[0])
-        }
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
index e5a75e2..49cdfa7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
@@ -86,7 +86,7 @@
         mHandler = mHandlerThread.getThreadHandler();
 
         mDozeUi = new DozeUi(mContext, mAlarmManager, mWakeLock, mHost, mHandler,
-                mDozeParameters, mKeyguardUpdateMonitor, mStatusBarStateController, mDozeLog);
+                mDozeParameters, mStatusBarStateController, mDozeLog);
         mDozeUi.setDozeMachine(mMachine);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
index d334694..60e5a94 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
@@ -184,6 +184,28 @@
     }
 
     @Test
+    public void testOnViewAttachedShowsMicIconWhenDisabled() {
+        when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE))
+                .thenReturn(true);
+        when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA))
+                .thenReturn(false);
+        mController.onViewAttached();
+        verify(mView).showIcon(
+                DreamOverlayStatusBarView.STATUS_ICON_MIC_DISABLED, true, null);
+    }
+
+    @Test
+    public void testOnViewAttachedShowsCameraIconWhenDisabled() {
+        when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE))
+                .thenReturn(false);
+        when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA))
+                .thenReturn(true);
+        mController.onViewAttached();
+        verify(mView).showIcon(
+                DreamOverlayStatusBarView.STATUS_ICON_CAMERA_DISABLED, true, null);
+    }
+
+    @Test
     public void testOnViewAttachedShowsMicCameraIconWhenDisabled() {
         when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE))
                 .thenReturn(true);
@@ -195,17 +217,6 @@
     }
 
     @Test
-    public void testOnViewAttachedHidesMicCameraIconWhenEnabled() {
-        when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE))
-                .thenReturn(false);
-        when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA))
-                .thenReturn(false);
-        mController.onViewAttached();
-        verify(mView).showIcon(
-                DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED, false, null);
-    }
-
-    @Test
     public void testOnViewAttachedShowsNotificationsIconWhenNotificationsExist() {
         mController.onViewAttached();
 
@@ -386,24 +397,6 @@
     }
 
     @Test
-    public void testMicCameraIconHiddenWhenSensorsNotBlocked() {
-        when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE))
-                .thenReturn(true).thenReturn(false);
-        when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA))
-                .thenReturn(true).thenReturn(false);
-        mController.onViewAttached();
-
-        final ArgumentCaptor<IndividualSensorPrivacyController.Callback> callbackCapture =
-                ArgumentCaptor.forClass(IndividualSensorPrivacyController.Callback.class);
-        verify(mSensorPrivacyController).addCallback(callbackCapture.capture());
-        callbackCapture.getValue().onSensorBlockedChanged(
-                SensorPrivacyManager.Sensors.MICROPHONE, false);
-
-        verify(mView).showIcon(
-                DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED, false, null);
-    }
-
-    @Test
     public void testPriorityModeIconShownWhenZenModeEnabled() {
         mController.onViewAttached();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/AirQualityColorPickerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/AirQualityColorPickerTest.java
deleted file mode 100644
index 33be5dc..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/AirQualityColorPickerTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.dreams.complication;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.testing.AndroidTestingRunner;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-public class AirQualityColorPickerTest extends SysuiTestCase {
-    private static final int DEFAULT_COLOR = 0;
-    private static final int MOCK_COLOR_1 = 1;
-    private static final int MOCK_COLOR_2 = 2;
-    private static final int MOCK_COLOR_3 = 3;
-    private static final int MOCK_COLOR_4 = 4;
-    private static final int MOCK_COLOR_5 = 5;
-
-    private static final int[] MOCK_THRESHOLDS = {-1, 100, 200, 201, 500};
-    private static final int[] MOCK_COLORS =
-            {MOCK_COLOR_1, MOCK_COLOR_2, MOCK_COLOR_3, MOCK_COLOR_4, MOCK_COLOR_5};
-    private static final int[] EMPTY_ARRAY = {};
-
-    @Test
-    public void testEmptyThresholds() {
-        final AirQualityColorPicker colorPicker = new AirQualityColorPicker(
-                EMPTY_ARRAY,
-                MOCK_COLORS,
-                DEFAULT_COLOR);
-        assertThat(colorPicker.getColorForValue("110 AQI")).isEqualTo(DEFAULT_COLOR);
-    }
-
-    @Test
-    public void testEmptyColors() {
-        final AirQualityColorPicker colorPicker = new AirQualityColorPicker(
-                MOCK_THRESHOLDS,
-                EMPTY_ARRAY,
-                DEFAULT_COLOR);
-        assertThat(colorPicker.getColorForValue("110 AQI")).isEqualTo(DEFAULT_COLOR);
-    }
-
-    @Test
-    public void testEmptyAqiString() {
-        final AirQualityColorPicker colorPicker = new AirQualityColorPicker(
-                MOCK_THRESHOLDS,
-                MOCK_COLORS,
-                DEFAULT_COLOR);
-        assertThat(colorPicker.getColorForValue("")).isEqualTo(DEFAULT_COLOR);
-    }
-
-    @Test
-    public void testInvalidAqiString() {
-        final AirQualityColorPicker colorPicker = new AirQualityColorPicker(
-                MOCK_THRESHOLDS,
-                MOCK_COLORS,
-                DEFAULT_COLOR);
-        assertThat(colorPicker.getColorForValue("invalid")).isEqualTo(DEFAULT_COLOR);
-    }
-
-    @Test
-    public void testZeroAirQuality() {
-        final AirQualityColorPicker colorPicker = new AirQualityColorPicker(
-                MOCK_THRESHOLDS,
-                MOCK_COLORS,
-                DEFAULT_COLOR);
-        assertThat(colorPicker.getColorForValue("0 AQI")).isEqualTo(MOCK_COLOR_1);
-    }
-
-    @Test
-    public void testVeryLargeAirQuality() {
-        final AirQualityColorPicker colorPicker = new AirQualityColorPicker(
-                MOCK_THRESHOLDS,
-                MOCK_COLORS,
-                DEFAULT_COLOR);
-        assertThat(colorPicker.getColorForValue("100000 AQI")).isEqualTo(MOCK_COLOR_5);
-    }
-
-    @Test
-    public void testAirQuality200() {
-        final AirQualityColorPicker colorPicker = new AirQualityColorPicker(
-                MOCK_THRESHOLDS,
-                MOCK_COLORS,
-                DEFAULT_COLOR);
-        assertThat(colorPicker.getColorForValue("200 AQI")).isEqualTo(MOCK_COLOR_2);
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamAirQualityComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamAirQualityComplicationTest.java
deleted file mode 100644
index b8a7059..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamAirQualityComplicationTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.dreams.complication;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.testing.AndroidTestingRunner;
-import android.widget.TextView;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.dreams.DreamOverlayStateController;
-import com.android.systemui.dreams.complication.DreamAirQualityComplication.DreamAirQualityViewController;
-import com.android.systemui.dreams.smartspace.DreamSmartspaceController;
-import com.android.systemui.plugins.ActivityStarter;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-public class DreamAirQualityComplicationTest extends SysuiTestCase {
-    private static final String TRAMPOLINE_COMPONENT = "TestComponent";
-
-    @Mock
-    private DreamSmartspaceController mDreamSmartspaceController;
-
-    @Mock
-    private DreamOverlayStateController mDreamOverlayStateController;
-
-    @Mock
-    private DreamAirQualityComplication mComplication;
-
-    @Mock
-    private AirQualityColorPicker mColorPicker;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-    }
-
-    /**
-     * Ensures {@link DreamAirQualityComplication} is registered.
-     */
-    @Test
-    public void testComplicationRegistered() {
-        final DreamAirQualityComplication.Registrant registrant =
-                new DreamAirQualityComplication.Registrant(
-                        mContext,
-                        mDreamOverlayStateController,
-                        mComplication);
-        registrant.start();
-        verify(mDreamOverlayStateController).addComplication(eq(mComplication));
-    }
-
-    @Test
-    public void testGetUnfilteredTargets() {
-        final DreamAirQualityViewController controller =
-                new DreamAirQualityViewController(
-                        mock(TextView.class),
-                        mDreamSmartspaceController,
-                        TRAMPOLINE_COMPONENT,
-                        mock(ActivityStarter.class),
-                        mColorPicker);
-        controller.onViewAttached();
-        verify(mDreamSmartspaceController).addUnfilteredListener(any());
-        controller.onViewDetached();
-        verify(mDreamSmartspaceController).removeUnfilteredListener(any());
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java
deleted file mode 100644
index 883bec4..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.dreams.complication;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.testing.AndroidTestingRunner;
-import android.widget.TextView;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.dreams.DreamOverlayStateController;
-import com.android.systemui.dreams.smartspace.DreamSmartspaceController;
-import com.android.systemui.plugins.ActivityStarter;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-public class DreamWeatherComplicationTest extends SysuiTestCase {
-    private static final String TRAMPOLINE_COMPONENT = "TestComponent";
-
-    @SuppressWarnings("HidingField")
-    @Mock
-    private Context mContext;
-
-    @Mock
-    private DreamSmartspaceController mDreamSmartspaceController;
-
-    @Mock
-    private DreamOverlayStateController mDreamOverlayStateController;
-
-    @Mock
-    private DreamWeatherComplication mComplication;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-    }
-
-    /**
-     * Ensures {@link DreamWeatherComplication} is registered.
-     */
-    @Test
-    public void testComplicationRegistered() {
-        final DreamWeatherComplication.Registrant registrant =
-                new DreamWeatherComplication.Registrant(
-                        mContext,
-                        mDreamOverlayStateController,
-                        mComplication);
-        registrant.start();
-        verify(mDreamOverlayStateController).addComplication(eq(mComplication));
-    }
-
-    @Test
-    public void testGetUnfilteredTargets() {
-        final DreamWeatherComplication.DreamWeatherViewController controller =
-                new DreamWeatherComplication.DreamWeatherViewController(mock(
-                        TextView.class), TRAMPOLINE_COMPONENT, mock(ActivityStarter.class),
-                        mDreamSmartspaceController);
-        controller.onViewAttached();
-        verify(mDreamSmartspaceController).addUnfilteredListener(any());
-        controller.onViewDetached();
-        verify(mDreamSmartspaceController).removeUnfilteredListener(any());
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
index 51c2580..23516c9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
@@ -45,6 +45,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.SystemUIInitializerImpl;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.NotificationMediaManager;
@@ -100,7 +101,7 @@
         MockitoAnnotations.initMocks(this);
         mIsZenMode = false;
         mProvider = new TestableKeyguardSliceProvider();
-        mProvider.setContextAvailableCallback(context -> { });
+        mProvider.setContextAvailableCallback(context -> new SystemUIInitializerImpl(mContext));
         mProvider.attachInfo(getContext(), null);
         reset(mContentResolver);
         SliceProvider.setSpecs(new HashSet<>(Arrays.asList(SliceSpecs.LIST)));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index a80aed7..9b66555 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -203,6 +203,13 @@
                 mViewMediator.mViewMediatorCallback.getBouncerPromptReason());
     }
 
+    @Test
+    public void testHideSurfaceBehindKeyguardMarksKeyguardNotGoingAway() {
+        mViewMediator.hideSurfaceBehindKeyguard();
+
+        verify(mKeyguardStateController).notifyKeyguardGoingAway(false);
+    }
+
     private void createAndStartViewMediator() {
         mViewMediator = new KeyguardViewMediator(
                 mContext,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/lifecycle/WindowAddedViewLifecycleOwnerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/lifecycle/WindowAddedViewLifecycleOwnerTest.kt
new file mode 100644
index 0000000..4f5c570
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/lifecycle/WindowAddedViewLifecycleOwnerTest.kt
@@ -0,0 +1,150 @@
+package com.android.systemui.lifecycle
+
+import android.view.View
+import android.view.ViewTreeObserver
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleRegistry
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.capture
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(JUnit4::class)
+class WindowAddedViewLifecycleOwnerTest : SysuiTestCase() {
+
+    @Mock lateinit var view: View
+    @Mock lateinit var viewTreeObserver: ViewTreeObserver
+
+    private lateinit var underTest: WindowAddedViewLifecycleOwner
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        whenever(view.viewTreeObserver).thenReturn(viewTreeObserver)
+        whenever(view.isAttachedToWindow).thenReturn(false)
+        whenever(view.windowVisibility).thenReturn(View.INVISIBLE)
+        whenever(view.hasWindowFocus()).thenReturn(false)
+
+        underTest = WindowAddedViewLifecycleOwner(view) { LifecycleRegistry.createUnsafe(it) }
+    }
+
+    @Test
+    fun `detached - invisible - does not have focus -- INITIALIZED`() {
+        assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.INITIALIZED)
+    }
+
+    @Test
+    fun `detached - invisible - has focus -- INITIALIZED`() {
+        whenever(view.hasWindowFocus()).thenReturn(true)
+        val captor = argumentCaptor<ViewTreeObserver.OnWindowFocusChangeListener>()
+        verify(viewTreeObserver).addOnWindowFocusChangeListener(capture(captor))
+        captor.value.onWindowFocusChanged(true)
+
+        assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.INITIALIZED)
+    }
+
+    @Test
+    fun `detached - visible - does not have focus -- INITIALIZED`() {
+        whenever(view.windowVisibility).thenReturn(View.VISIBLE)
+        val captor = argumentCaptor<ViewTreeObserver.OnWindowVisibilityChangeListener>()
+        verify(viewTreeObserver).addOnWindowVisibilityChangeListener(capture(captor))
+        captor.value.onWindowVisibilityChanged(View.VISIBLE)
+
+        assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.INITIALIZED)
+    }
+
+    @Test
+    fun `detached - visible - has focus -- INITIALIZED`() {
+        whenever(view.hasWindowFocus()).thenReturn(true)
+        val focusCaptor = argumentCaptor<ViewTreeObserver.OnWindowFocusChangeListener>()
+        verify(viewTreeObserver).addOnWindowFocusChangeListener(capture(focusCaptor))
+        focusCaptor.value.onWindowFocusChanged(true)
+
+        whenever(view.windowVisibility).thenReturn(View.VISIBLE)
+        val visibilityCaptor = argumentCaptor<ViewTreeObserver.OnWindowVisibilityChangeListener>()
+        verify(viewTreeObserver).addOnWindowVisibilityChangeListener(capture(visibilityCaptor))
+        visibilityCaptor.value.onWindowVisibilityChanged(View.VISIBLE)
+
+        assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.INITIALIZED)
+    }
+
+    @Test
+    fun `attached - invisible - does not have focus -- CREATED`() {
+        whenever(view.isAttachedToWindow).thenReturn(true)
+        val captor = argumentCaptor<ViewTreeObserver.OnWindowAttachListener>()
+        verify(viewTreeObserver).addOnWindowAttachListener(capture(captor))
+        captor.value.onWindowAttached()
+
+        assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.CREATED)
+    }
+
+    @Test
+    fun `attached - invisible - has focus -- CREATED`() {
+        whenever(view.isAttachedToWindow).thenReturn(true)
+        val attachCaptor = argumentCaptor<ViewTreeObserver.OnWindowAttachListener>()
+        verify(viewTreeObserver).addOnWindowAttachListener(capture(attachCaptor))
+        attachCaptor.value.onWindowAttached()
+
+        whenever(view.hasWindowFocus()).thenReturn(true)
+        val focusCaptor = argumentCaptor<ViewTreeObserver.OnWindowFocusChangeListener>()
+        verify(viewTreeObserver).addOnWindowFocusChangeListener(capture(focusCaptor))
+        focusCaptor.value.onWindowFocusChanged(true)
+
+        assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.CREATED)
+    }
+
+    @Test
+    fun `attached - visible - does not have focus -- STARTED`() {
+        whenever(view.isAttachedToWindow).thenReturn(true)
+        val attachCaptor = argumentCaptor<ViewTreeObserver.OnWindowAttachListener>()
+        verify(viewTreeObserver).addOnWindowAttachListener(capture(attachCaptor))
+        attachCaptor.value.onWindowAttached()
+
+        whenever(view.windowVisibility).thenReturn(View.VISIBLE)
+        val visibilityCaptor = argumentCaptor<ViewTreeObserver.OnWindowVisibilityChangeListener>()
+        verify(viewTreeObserver).addOnWindowVisibilityChangeListener(capture(visibilityCaptor))
+        visibilityCaptor.value.onWindowVisibilityChanged(View.VISIBLE)
+
+        assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
+    }
+
+    @Test
+    fun `attached - visible - has focus -- RESUMED`() {
+        whenever(view.isAttachedToWindow).thenReturn(true)
+        val attachCaptor = argumentCaptor<ViewTreeObserver.OnWindowAttachListener>()
+        verify(viewTreeObserver).addOnWindowAttachListener(capture(attachCaptor))
+        attachCaptor.value.onWindowAttached()
+
+        whenever(view.hasWindowFocus()).thenReturn(true)
+        val focusCaptor = argumentCaptor<ViewTreeObserver.OnWindowFocusChangeListener>()
+        verify(viewTreeObserver).addOnWindowFocusChangeListener(capture(focusCaptor))
+        focusCaptor.value.onWindowFocusChanged(true)
+
+        whenever(view.windowVisibility).thenReturn(View.VISIBLE)
+        val visibilityCaptor = argumentCaptor<ViewTreeObserver.OnWindowVisibilityChangeListener>()
+        verify(viewTreeObserver).addOnWindowVisibilityChangeListener(capture(visibilityCaptor))
+        visibilityCaptor.value.onWindowVisibilityChanged(View.VISIBLE)
+
+        assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.RESUMED)
+    }
+
+    @Test
+    fun dispose() {
+        underTest.dispose()
+
+        verify(viewTreeObserver).removeOnWindowAttachListener(any())
+        verify(viewTreeObserver).removeOnWindowVisibilityChangeListener(any())
+        verify(viewTreeObserver).removeOnWindowFocusChangeListener(any())
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
index c13c30b..1785022 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
@@ -561,6 +561,19 @@
     }
 
     @Test
+    fun bindAlbumView_artUsesResource() {
+        val albumArt = Icon.createWithResource(context, R.drawable.ic_android)
+        val state = mediaData.copy(artwork = albumArt)
+
+        player.attachPlayer(viewHolder)
+        player.bindPlayer(state, PACKAGE)
+        bgExecutor.runAllReady()
+        mainExecutor.runAllReady()
+
+        verify(albumView).setImageDrawable(any(Drawable::class.java))
+    }
+
+    @Test
     fun bindAlbumView_setAfterExecutors() {
         val bmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
         val canvas = Canvas(bmp)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
index 59475cf..568e0cb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
@@ -71,14 +71,13 @@
 
     @Before
     public void setUp() {
-        mMediaOutputAdapter = new MediaOutputAdapter(mMediaOutputController, mMediaOutputDialog);
+        mMediaOutputAdapter = new MediaOutputAdapter(mMediaOutputController);
         mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
                 .onCreateViewHolder(new LinearLayout(mContext), 0);
         mSpyMediaOutputSeekbar = spy(mViewHolder.mSeekBar);
 
         when(mMediaOutputController.getMediaDevices()).thenReturn(mMediaDevices);
         when(mMediaOutputController.hasAdjustVolumeUserRestriction()).thenReturn(false);
-        when(mMediaOutputController.isZeroMode()).thenReturn(false);
         when(mMediaOutputController.isTransferring()).thenReturn(false);
         when(mMediaOutputController.getDeviceIconCompat(mMediaDevice1)).thenReturn(mIconCompat);
         when(mMediaOutputController.getDeviceIconCompat(mMediaDevice2)).thenReturn(mIconCompat);
@@ -98,28 +97,12 @@
     }
 
     @Test
-    public void getItemCount_nonZeroMode_isDeviceSize() {
-        assertThat(mMediaOutputAdapter.getItemCount()).isEqualTo(mMediaDevices.size());
-    }
-
-    @Test
-    public void getItemCount_zeroMode_containExtraOneForPairNew() {
-        when(mMediaOutputController.isZeroMode()).thenReturn(true);
-
+    public void getItemCount_containExtraOneForPairNew() {
         assertThat(mMediaOutputAdapter.getItemCount()).isEqualTo(mMediaDevices.size() + 1);
     }
 
     @Test
-    public void getItemCount_withDynamicGroup_containExtraOneForGroup() {
-        when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mMediaDevices);
-        when(mMediaOutputController.isZeroMode()).thenReturn(false);
-
-        assertThat(mMediaOutputAdapter.getItemCount()).isEqualTo(mMediaDevices.size());
-    }
-
-    @Test
-    public void onBindViewHolder_zeroMode_bindPairNew_verifyView() {
-        when(mMediaOutputController.isZeroMode()).thenReturn(true);
+    public void onBindViewHolder_bindPairNew_verifyView() {
         mMediaOutputAdapter.onBindViewHolder(mViewHolder, 2);
 
         assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE);
@@ -133,7 +116,6 @@
     @Test
     public void onBindViewHolder_bindGroup_withSessionName_verifyView() {
         when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mMediaDevices);
-        when(mMediaOutputController.isZeroMode()).thenReturn(false);
         when(mMediaOutputController.getSessionName()).thenReturn(TEST_SESSION_NAME);
         mMediaOutputAdapter.getItemCount();
         mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -148,7 +130,6 @@
     @Test
     public void onBindViewHolder_bindGroup_noSessionName_verifyView() {
         when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mMediaDevices);
-        when(mMediaOutputController.isZeroMode()).thenReturn(false);
         when(mMediaOutputController.getSessionName()).thenReturn(null);
         mMediaOutputAdapter.getItemCount();
         mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -257,7 +238,6 @@
 
     @Test
     public void onItemClick_clickPairNew_verifyLaunchBluetoothPairing() {
-        when(mMediaOutputController.isZeroMode()).thenReturn(true);
         mMediaOutputAdapter.onBindViewHolder(mViewHolder, 2);
         mViewHolder.mContainerLayout.performClick();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
index 9eaa20c..d414660 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
@@ -43,6 +43,8 @@
 import androidx.core.graphics.drawable.IconCompat;
 import androidx.test.filters.SmallTest;
 
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
@@ -98,10 +100,17 @@
     private CharSequence mHeaderSubtitle;
     private String mStopText;
     private boolean mIsBroadcasting;
+    private boolean mIsBroadcastIconVisibility;
+
 
     @Before
     public void setUp() {
         when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
+        final CachedBluetoothDeviceManager cachedBluetoothDeviceManager = mock(
+                CachedBluetoothDeviceManager.class);
+        when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(
+                cachedBluetoothDeviceManager);
+        when(cachedBluetoothDeviceManager.findDevice(any())).thenReturn(null);
         when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(null);
         when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
         when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_NONE);
@@ -153,6 +162,27 @@
     }
 
     @Test
+    public void refresh_broadcastIconVisibilityOff_broadcastIconLayoutNotVisible() {
+        mIsBroadcastIconVisibility = false;
+
+        mMediaOutputBaseDialogImpl.refresh();
+        final ImageView view = mMediaOutputBaseDialogImpl.mDialogView.requireViewById(
+                R.id.broadcast_icon);
+
+        assertThat(view.getVisibility()).isEqualTo(View.GONE);
+    }
+    @Test
+    public void refresh_broadcastIconVisibilityOn_broadcastIconLayoutVisible() {
+        mIsBroadcastIconVisibility = true;
+
+        mMediaOutputBaseDialogImpl.refresh();
+        final ImageView view = mMediaOutputBaseDialogImpl.mDialogView.requireViewById(
+                R.id.broadcast_icon);
+
+        assertThat(view.getVisibility()).isEqualTo(View.VISIBLE);
+    }
+
+    @Test
     public void refresh_checkTitle() {
         mHeaderTitle = "test_string";
 
@@ -308,5 +338,10 @@
         public CharSequence getStopButtonText() {
             return mStopText;
         }
+
+        @Override
+        public int getBroadcastIconVisibility() {
+            return mIsBroadcastIconVisibility ? View.VISIBLE : View.GONE;
+        }
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
index 2bf5f0f..751c895 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
@@ -383,62 +383,6 @@
     }
 
     @Test
-    public void isZeroMode_onlyFromPhoneOutput_returnTrue() {
-        // Multiple available devices
-        assertThat(mMediaOutputController.isZeroMode()).isFalse();
-        when(mMediaDevice1.getDeviceType()).thenReturn(
-                MediaDevice.MediaDeviceType.TYPE_PHONE_DEVICE);
-        mMediaDevices.clear();
-        mMediaDevices.add(mMediaDevice1);
-        mMediaOutputController.start(mCb);
-        mMediaOutputController.onDeviceListUpdate(mMediaDevices);
-
-        assertThat(mMediaOutputController.isZeroMode()).isTrue();
-
-        when(mMediaDevice1.getDeviceType()).thenReturn(
-                MediaDevice.MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE);
-
-        assertThat(mMediaOutputController.isZeroMode()).isTrue();
-
-        when(mMediaDevice1.getDeviceType()).thenReturn(
-                MediaDevice.MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE);
-
-        assertThat(mMediaOutputController.isZeroMode()).isTrue();
-    }
-
-    @Test
-    public void isZeroMode_notFromPhoneOutput_returnFalse() {
-        when(mMediaDevice1.getDeviceType()).thenReturn(
-                MediaDevice.MediaDeviceType.TYPE_UNKNOWN);
-        mMediaDevices.clear();
-        mMediaDevices.add(mMediaDevice1);
-        mMediaOutputController.start(mCb);
-        mMediaOutputController.onDeviceListUpdate(mMediaDevices);
-
-        assertThat(mMediaOutputController.isZeroMode()).isFalse();
-
-        when(mMediaDevice1.getDeviceType()).thenReturn(
-                MediaDevice.MediaDeviceType.TYPE_FAST_PAIR_BLUETOOTH_DEVICE);
-
-        assertThat(mMediaOutputController.isZeroMode()).isFalse();
-
-        when(mMediaDevice1.getDeviceType()).thenReturn(
-                MediaDevice.MediaDeviceType.TYPE_BLUETOOTH_DEVICE);
-
-        assertThat(mMediaOutputController.isZeroMode()).isFalse();
-
-        when(mMediaDevice1.getDeviceType()).thenReturn(
-                MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE);
-
-        assertThat(mMediaOutputController.isZeroMode()).isFalse();
-
-        when(mMediaDevice1.getDeviceType()).thenReturn(
-                MediaDevice.MediaDeviceType.TYPE_CAST_GROUP_DEVICE);
-
-        assertThat(mMediaOutputController.isZeroMode()).isFalse();
-    }
-
-    @Test
     public void getGroupMediaDevices_differentDeviceOrder_showingSameOrder() {
         final MediaDevice selectedMediaDevice1 = mock(MediaDevice.class);
         final MediaDevice selectedMediaDevice2 = mock(MediaDevice.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
index c45db05..6afed1a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
@@ -172,6 +172,39 @@
     }
 
     @Test
+    public void getBroadcastIconVisibility_isBroadcasting_returnVisible() {
+        when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
+                mLocalBluetoothLeBroadcast);
+        when(mLocalBluetoothLeBroadcast.isEnabled(any())).thenReturn(true);
+        when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PLAYING);
+        when(mMediaDevice.isBLEDevice()).thenReturn(true);
+
+        assertThat(mMediaOutputDialog.getBroadcastIconVisibility()).isEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void getBroadcastIconVisibility_noBroadcasting_returnGone() {
+        when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
+                mLocalBluetoothLeBroadcast);
+        when(mLocalBluetoothLeBroadcast.isEnabled(any())).thenReturn(false);
+        when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PLAYING);
+        when(mMediaDevice.isBLEDevice()).thenReturn(true);
+
+        assertThat(mMediaOutputDialog.getBroadcastIconVisibility()).isEqualTo(View.GONE);
+    }
+
+    @Test
+    public void getBroadcastIconVisibility_remoteNonLeDevice_returnGone() {
+        when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
+                mLocalBluetoothLeBroadcast);
+        when(mLocalBluetoothLeBroadcast.isEnabled(any())).thenReturn(false);
+        when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PLAYING);
+        when(mMediaDevice.isBLEDevice()).thenReturn(false);
+
+        assertThat(mMediaOutputDialog.getBroadcastIconVisibility()).isEqualTo(View.GONE);
+    }
+
+    @Test
     // Check the visibility metric logging by creating a new MediaOutput dialog,
     // and verify if the calling times increases.
     public void onCreate_ShouldLogVisibility() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupAdapterTest.java
deleted file mode 100644
index 9256cd3..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupAdapterTest.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.media.dialog;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.graphics.drawable.Icon;
-import android.testing.AndroidTestingRunner;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import androidx.core.graphics.drawable.IconCompat;
-import androidx.test.filters.SmallTest;
-
-import com.android.settingslib.media.MediaDevice;
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-public class MediaOutputGroupAdapterTest extends SysuiTestCase {
-
-    private static final String TEST_DEVICE_NAME_1 = "test_device_name_1";
-    private static final String TEST_DEVICE_NAME_2 = "test_device_name_2";
-    private static final String TEST_DEVICE_ID_1 = "test_device_id_1";
-    private static final String TEST_DEVICE_ID_2 = "test_device_id_2";
-    private static final int TEST_VOLUME = 10;
-    private static final int TEST_MAX_VOLUME = 50;
-
-    // Mock
-    private MediaOutputController mMediaOutputController = mock(MediaOutputController.class);
-    private MediaDevice mMediaDevice1 = mock(MediaDevice.class);
-    private MediaDevice mMediaDevice2 = mock(MediaDevice.class);
-    private Icon mIcon = mock(Icon.class);
-    private IconCompat mIconCompat = mock(IconCompat.class);
-
-    private MediaOutputGroupAdapter mGroupAdapter;
-    private MediaOutputGroupAdapter.GroupViewHolder mGroupViewHolder;
-    private List<MediaDevice> mGroupMediaDevices = new ArrayList<>();
-    private List<MediaDevice> mSelectableMediaDevices = new ArrayList<>();
-    private List<MediaDevice> mSelectedMediaDevices = new ArrayList<>();
-    private List<MediaDevice> mDeselectableMediaDevices = new ArrayList<>();
-
-    @Before
-    public void setUp() {
-        when(mMediaOutputController.getGroupMediaDevices()).thenReturn(mGroupMediaDevices);
-        when(mMediaOutputController.getDeviceIconCompat(mMediaDevice1)).thenReturn(mIconCompat);
-        when(mMediaOutputController.getDeviceIconCompat(mMediaDevice2)).thenReturn(mIconCompat);
-        when(mMediaOutputController.getSelectableMediaDevice()).thenReturn(mSelectableMediaDevices);
-        when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mSelectedMediaDevices);
-        when(mMediaOutputController.getDeselectableMediaDevice()).thenReturn(
-                mDeselectableMediaDevices);
-        when(mIconCompat.toIcon(mContext)).thenReturn(mIcon);
-        when(mMediaDevice1.getName()).thenReturn(TEST_DEVICE_NAME_1);
-        when(mMediaDevice1.getId()).thenReturn(TEST_DEVICE_ID_1);
-        when(mMediaDevice2.getName()).thenReturn(TEST_DEVICE_NAME_2);
-        when(mMediaDevice2.getId()).thenReturn(TEST_DEVICE_ID_2);
-        mGroupMediaDevices.add(mMediaDevice1);
-        mGroupMediaDevices.add(mMediaDevice2);
-        mSelectedMediaDevices.add(mMediaDevice1);
-        mSelectableMediaDevices.add(mMediaDevice2);
-        mDeselectableMediaDevices.add(mMediaDevice1);
-
-        mGroupAdapter = new MediaOutputGroupAdapter(mMediaOutputController);
-        mGroupViewHolder = (MediaOutputGroupAdapter.GroupViewHolder) mGroupAdapter
-                .onCreateViewHolder(new LinearLayout(mContext), 0);
-    }
-
-    @Test
-    public void onBindViewHolder_verifyGroupItem() {
-        mGroupAdapter.onBindViewHolder(mGroupViewHolder, 0);
-
-        assertThat(mGroupViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mGroupViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mGroupViewHolder.mSubTitleText.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mGroupViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mGroupViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mGroupViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mGroupViewHolder.mTwoLineTitleText.getText()).isEqualTo(mContext.getText(
-                R.string.media_output_dialog_group));
-    }
-
-    @Test
-    public void onBindViewHolder_singleSelectedDevice_verifyView() {
-        mGroupAdapter.onBindViewHolder(mGroupViewHolder, 1);
-
-        assertThat(mGroupViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mGroupViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mGroupViewHolder.mSubTitleText.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mGroupViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mGroupViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mGroupViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_1);
-        assertThat(mGroupViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mGroupViewHolder.mCheckBox.isChecked()).isTrue();
-        // Disabled checkBox
-        assertThat(mGroupViewHolder.mCheckBox.isEnabled()).isFalse();
-    }
-
-    @Test
-    public void onBindViewHolder_multipleSelectedDevice_verifyView() {
-        mSelectedMediaDevices.clear();
-        mSelectedMediaDevices.add(mMediaDevice1);
-        mSelectedMediaDevices.add(mMediaDevice2);
-        mDeselectableMediaDevices.clear();
-        mDeselectableMediaDevices.add(mMediaDevice1);
-        mDeselectableMediaDevices.add(mMediaDevice2);
-        mSelectableMediaDevices.clear();
-
-        mGroupAdapter.onBindViewHolder(mGroupViewHolder, 1);
-
-        assertThat(mGroupViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mGroupViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mGroupViewHolder.mSubTitleText.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mGroupViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mGroupViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mGroupViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_1);
-        assertThat(mGroupViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mGroupViewHolder.mCheckBox.isChecked()).isTrue();
-        // Enabled checkBox
-        assertThat(mGroupViewHolder.mCheckBox.isEnabled()).isTrue();
-    }
-
-    @Test
-    public void onBindViewHolder_notDeselectedDevice_verifyView() {
-        mSelectedMediaDevices.clear();
-        mSelectedMediaDevices.add(mMediaDevice1);
-        mSelectedMediaDevices.add(mMediaDevice2);
-        mDeselectableMediaDevices.clear();
-        mDeselectableMediaDevices.add(mMediaDevice1);
-        mSelectableMediaDevices.clear();
-
-        mGroupAdapter.onBindViewHolder(mGroupViewHolder, 2);
-
-        assertThat(mGroupViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mGroupViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mGroupViewHolder.mSubTitleText.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mGroupViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mGroupViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mGroupViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_2);
-        assertThat(mGroupViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mGroupViewHolder.mCheckBox.isChecked()).isTrue();
-        // Disabled checkBox
-        assertThat(mGroupViewHolder.mCheckBox.isEnabled()).isFalse();
-    }
-
-    @Test
-    public void onBindViewHolder_selectableDevice_verifyCheckBox() {
-        mGroupAdapter.onBindViewHolder(mGroupViewHolder, 2);
-
-        assertThat(mGroupViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mGroupViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mGroupViewHolder.mSubTitleText.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mGroupViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mGroupViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mGroupViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_2);
-        assertThat(mGroupViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mGroupViewHolder.mCheckBox.isChecked()).isFalse();
-        // Enabled checkBox
-        assertThat(mGroupViewHolder.mCheckBox.isEnabled()).isTrue();
-    }
-
-    @Test
-    public void onBindViewHolder_verifyDeviceVolume() {
-        when(mMediaDevice1.getCurrentVolume()).thenReturn(TEST_VOLUME);
-        when(mMediaDevice1.getMaxVolume()).thenReturn(TEST_MAX_VOLUME);
-        mGroupViewHolder.mSeekBar.setVisibility(View.VISIBLE);
-
-        mGroupAdapter.onBindViewHolder(mGroupViewHolder, 1);
-
-        assertThat(mGroupViewHolder.mSeekBar.getVolume()).isEqualTo(TEST_VOLUME);
-    }
-
-    @Test
-    public void clickSelectedDevice_verifyRemoveDeviceFromPlayMedia() {
-        mSelectedMediaDevices.clear();
-        mSelectedMediaDevices.add(mMediaDevice1);
-        mSelectedMediaDevices.add(mMediaDevice2);
-        mDeselectableMediaDevices.clear();
-        mDeselectableMediaDevices.add(mMediaDevice1);
-        mDeselectableMediaDevices.add(mMediaDevice2);
-        mSelectableMediaDevices.clear();
-
-        mGroupAdapter.onBindViewHolder(mGroupViewHolder, 1);
-        mGroupViewHolder.mCheckBox.performClick();
-
-        verify(mMediaOutputController).removeDeviceFromPlayMedia(mMediaDevice1);
-    }
-
-    @Test
-    public void clickSelectabelDevice_verifyAddDeviceToPlayMedia() {
-        mGroupAdapter.onBindViewHolder(mGroupViewHolder, 2);
-
-        mGroupViewHolder.mCheckBox.performClick();
-
-        verify(mMediaOutputController).addDeviceToPlayMedia(mMediaDevice2);
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupDialogTest.java
deleted file mode 100644
index 4534ae6..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupDialogTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.media.dialog;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.media.AudioManager;
-import android.media.session.MediaSessionManager;
-import android.os.PowerExemptionManager;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.view.View;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.settingslib.bluetooth.LocalBluetoothManager;
-import com.android.settingslib.media.LocalMediaManager;
-import com.android.settingslib.media.MediaDevice;
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.animation.DialogLaunchAnimator;
-import com.android.systemui.broadcast.BroadcastSender;
-import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
-import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class MediaOutputGroupDialogTest extends SysuiTestCase {
-
-    private static final String TEST_PACKAGE = "test_package";
-
-    // Mock
-    private MediaSessionManager mMediaSessionManager = mock(MediaSessionManager.class);
-    private LocalBluetoothManager mLocalBluetoothManager = mock(LocalBluetoothManager.class);
-    private ActivityStarter mStarter = mock(ActivityStarter.class);
-    private BroadcastSender mBroadcastSender = mock(BroadcastSender.class);
-    private LocalMediaManager mLocalMediaManager = mock(LocalMediaManager.class);
-    private MediaDevice mMediaDevice = mock(MediaDevice.class);
-    private MediaDevice mMediaDevice1 = mock(MediaDevice.class);
-    private NotificationEntryManager mNotificationEntryManager =
-            mock(NotificationEntryManager.class);
-    private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class);
-    private NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock(
-            NearbyMediaDevicesManager.class);
-    private final AudioManager mAudioManager = mock(AudioManager.class);
-    private PowerExemptionManager mPowerExemptionManager = mock(PowerExemptionManager.class);
-
-    private MediaOutputGroupDialog mMediaOutputGroupDialog;
-    private MediaOutputController mMediaOutputController;
-    private List<MediaDevice> mMediaDevices = new ArrayList<>();
-
-    @Before
-    public void setUp() {
-        mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE,
-                mMediaSessionManager, mLocalBluetoothManager, mStarter,
-                mNotificationEntryManager, mDialogLaunchAnimator,
-                Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager);
-        mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
-        mMediaOutputGroupDialog = new MediaOutputGroupDialog(mContext, false, mBroadcastSender,
-                mMediaOutputController);
-        mMediaOutputGroupDialog.show();
-        when(mLocalMediaManager.getSelectedMediaDevice()).thenReturn(mMediaDevices);
-    }
-
-    @After
-    public void tearDown() {
-        mMediaOutputGroupDialog.dismissDialog();
-    }
-
-    @Test
-    public void getStopButtonVisibility_returnVisible() {
-        assertThat(mMediaOutputGroupDialog.getStopButtonVisibility()).isEqualTo(View.VISIBLE);
-    }
-
-    @Test
-    public void getHeaderSubtitle_singleDevice_verifyTitle() {
-        mMediaDevices.add(mMediaDevice);
-
-        assertThat(mMediaOutputGroupDialog.getHeaderSubtitle()).isEqualTo(
-                mContext.getText(R.string.media_output_dialog_single_device));
-    }
-
-    @Test
-    public void getHeaderSubtitle_multipleDevices_verifyTitle() {
-        mMediaDevices.add(mMediaDevice);
-        mMediaDevices.add(mMediaDevice1);
-
-        assertThat(mMediaOutputGroupDialog.getHeaderSubtitle()).isEqualTo(mContext.getString(
-                R.string.media_output_dialog_multiple_devices, mMediaDevices.size()));
-    }
-
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
index 1cfa3b2..8fa5c93 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
@@ -89,6 +89,7 @@
 import com.android.systemui.recents.Recents;
 import com.android.systemui.settings.UserContextProvider;
 import com.android.systemui.settings.UserTracker;
+import com.android.systemui.shade.NotificationShadeWindowView;
 import com.android.systemui.shared.rotation.RotationButtonController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -97,7 +98,6 @@
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.phone.LightBarTransitionsController;
-import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/LaunchConversationActivityTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/LaunchConversationActivityTest.java
index 99f21ad..c8ebd12 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/LaunchConversationActivityTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/LaunchConversationActivityTest.java
@@ -48,6 +48,8 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
 import com.android.systemui.wmshell.BubblesManager;
 import com.android.wm.shell.bubbles.Bubble;
 
@@ -106,6 +108,9 @@
 
     private Intent mIntent;
 
+    private FakeSystemClock mFakeSystemClock = new FakeSystemClock();
+    private FakeExecutor mBgExecutor = new FakeExecutor(mFakeSystemClock);
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
@@ -114,7 +119,8 @@
                 mNotifCollection,
                 Optional.of(mBubblesManager),
                 mUserManager,
-                mCommandQueue
+                mCommandQueue,
+                mBgExecutor
         );
         verify(mCommandQueue, times(1)).addCallback(mCallbacksCaptor.capture());
 
@@ -193,6 +199,7 @@
         // Ensure callback removed
         verify(mCommandQueue).removeCallback(any());
         // Clear the notification for bubbles.
+        FakeExecutor.exhaustExecutors(mBgExecutor);
         verify(mIStatusBarService, times(1)).onNotificationClear(any(),
                 anyInt(), any(), anyInt(), anyInt(), mNotificationVisibilityCaptor.capture());
         // Do not select the bubble.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt
new file mode 100644
index 0000000..73a0cbc
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles
+
+import android.net.ConnectivityManager
+import android.os.Handler
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.MetricsLogger
+import com.android.internal.logging.UiEventLogger
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.classifier.FalsingManagerFake
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSHost
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.util.settings.GlobalSettings
+import com.google.common.truth.Truth.assertThat
+import dagger.Lazy
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class AirplaneModeTileTest : SysuiTestCase() {
+    @Mock
+    private lateinit var mHost: QSHost
+    @Mock
+    private lateinit var mMetricsLogger: MetricsLogger
+    @Mock
+    private lateinit var mStatusBarStateController: StatusBarStateController
+    @Mock
+    private lateinit var mActivityStarter: ActivityStarter
+    @Mock
+    private lateinit var mQsLogger: QSLogger
+    @Mock
+    private lateinit var mBroadcastDispatcher: BroadcastDispatcher
+    @Mock
+    private lateinit var mConnectivityManager: Lazy<ConnectivityManager>
+    @Mock
+    private lateinit var mGlobalSettings: GlobalSettings
+    private lateinit var mTestableLooper: TestableLooper
+    private lateinit var mTile: AirplaneModeTile
+
+    private val mUiEventLogger: UiEventLogger = UiEventLoggerFake()
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        mTestableLooper = TestableLooper.get(this)
+        Mockito.`when`(mHost.context).thenReturn(mContext)
+        Mockito.`when`(mHost.uiEventLogger).thenReturn(mUiEventLogger)
+        Mockito.`when`(mHost.userContext).thenReturn(mContext)
+
+        mTile = AirplaneModeTile(mHost,
+            mTestableLooper.looper,
+            Handler(mTestableLooper.looper),
+            FalsingManagerFake(),
+            mMetricsLogger,
+            mStatusBarStateController,
+            mActivityStarter,
+            mQsLogger,
+            mBroadcastDispatcher,
+            mConnectivityManager,
+            mGlobalSettings)
+    }
+
+    @Test
+    fun testIcon_whenDisabled_showsOffState() {
+        val state = QSTile.BooleanState()
+
+        mTile.handleUpdateState(state, 0)
+
+        assertThat(state.icon)
+            .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_airplane_icon_off))
+    }
+
+    @Test
+    fun testIcon_whenEnabled_showsOnState() {
+        val state = QSTile.BooleanState()
+
+        mTile.handleUpdateState(state, 1)
+
+        assertThat(state.icon)
+            .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_airplane_icon_on))
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
index 3d9205e..95e7ad9f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
@@ -24,15 +24,19 @@
 import android.view.View
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
+import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingManagerFake
 import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.qs.QSTile
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.statusbar.policy.BatteryController
 import com.android.systemui.util.settings.FakeSettings
 import com.android.systemui.util.settings.SecureSettings
+import com.google.common.truth.Truth.assertThat
 import org.junit.Assert.assertEquals
 import org.junit.Before
 import org.junit.Test
@@ -77,6 +81,7 @@
     fun setUp() {
         MockitoAnnotations.initMocks(this)
         testableLooper = TestableLooper.get(this)
+        `when`(qsHost.context).thenReturn(mContext)
         `when`(qsHost.userContext).thenReturn(userContext)
         `when`(userContext.userId).thenReturn(USER)
 
@@ -133,4 +138,26 @@
         tile.handleSetListening(false)
         verify(batteryController).clearLastPowerSaverStartView()
     }
+
+    @Test
+    fun testIcon_whenBatterySaverDisabled_isOffState() {
+        val state = QSTile.BooleanState()
+        tile.onPowerSaveChanged(false)
+
+        tile.handleUpdateState(state, /* arg= */ null)
+
+        assertThat(state.icon)
+                .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_battery_saver_icon_off))
+    }
+
+    @Test
+    fun testIcon_whenBatterySaverEnabled_isOnState() {
+        val state = QSTile.BooleanState()
+        tile.onPowerSaveChanged(true)
+
+        tile.handleUpdateState(state, /* arg= */ null)
+
+        assertThat(state.icon)
+                .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_battery_saver_icon_on))
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt
new file mode 100644
index 0000000..cfbb82f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles
+
+import android.os.Handler
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.MetricsLogger
+import com.android.internal.logging.UiEventLogger
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.FalsingManagerFake
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSHost
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.`when` as whenever
+
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class CameraToggleTileTest : SysuiTestCase() {
+    companion object {
+        /* isBlocked */
+        const val CAMERA_TOGGLE_ENABLED: Boolean = false
+        const val CAMERA_TOGGLE_DISABLED: Boolean = true
+    }
+
+    @Mock
+    private lateinit var host: QSHost
+    @Mock
+    private lateinit var metricsLogger: MetricsLogger
+    @Mock
+    private lateinit var statusBarStateController: StatusBarStateController
+    @Mock
+    private lateinit var activityStarter: ActivityStarter
+    @Mock
+    private lateinit var qsLogger: QSLogger
+    @Mock
+    private lateinit var privacyController: IndividualSensorPrivacyController
+    @Mock
+    private lateinit var keyguardStateController: KeyguardStateController
+
+    private lateinit var testableLooper: TestableLooper
+    private lateinit var tile: CameraToggleTile
+    private val uiEventLogger: UiEventLogger = UiEventLoggerFake()
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        testableLooper = TestableLooper.get(this)
+        whenever(host.context).thenReturn(mContext)
+        whenever(host.uiEventLogger).thenReturn(uiEventLogger)
+
+        tile = CameraToggleTile(host,
+                testableLooper.looper,
+                Handler(testableLooper.looper),
+                metricsLogger,
+                FalsingManagerFake(),
+                statusBarStateController,
+                activityStarter,
+                qsLogger,
+                privacyController,
+                keyguardStateController)
+    }
+
+    @Test
+    fun testIcon_whenCameraAccessEnabled_isOnState() {
+        val state = QSTile.BooleanState()
+
+        tile.handleUpdateState(state, CAMERA_TOGGLE_ENABLED)
+
+        assertThat(state.icon)
+                .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_camera_access_icon_on))
+    }
+
+    @Test
+    fun testIcon_whenCameraAccessDisabled_isOffState() {
+        val state = QSTile.BooleanState()
+
+        tile.handleUpdateState(state, CAMERA_TOGGLE_DISABLED)
+
+        assertThat(state.icon)
+                .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_camera_access_icon_off))
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
index ae70d32..ce5edb1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
@@ -21,6 +21,7 @@
 import android.content.SharedPreferences
 import android.os.Handler
 import android.provider.Settings
+import android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS
 import android.provider.Settings.Global.ZEN_MODE_OFF
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
@@ -28,13 +29,16 @@
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
 import com.android.internal.logging.UiEventLogger
+import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.classifier.FalsingManagerFake
 import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.qs.QSTile
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.statusbar.policy.ZenModeController
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
@@ -66,22 +70,31 @@
 
     @Mock
     private lateinit var qsHost: QSHost
+
     @Mock
     private lateinit var metricsLogger: MetricsLogger
+
     @Mock
     private lateinit var statusBarStateController: StatusBarStateController
+
     @Mock
     private lateinit var activityStarter: ActivityStarter
+
     @Mock
     private lateinit var qsLogger: QSLogger
+
     @Mock
     private lateinit var uiEventLogger: UiEventLogger
+
     @Mock
     private lateinit var zenModeController: ZenModeController
+
     @Mock
     private lateinit var sharedPreferences: SharedPreferences
+
     @Mock
     private lateinit var dialogLaunchAnimator: DialogLaunchAnimator
+
     @Mock
     private lateinit var hostDialog: Dialog
 
@@ -190,4 +203,24 @@
 
         verify(dialogLaunchAnimator, never()).showFromView(any(), any(), nullable(), anyBoolean())
     }
+
+    @Test
+    fun testIcon_whenDndModeOff_isOffState() {
+        whenever(zenModeController.zen).thenReturn(ZEN_MODE_OFF)
+        val state = QSTile.BooleanState()
+
+        tile.handleUpdateState(state, /* arg= */ null)
+
+        assertThat(state.icon).isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_dnd_icon_off))
+    }
+
+    @Test
+    fun testIcon_whenDndModeOn_isOnState() {
+        whenever(zenModeController.zen).thenReturn(ZEN_MODE_NO_INTERRUPTIONS)
+        val state = QSTile.BooleanState()
+
+        tile.handleUpdateState(state, /* arg= */ null)
+
+        assertThat(state.icon).isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_dnd_icon_on))
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
new file mode 100644
index 0000000..d2bbc8c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.qs.tiles
+
+import android.content.Context
+import android.os.Handler
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.MetricsLogger
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.FalsingManagerFake
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSTileHost
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.statusbar.policy.LocationController
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.`when`
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class LocationTileTest : SysuiTestCase() {
+
+    @Mock
+    private lateinit var mockContext: Context
+    @Mock
+    private lateinit var qsLogger: QSLogger
+    @Mock
+    private lateinit var qsHost: QSTileHost
+    @Mock
+    private lateinit var metricsLogger: MetricsLogger
+    private val falsingManager = FalsingManagerFake()
+    @Mock
+    private lateinit var statusBarStateController: StatusBarStateController
+    @Mock
+    private lateinit var activityStarter: ActivityStarter
+    @Mock
+    private lateinit var locationController: LocationController
+    @Mock
+    private lateinit var keyguardStateController: KeyguardStateController
+
+    private val uiEventLogger = UiEventLoggerFake()
+    private lateinit var testableLooper: TestableLooper
+    private lateinit var tile: LocationTile
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        testableLooper = TestableLooper.get(this)
+        `when`(qsHost.uiEventLogger).thenReturn(uiEventLogger)
+        `when`(qsHost.context).thenReturn(mockContext)
+
+        tile = LocationTile(qsHost,
+            testableLooper.looper,
+            Handler(testableLooper.looper),
+            falsingManager,
+            metricsLogger,
+            statusBarStateController,
+            activityStarter,
+            qsLogger,
+            locationController,
+            keyguardStateController)
+    }
+
+    @Test
+    fun testIcon_whenDisabled_isOffState() {
+        val state = QSTile.BooleanState()
+        `when`(locationController.isLocationEnabled).thenReturn(false)
+
+        tile.handleUpdateState(state, /* arg= */ null)
+
+        assertThat(state.icon)
+            .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_location_icon_off))
+    }
+
+    @Test
+    fun testIcon_whenEnabled_isOnState() {
+        val state = QSTile.BooleanState()
+        `when`(locationController.isLocationEnabled).thenReturn(true)
+
+        tile.handleUpdateState(state, /* arg= */ null)
+
+        assertThat(state.icon)
+            .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_location_icon_on))
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt
new file mode 100644
index 0000000..1ab601c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles
+
+import android.os.Handler
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.MetricsLogger
+import com.android.internal.logging.UiEventLogger
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.FalsingManagerFake
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSHost
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.`when` as whenever
+
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class MicrophoneToggleTileTest : SysuiTestCase() {
+    companion object {
+        /* isBlocked */
+        const val MICROPHONE_TOGGLE_ENABLED: Boolean = false
+        const val MICROPHONE_TOGGLE_DISABLED: Boolean = true
+    }
+
+    @Mock
+    private lateinit var host: QSHost
+    @Mock
+    private lateinit var metricsLogger: MetricsLogger
+    @Mock
+    private lateinit var statusBarStateController: StatusBarStateController
+    @Mock
+    private lateinit var activityStarter: ActivityStarter
+    @Mock
+    private lateinit var qsLogger: QSLogger
+    @Mock
+    private lateinit var privacyController: IndividualSensorPrivacyController
+    @Mock
+    private lateinit var keyguardStateController: KeyguardStateController
+
+    private lateinit var testableLooper: TestableLooper
+    private lateinit var tile: MicrophoneToggleTile
+    private val uiEventLogger: UiEventLogger = UiEventLoggerFake()
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        testableLooper = TestableLooper.get(this)
+        whenever(host.context).thenReturn(mContext)
+        whenever(host.uiEventLogger).thenReturn(uiEventLogger)
+
+        tile = MicrophoneToggleTile(host,
+                testableLooper.looper,
+                Handler(testableLooper.looper),
+                metricsLogger,
+                FalsingManagerFake(),
+                statusBarStateController,
+                activityStarter,
+                qsLogger,
+                privacyController,
+                keyguardStateController)
+    }
+
+    @Test
+    fun testIcon_whenMicrophoneAccessEnabled_isOnState() {
+        val state = QSTile.BooleanState()
+
+        tile.handleUpdateState(state, MICROPHONE_TOGGLE_ENABLED)
+
+        assertThat(state.icon).isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_mic_access_on))
+    }
+
+    @Test
+    fun testIcon_whenMicrophoneAccessDisabled_isOffState() {
+        val state = QSTile.BooleanState()
+
+        tile.handleUpdateState(state, MICROPHONE_TOGGLE_DISABLED)
+
+        assertThat(state.icon).isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_mic_access_off))
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
index 91cafea..b05d9a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
@@ -16,18 +16,21 @@
 
 package com.android.systemui.screenrecord;
 
+import static org.junit.Assert.assertThrows;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.content.Intent;
+import android.os.Handler;
 import android.os.RemoteException;
 import android.testing.AndroidTestingRunner;
 
@@ -66,6 +69,8 @@
     @Mock
     private Executor mExecutor;
     @Mock
+    private Handler mHandler;
+    @Mock
     private UserContextProvider mUserContextTracker;
     private KeyguardDismissUtil mKeyguardDismissUtil = new KeyguardDismissUtil() {
         public void executeWhenUnlocked(ActivityStarter.OnDismissAction action,
@@ -79,8 +84,8 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mRecordingService = Mockito.spy(new RecordingService(mController, mExecutor, mUiEventLogger,
-                mNotificationManager, mUserContextTracker, mKeyguardDismissUtil));
+        mRecordingService = Mockito.spy(new RecordingService(mController, mExecutor, mHandler,
+                mUiEventLogger, mNotificationManager, mUserContextTracker, mKeyguardDismissUtil));
 
         // Return actual context info
         doReturn(mContext).when(mRecordingService).getApplicationContext();
@@ -143,4 +148,54 @@
         // Then the state is set to not recording
         verify(mController).updateState(false);
     }
+
+    @Test
+    public void testOnSystemRequestedStop_recordingInProgress_endsRecording() throws IOException {
+        doReturn(true).when(mController).isRecording();
+
+        mRecordingService.onStopped();
+
+        verify(mScreenMediaRecorder).end();
+    }
+
+    @Test
+    public void testOnSystemRequestedStop_recordingInProgress_updatesState() {
+        doReturn(true).when(mController).isRecording();
+
+        mRecordingService.onStopped();
+
+        verify(mController).updateState(false);
+    }
+
+    @Test
+    public void testOnSystemRequestedStop_recordingIsNotInProgress_doesNotEndRecording()
+            throws IOException {
+        doReturn(false).when(mController).isRecording();
+
+        mRecordingService.onStopped();
+
+        verify(mScreenMediaRecorder, never()).end();
+    }
+
+    @Test
+    public void testOnSystemRequestedStop_recorderEndThrowsRuntimeException_releasesRecording()
+            throws IOException {
+        doReturn(true).when(mController).isRecording();
+        doThrow(new RuntimeException()).when(mScreenMediaRecorder).end();
+
+        mRecordingService.onStopped();
+
+        verify(mScreenMediaRecorder).release();
+    }
+
+    @Test
+    public void testOnSystemRequestedStop_recorderEndThrowsOOMError_releasesRecording()
+            throws IOException {
+        doReturn(true).when(mController).isRecording();
+        doThrow(new OutOfMemoryError()).when(mScreenMediaRecorder).end();
+
+        assertThrows(Throwable.class, () -> mRecordingService.onStopped());
+
+        verify(mScreenMediaRecorder).release();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt
new file mode 100644
index 0000000..73226fa
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.settings
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.IntentFilter
+import android.os.Environment
+import android.os.UserManager
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.Executor
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.isNull
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class UserFileManagerImplTest : SysuiTestCase() {
+    companion object {
+        const val TEST_FILE_NAME = "abc.txt"
+    }
+
+    lateinit var userFileManager: UserFileManagerImpl
+    lateinit var backgroundExecutor: FakeExecutor
+    @Mock
+    lateinit var userManager: UserManager
+    @Mock
+    lateinit var broadcastDispatcher: BroadcastDispatcher
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        backgroundExecutor = FakeExecutor(FakeSystemClock())
+        userFileManager = UserFileManagerImpl(context, userManager,
+            broadcastDispatcher, backgroundExecutor)
+    }
+
+    @Test
+    fun testGetFile() {
+        assertThat(userFileManager.getFile(TEST_FILE_NAME, 0).path)
+            .isEqualTo("${context.filesDir}/$TEST_FILE_NAME")
+        assertThat(userFileManager.getFile(TEST_FILE_NAME, 11).path)
+            .isEqualTo("${context.filesDir}/${UserFileManagerImpl.ID}/11/files/$TEST_FILE_NAME")
+    }
+
+    @Test
+    fun testGetSharedPreferences() {
+        assertThat(userFileManager.getSharedPreferences(TEST_FILE_NAME, 0, 0))
+            .isNotEqualTo(userFileManager.getSharedPreferences(TEST_FILE_NAME, 0, 11))
+    }
+
+    @Test
+    fun testUserFileManagerStart() {
+        val userFileManager = spy(userFileManager)
+        userFileManager.start()
+        verify(userFileManager).clearDeletedUserData()
+        verify(broadcastDispatcher).registerReceiver(any(BroadcastReceiver::class.java),
+            any(IntentFilter::class.java),
+            any(Executor::class.java), isNull(), eq(Context.RECEIVER_EXPORTED), isNull())
+    }
+
+    @Test
+    fun testClearDeletedUserData() {
+        val dir = Environment.buildPath(
+            context.filesDir,
+            UserFileManagerImpl.ID,
+            "11",
+            "files"
+        )
+        dir.mkdirs()
+        val file = Environment.buildPath(
+            context.filesDir,
+            UserFileManagerImpl.ID,
+            "11",
+            "files",
+            TEST_FILE_NAME
+        )
+        val secondaryUserDir = Environment.buildPath(
+            context.filesDir,
+            UserFileManagerImpl.ID,
+            "11",
+        )
+        file.createNewFile()
+        assertThat(secondaryUserDir.exists()).isTrue()
+        assertThat(file.exists()).isTrue()
+        userFileManager.clearDeletedUserData()
+        assertThat(backgroundExecutor.runAllReady()).isGreaterThan(0)
+        verify(userManager).aliveUsers
+        assertThat(secondaryUserDir.exists()).isFalse()
+        assertThat(file.exists()).isFalse()
+        dir.deleteRecursively()
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
similarity index 95%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index 7fd61cf..5abcff3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.shade;
 
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 
@@ -106,6 +106,7 @@
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.qrcodescanner.controller.QRCodeScannerController;
 import com.android.systemui.screenrecord.RecordingController;
+import com.android.systemui.shade.transition.ShadeTransitionController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
@@ -131,8 +132,28 @@
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
 import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.phone.ConfigurationControllerImpl;
+import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
+import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
+import com.android.systemui.statusbar.phone.KeyguardBottomAreaViewController;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
+import com.android.systemui.statusbar.phone.KeyguardStatusBarViewController;
+import com.android.systemui.statusbar.phone.LargeScreenShadeHeaderController;
+import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
+import com.android.systemui.statusbar.phone.NotificationIconAreaController;
+import com.android.systemui.statusbar.phone.PanelViewController;
+import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
+import com.android.systemui.statusbar.phone.ScrimController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
+import com.android.systemui.statusbar.phone.TapAgainViewController;
+import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
-import com.android.systemui.statusbar.phone.shade.transition.ShadeTransitionController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardQsUserSwitchController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -487,7 +508,6 @@
 
         mNotificationPanelViewController = new NotificationPanelViewController(
                 mView,
-                mResources,
                 mMainHandler,
                 mLayoutInflater,
                 mFeatureFlags,
@@ -528,8 +548,6 @@
                 mQuickAccessWalletController,
                 mQrCodeScannerController,
                 mRecordingController,
-                mExecutor,
-                mSecureSettings,
                 mLargeScreenShadeHeaderController,
                 mScreenOffAnimationController,
                 mLockscreenGestureLogger,
@@ -566,7 +584,7 @@
                 ArgumentCaptor.forClass(View.AccessibilityDelegate.class);
         verify(mView).setAccessibilityDelegate(accessibilityDelegateArgumentCaptor.capture());
         mAccessibiltyDelegate = accessibilityDelegateArgumentCaptor.getValue();
-        mNotificationPanelViewController.mStatusBarStateController
+        mNotificationPanelViewController.getStatusBarStateController()
                 .addCallback(mNotificationPanelViewController.mStatusBarStateListener);
         mNotificationPanelViewController
                 .setHeadsUpAppearanceController(mock(HeadsUpAppearanceController.class));
@@ -994,6 +1012,21 @@
     }
 
     @Test
+    public void testSwipe_exactlyToTarget_notifiesNssl() {
+        // No over-expansion
+        mNotificationPanelViewController.setOverExpansion(0f);
+        // Fling to a target that is equal to the current position (i.e. a no-op fling).
+        mNotificationPanelViewController.flingToHeight(
+                0f,
+                true,
+                mNotificationPanelViewController.getExpandedHeight(),
+                1f,
+                false);
+        // Verify that the NSSL is notified that the panel is *not* flinging.
+        verify(mNotificationStackScrollLayoutController).setPanelFlinging(false);
+    }
+
+    @Test
     public void testDoubleTapRequired_Keyguard() {
         FalsingManager.FalsingTapListener listener = getFalsingTapListener();
         mStatusBarStateController.setState(KEYGUARD);
@@ -1180,14 +1213,14 @@
         when(mPowerManager.isPowerSaveMode()).thenReturn(false);
         when(mAmbientState.getDozeAmount()).thenReturn(0f);
         mNotificationPanelViewController.startUnlockHintAnimation();
-        assertThat(mNotificationPanelViewController.mHintAnimationRunning).isTrue();
+        assertThat(mNotificationPanelViewController.isHintAnimationRunning()).isTrue();
     }
 
     @Test
     public void testUnlockHintAnimation_doesNotRun_inPowerSaveMode() {
         when(mPowerManager.isPowerSaveMode()).thenReturn(true);
         mNotificationPanelViewController.startUnlockHintAnimation();
-        assertThat(mNotificationPanelViewController.mHintAnimationRunning).isFalse();
+        assertThat(mNotificationPanelViewController.isHintAnimationRunning()).isFalse();
     }
 
     @Test
@@ -1195,7 +1228,7 @@
         when(mPowerManager.isPowerSaveMode()).thenReturn(false);
         when(mAmbientState.getDozeAmount()).thenReturn(0.5f);
         mNotificationPanelViewController.startUnlockHintAnimation();
-        assertThat(mNotificationPanelViewController.mHintAnimationRunning).isFalse();
+        assertThat(mNotificationPanelViewController.isHintAnimationRunning()).isFalse();
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt
similarity index 99%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt
index de40b7f..0c6a6a9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt
@@ -1,4 +1,4 @@
-package com.android.systemui.statusbar.phone
+package com.android.systemui.shade
 
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
similarity index 91%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
index c402d2e..1dfd7c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.shade;
 
 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
@@ -28,8 +28,10 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
@@ -42,6 +44,8 @@
 import android.view.View;
 import android.view.WindowManager;
 
+import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.ViewTreeLifecycleOwner;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.colorextraction.ColorExtractor;
@@ -51,6 +55,11 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowControllerImpl;
+import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
+import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
@@ -61,6 +70,7 @@
 import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
 
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
@@ -69,7 +79,8 @@
 
     @Mock private WindowManager mWindowManager;
     @Mock private DozeParameters mDozeParameters;
-    @Mock private NotificationShadeWindowView mNotificationShadeWindowView;
+    @Spy private final NotificationShadeWindowView mNotificationShadeWindowView = spy(
+            new NotificationShadeWindowView(mContext, null));
     @Mock private IActivityManager mActivityManager;
     @Mock private SysuiStatusBarStateController mStatusBarStateController;
     @Mock private ConfigurationController mConfigurationController;
@@ -85,6 +96,7 @@
 
     private NotificationShadeWindowControllerImpl mNotificationShadeWindowController;
 
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -177,6 +189,24 @@
     }
 
     @Test
+    public void attach_setsUpLifecycleOwner() {
+        mNotificationShadeWindowController.attach();
+
+        assertThat(ViewTreeLifecycleOwner.get(mNotificationShadeWindowView)).isNotNull();
+    }
+
+    @Test
+    public void attach_doesNotSetUpLifecycleOwnerIfAlreadySet() {
+        final LifecycleOwner previouslySet = mock(LifecycleOwner.class);
+        ViewTreeLifecycleOwner.set(mNotificationShadeWindowView, previouslySet);
+
+        mNotificationShadeWindowController.attach();
+
+        assertThat(ViewTreeLifecycleOwner.get(mNotificationShadeWindowView))
+                .isEqualTo(previouslySet);
+    }
+
+    @Test
     public void setScrimsVisibility_earlyReturn() {
         clearInvocations(mWindowManager);
         mNotificationShadeWindowController.setScrimsVisibility(ScrimController.TRANSPARENT);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
new file mode 100644
index 0000000..471918c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
@@ -0,0 +1,284 @@
+/*
+ * 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 com.android.systemui.shade
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import android.view.MotionEvent
+import androidx.test.filters.SmallTest
+import com.android.keyguard.LockIconViewController
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.FalsingCollectorFake
+import com.android.systemui.dock.DockManager
+import com.android.systemui.keyguard.KeyguardUnlockAnimationController
+import com.android.systemui.lowlightclock.LowLightClockController
+import com.android.systemui.statusbar.LockscreenShadeTransitionController
+import com.android.systemui.statusbar.NotificationShadeDepthController
+import com.android.systemui.statusbar.NotificationShadeWindowController
+import com.android.systemui.statusbar.SysuiStatusBarStateController
+import com.android.systemui.statusbar.notification.stack.AmbientState
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
+import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler
+import com.android.systemui.statusbar.phone.CentralSurfaces
+import com.android.systemui.statusbar.phone.PhoneStatusBarViewController
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
+import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager
+import com.android.systemui.statusbar.window.StatusBarWindowStateController
+import com.android.systemui.tuner.TunerService
+import com.google.common.truth.Truth.assertThat
+import java.util.Optional
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers
+import org.mockito.Mock
+import org.mockito.Mockito.anyFloat
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
+    @Mock
+    private lateinit var view: NotificationShadeWindowView
+    @Mock
+    private lateinit var tunserService: TunerService
+    @Mock
+    private lateinit var sysuiStatusBarStateController: SysuiStatusBarStateController
+    @Mock
+    private lateinit var centralSurfaces: CentralSurfaces
+    @Mock
+    private lateinit var dockManager: DockManager
+    @Mock
+    private lateinit var notificationPanelViewController: NotificationPanelViewController
+    @Mock
+    private lateinit var notificationShadeDepthController: NotificationShadeDepthController
+    @Mock
+    private lateinit var notificationShadeWindowController: NotificationShadeWindowController
+    @Mock
+    private lateinit var keyguardUnlockAnimationController: KeyguardUnlockAnimationController
+    @Mock
+    private lateinit var ambientState: AmbientState
+    @Mock
+    private lateinit var stackScrollLayoutController: NotificationStackScrollLayoutController
+    @Mock
+    private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager
+    @Mock
+    private lateinit var statusBarWindowStateController: StatusBarWindowStateController
+    @Mock
+    private lateinit var lockscreenShadeTransitionController: LockscreenShadeTransitionController
+    @Mock
+    private lateinit var lockIconViewController: LockIconViewController
+    @Mock
+    private lateinit var phoneStatusBarViewController: PhoneStatusBarViewController
+    @Mock
+    private lateinit var lowLightClockController: LowLightClockController
+
+    private lateinit var interactionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
+    private lateinit var interactionEventHandler: InteractionEventHandler
+
+    private lateinit var underTest: NotificationShadeWindowViewController
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        whenever(view.bottom).thenReturn(VIEW_BOTTOM)
+
+        underTest = NotificationShadeWindowViewController(
+            lockscreenShadeTransitionController,
+            FalsingCollectorFake(),
+            tunserService,
+            sysuiStatusBarStateController,
+            dockManager,
+            notificationShadeDepthController,
+            view,
+            notificationPanelViewController,
+            PanelExpansionStateManager(),
+            stackScrollLayoutController,
+            statusBarKeyguardViewManager,
+            statusBarWindowStateController,
+            lockIconViewController,
+            Optional.of(lowLightClockController),
+            centralSurfaces,
+            notificationShadeWindowController,
+            keyguardUnlockAnimationController,
+            ambientState
+        )
+        underTest.setupExpandedStatusBar()
+
+        interactionEventHandlerCaptor =
+            ArgumentCaptor.forClass(InteractionEventHandler::class.java)
+        verify(view).setInteractionEventHandler(interactionEventHandlerCaptor.capture())
+            interactionEventHandler = interactionEventHandlerCaptor.value
+    }
+
+    // Note: So far, these tests only cover interactions with the status bar view controller. More
+    // tests need to be added to test the rest of handleDispatchTouchEvent.
+
+    @Test
+    fun handleDispatchTouchEvent_nullStatusBarViewController_returnsFalse() {
+        underTest.setStatusBarViewController(null)
+
+        val returnVal = interactionEventHandler.handleDispatchTouchEvent(downEv)
+
+        assertThat(returnVal).isFalse()
+    }
+
+    @Test
+    fun handleDispatchTouchEvent_downTouchBelowView_sendsTouchToSb() {
+        underTest.setStatusBarViewController(phoneStatusBarViewController)
+        val ev = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, VIEW_BOTTOM + 4f, 0)
+        whenever(phoneStatusBarViewController.sendTouchToView(ev)).thenReturn(true)
+
+        val returnVal = interactionEventHandler.handleDispatchTouchEvent(ev)
+
+        verify(phoneStatusBarViewController).sendTouchToView(ev)
+        assertThat(returnVal).isTrue()
+    }
+
+    @Test
+    fun handleDispatchTouchEvent_downTouchBelowViewThenAnotherTouch_sendsTouchToSb() {
+        underTest.setStatusBarViewController(phoneStatusBarViewController)
+        val downEvBelow = MotionEvent.obtain(
+            0L, 0L, MotionEvent.ACTION_DOWN, 0f, VIEW_BOTTOM + 4f, 0
+        )
+        interactionEventHandler.handleDispatchTouchEvent(downEvBelow)
+
+        val nextEvent = MotionEvent.obtain(
+            0L, 0L, MotionEvent.ACTION_MOVE, 0f, VIEW_BOTTOM + 5f, 0
+        )
+        whenever(phoneStatusBarViewController.sendTouchToView(nextEvent)).thenReturn(true)
+
+        val returnVal = interactionEventHandler.handleDispatchTouchEvent(nextEvent)
+
+        verify(phoneStatusBarViewController).sendTouchToView(nextEvent)
+        assertThat(returnVal).isTrue()
+    }
+
+    @Test
+    fun handleDispatchTouchEvent_downAndPanelCollapsedAndInSbBoundAndSbWindowShow_sendsTouchToSb() {
+        underTest.setStatusBarViewController(phoneStatusBarViewController)
+        whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
+        whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
+        whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+            .thenReturn(true)
+        whenever(phoneStatusBarViewController.sendTouchToView(downEv)).thenReturn(true)
+
+        val returnVal = interactionEventHandler.handleDispatchTouchEvent(downEv)
+
+        verify(phoneStatusBarViewController).sendTouchToView(downEv)
+        assertThat(returnVal).isTrue()
+    }
+
+    @Test
+    fun handleDispatchTouchEvent_panelNotCollapsed_returnsNull() {
+        underTest.setStatusBarViewController(phoneStatusBarViewController)
+        whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
+        whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+            .thenReturn(true)
+        // Item we're testing
+        whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(false)
+
+        val returnVal = interactionEventHandler.handleDispatchTouchEvent(downEv)
+
+        verify(phoneStatusBarViewController, never()).sendTouchToView(downEv)
+        assertThat(returnVal).isNull()
+    }
+
+    @Test
+    fun handleDispatchTouchEvent_touchNotInSbBounds_returnsNull() {
+        underTest.setStatusBarViewController(phoneStatusBarViewController)
+        whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
+        whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
+        // Item we're testing
+        whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+            .thenReturn(false)
+
+        val returnVal = interactionEventHandler.handleDispatchTouchEvent(downEv)
+
+        verify(phoneStatusBarViewController, never()).sendTouchToView(downEv)
+        assertThat(returnVal).isNull()
+    }
+
+    @Test
+    fun handleDispatchTouchEvent_sbWindowNotShowing_noSendTouchToSbAndReturnsTrue() {
+        underTest.setStatusBarViewController(phoneStatusBarViewController)
+        whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
+        whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+            .thenReturn(true)
+        // Item we're testing
+        whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(false)
+
+        val returnVal = interactionEventHandler.handleDispatchTouchEvent(downEv)
+
+        verify(phoneStatusBarViewController, never()).sendTouchToView(downEv)
+        assertThat(returnVal).isTrue()
+    }
+
+    @Test
+    fun handleDispatchTouchEvent_downEventSentToSbThenAnotherEvent_sendsTouchToSb() {
+        underTest.setStatusBarViewController(phoneStatusBarViewController)
+        whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
+        whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
+        whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+            .thenReturn(true)
+
+        // Down event first
+        interactionEventHandler.handleDispatchTouchEvent(downEv)
+
+        // Then another event
+        val nextEvent = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0)
+        whenever(phoneStatusBarViewController.sendTouchToView(nextEvent)).thenReturn(true)
+
+        val returnVal = interactionEventHandler.handleDispatchTouchEvent(nextEvent)
+
+        verify(phoneStatusBarViewController).sendTouchToView(nextEvent)
+        assertThat(returnVal).isTrue()
+    }
+
+    @Test
+    fun testLowLightClockAttachedWhenExpandedStatusBarSetup() {
+        verify(lowLightClockController).attachLowLightClockView(ArgumentMatchers.any())
+    }
+
+    @Test
+    fun testLowLightClockShownWhenDozing() {
+        underTest.setDozing(true)
+        verify(lowLightClockController).showLowLightClock(true)
+    }
+
+    @Test
+    fun testLowLightClockDozeTimeTickCalled() {
+        underTest.dozeTimeTick()
+        verify(lowLightClockController).dozeTimeTick()
+    }
+
+    @Test
+    fun testLowLightClockHiddenWhenNotDozing() {
+        underTest.setDozing(true)
+        verify(lowLightClockController).showLowLightClock(true)
+        underTest.setDozing(false)
+        verify(lowLightClockController).showLowLightClock(false)
+    }
+}
+
+private val downEv = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
+private const val VIEW_BOTTOM = 100
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java
similarity index 96%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java
index 1d86fb1..665d849 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.shade;
 
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
@@ -47,6 +47,9 @@
 import com.android.systemui.statusbar.notification.stack.AmbientState;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
 import com.android.systemui.statusbar.window.StatusBarWindowStateController;
 import com.android.systemui.tuner.TunerService;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt
similarity index 98%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionControllerTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt
index 304a274..baaa447 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt
@@ -1,4 +1,4 @@
-package com.android.systemui.statusbar.phone.shade.transition
+package com.android.systemui.shade.transition
 
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt
similarity index 68%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionControllerTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt
index 8b7e04b..b6f8326 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt
@@ -1,4 +1,4 @@
-package com.android.systemui.statusbar.phone.shade.transition
+package com.android.systemui.shade.transition
 
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
@@ -6,8 +6,10 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.qs.QS
+import com.android.systemui.shade.NotificationPanelViewController
+import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.SysuiStatusBarStateController
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
-import com.android.systemui.statusbar.phone.NotificationPanelViewController
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager
 import com.android.systemui.statusbar.phone.panelstate.STATE_OPENING
@@ -19,6 +21,7 @@
 import org.mockito.Mockito.reset
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyZeroInteractions
+import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
 
 @RunWith(AndroidTestingRunner::class)
@@ -32,6 +35,7 @@
     @Mock private lateinit var splitShadeOverScroller: SplitShadeOverScroller
     @Mock private lateinit var scrimShadeTransitionController: ScrimShadeTransitionController
     @Mock private lateinit var dumpManager: DumpManager
+    @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
 
     private lateinit var controller: ShadeTransitionController
 
@@ -50,7 +54,9 @@
                 context,
                 splitShadeOverScrollerFactory = { _, _ -> splitShadeOverScroller },
                 noOpOverScroller,
-                scrimShadeTransitionController)
+                scrimShadeTransitionController,
+                statusBarStateController,
+            )
 
         // Resetting as they are notified upon initialization.
         reset(noOpOverScroller, splitShadeOverScroller)
@@ -80,6 +86,45 @@
     }
 
     @Test
+    fun onPanelStateChanged_inSplitShade_onKeyguard_forwardsToNoOpOverScroller() {
+        initLateProperties()
+        enableSplitShade()
+        setOnKeyguard()
+
+        startPanelExpansion()
+
+        verify(noOpOverScroller).onPanelStateChanged(STATE_OPENING)
+        verify(noOpOverScroller).onDragDownAmountChanged(DEFAULT_DRAG_DOWN_AMOUNT)
+        verifyZeroInteractions(splitShadeOverScroller)
+    }
+
+    @Test
+    fun onPanelStateChanged_inSplitShade_onLockedShade_forwardsToNoOpOverScroller() {
+        initLateProperties()
+        enableSplitShade()
+        setOnLockedShade()
+
+        startPanelExpansion()
+
+        verify(noOpOverScroller).onPanelStateChanged(STATE_OPENING)
+        verify(noOpOverScroller).onDragDownAmountChanged(DEFAULT_DRAG_DOWN_AMOUNT)
+        verifyZeroInteractions(splitShadeOverScroller)
+    }
+
+    @Test
+    fun onPanelExpansionChanged_inSplitShade_onUnlockedShade_forwardsToSplitShadeOverScroller() {
+        initLateProperties()
+        enableSplitShade()
+        setOnUnlockedShade()
+
+        startPanelExpansion()
+
+        verify(splitShadeOverScroller).onPanelStateChanged(STATE_OPENING)
+        verify(splitShadeOverScroller).onDragDownAmountChanged(DEFAULT_DRAG_DOWN_AMOUNT)
+        verifyZeroInteractions(noOpOverScroller)
+    }
+
+    @Test
     fun onPanelStateChanged_notInSplitShade_forwardsToNoOpOverScroller() {
         initLateProperties()
         disableSplitShade()
@@ -129,6 +174,23 @@
         )
     }
 
+    private fun setOnKeyguard() {
+        setShadeState(StatusBarState.KEYGUARD)
+    }
+
+    private fun setOnLockedShade() {
+        setShadeState(StatusBarState.SHADE_LOCKED)
+    }
+
+    private fun setOnUnlockedShade() {
+        setShadeState(StatusBarState.SHADE)
+    }
+
+    private fun setShadeState(state: Int) {
+        whenever(statusBarStateController.state).thenReturn(state)
+        whenever(statusBarStateController.currentOrUpcomingState).thenReturn(state)
+    }
+
     companion object {
         private const val DEFAULT_DRAG_DOWN_AMOUNT = 123f
         private val DEFAULT_EXPANSION_EVENT =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/SplitShadeOverScrollerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/SplitShadeOverScrollerTest.kt
similarity index 98%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/SplitShadeOverScrollerTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/shade/transition/SplitShadeOverScrollerTest.kt
index 5ca15bb..aafd871 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/SplitShadeOverScrollerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/SplitShadeOverScrollerTest.kt
@@ -1,4 +1,4 @@
-package com.android.systemui.statusbar.phone.shade.transition
+package com.android.systemui.shade.transition
 
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index 883e2dc..c5beee8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -30,6 +30,7 @@
 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_TRANSIENT;
 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_TRUST;
 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_USER_LOCKED;
+import static com.android.systemui.keyguard.ScreenLifecycle.SCREEN_ON;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -212,7 +213,7 @@
                 R.string.do_financed_disclosure_with_name, ORGANIZATION_NAME);
 
         when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
-        when(mScreenLifecycle.getScreenState()).thenReturn(ScreenLifecycle.SCREEN_ON);
+        when(mScreenLifecycle.getScreenState()).thenReturn(SCREEN_ON);
         when(mKeyguardUpdateMonitor.isUserUnlocked(anyInt())).thenReturn(true);
 
         when(mIndicationArea.findViewById(R.id.keyguard_indication_text_bottom))
@@ -957,64 +958,170 @@
     }
 
     @Test
-    public void nonBypassFaceSuccess_touchExplorationEnabled_showsSwipeToOpen() {
-        // GIVEN non bypass face auth and touch exploration is enabled
-        when(mKeyguardBypassController.canBypass()).thenReturn(false);
-        when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
-        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
-        createController();
-        String swipeToOpen = mContext.getString(R.string.keyguard_unlock);
-        mController.setVisible(true);
-
-        // WHEN face authenticated
-        mController.getKeyguardCallback().onBiometricAuthenticated(0,
-                BiometricSourceType.FACE, false);
-
-        // THEN show 'swipe up to open' message
-        verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, swipeToOpen);
-    }
-
-    @Test
-    public void nonBypassFaceSuccess_a11yEnabled_showsSwipeToOpen() {
-        // GIVEN non bypass face auth and a11y is enabled
-        when(mKeyguardBypassController.canBypass()).thenReturn(false);
-        when(mAccessibilityManager.isEnabled()).thenReturn(true);
-        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
-        createController();
-        String swipeToOpen = mContext.getString(R.string.keyguard_unlock);
-        mController.setVisible(true);
-
-        // WHEN face auth is successful
-        mController.getKeyguardCallback().onBiometricAuthenticated(0,
-                BiometricSourceType.FACE, false);
-
-        // THEN show 'swipe up to open' message
-        verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, swipeToOpen);
-    }
-
-    @Test
-    public void coEx_nonBypassFaceSuccess_showsPressLockIcon() {
-        // GIVEN udfps is supported, non-bypass face auth, and no a11y enabled
-        when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
-        when(mKeyguardBypassController.canBypass()).thenReturn(false);
-        when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true);
-        when(mAccessibilityManager.isEnabled()).thenReturn(false);
-        when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
+    public void coEx_faceSuccess_showsPressToOpen() {
+        // GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, no a11y enabled
         when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
         when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
                 .thenReturn(true);
+        when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
+        when(mAccessibilityManager.isEnabled()).thenReturn(false);
+        when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
         createController();
         mController.setVisible(true);
 
         // WHEN face auth succeeds
+        when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true);
         mController.getKeyguardCallback().onBiometricAuthenticated(0,
                 BiometricSourceType.FACE, false);
 
-        // THEN press unlock icon to open message shows
-        String pressLockIcon = mContext.getString(R.string.keyguard_face_successful_unlock_press);
-        verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, pressLockIcon);
+        // THEN 'face unlocked. press unlock icon to open' message shows
+        String pressToOpen = mContext.getString(R.string.keyguard_face_successful_unlock_press);
+        verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, pressToOpen);
 
-        assertThat(mTextView.getText()).isNotEqualTo(pressLockIcon);
+        assertThat(mTextView.getText()).isNotEqualTo(pressToOpen);
+    }
+
+
+    @Test
+    public void coEx_faceSuccess_touchExplorationEnabled_showsFaceUnlockedSwipeToOpen() {
+        // GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, a11y enabled
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+        when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+                .thenReturn(true);
+        when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
+        when(mAccessibilityManager.isEnabled()).thenReturn(true);
+        when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
+        createController();
+        mController.setVisible(true);
+
+        // WHEN face authenticated
+        when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true);
+        mController.getKeyguardCallback().onBiometricAuthenticated(0,
+                BiometricSourceType.FACE, false);
+
+        // THEN show 'face unlocked. swipe up to open' message
+        String faceUnlockedSwipeToOpen =
+                mContext.getString(R.string.keyguard_face_successful_unlock_swipe);
+        verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, faceUnlockedSwipeToOpen);
+    }
+
+    @Test
+    public void coEx_faceSuccess_a11yEnabled_showsFaceUnlockedSwipeToOpen() {
+        // GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, a11y is enabled
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+        when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+                .thenReturn(true);
+        when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
+        when(mAccessibilityManager.isEnabled()).thenReturn(true);
+        createController();
+        mController.setVisible(true);
+
+        // WHEN face auth is successful
+        when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true);
+        mController.getKeyguardCallback().onBiometricAuthenticated(0,
+                BiometricSourceType.FACE, false);
+
+        // THEN show 'swipe up to open' message
+        String faceUnlockedSwipeToOpen =
+                mContext.getString(R.string.keyguard_face_successful_unlock_swipe);
+        verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, faceUnlockedSwipeToOpen);
+    }
+
+    @Test
+    public void faceOnly_faceSuccess_showsFaceUnlockedSwipeToOpen() {
+        // GIVEN bouncer isn't showing, can skip bouncer, no udfps supported
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+        when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+                .thenReturn(true);
+        when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(false);
+        createController();
+        mController.setVisible(true);
+
+        // WHEN face auth is successful
+        when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true);
+        mController.getKeyguardCallback().onBiometricAuthenticated(0,
+                BiometricSourceType.FACE, false);
+
+        // THEN show 'swipe up to open' message
+        String faceUnlockedSwipeToOpen =
+                mContext.getString(R.string.keyguard_face_successful_unlock_swipe);
+        verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, faceUnlockedSwipeToOpen);
+    }
+
+    @Test
+    public void udfpsOnly_a11yEnabled_showsSwipeToOpen() {
+        // GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, a11y is enabled
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+        when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+                .thenReturn(true);
+        when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
+        when(mAccessibilityManager.isEnabled()).thenReturn(true);
+        when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
+        createController();
+        mController.setVisible(true);
+
+        // WHEN showActionToUnlock
+        mController.showActionToUnlock();
+
+        // THEN show 'swipe up to open' message
+        String swipeToOpen = mContext.getString(R.string.keyguard_unlock);
+        verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, swipeToOpen);
+    }
+
+    @Test
+    public void udfpsOnly_showsPressToOpen() {
+        // GIVEN bouncer isn't showing, udfps is supported, a11y is NOT enabled, can skip bouncer
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+        when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+                .thenReturn(true);
+        when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
+        when(mAccessibilityManager.isEnabled()).thenReturn(false);
+        when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
+        createController();
+        mController.setVisible(true);
+
+        // WHEN showActionToUnlock
+        mController.showActionToUnlock();
+
+        // THEN show 'press unlock icon to open' message
+        String pressToOpen = mContext.getString(R.string.keyguard_unlock_press);
+        verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, pressToOpen);
+    }
+
+    @Test
+    public void canSkipBouncer_noSecurity_showSwipeToUnlockHint() {
+        // GIVEN bouncer isn't showing, can skip bouncer, no security (udfps isn't supported,
+        // face wasn't authenticated)
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+        when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+                .thenReturn(true);
+        when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(false);
+        createController();
+        mController.setVisible(true);
+
+        // WHEN showActionToUnlock
+        mController.showActionToUnlock();
+
+        // THEN show 'swipe up to open' message
+        String swipeToOpen = mContext.getString(R.string.keyguard_unlock);
+        verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, swipeToOpen);
+    }
+
+    @Test
+    public void cannotSkipBouncer_showSwipeToUnlockHint() {
+        // GIVEN bouncer isn't showing and cannot skip bouncer
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+        when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+                .thenReturn(false);
+        createController();
+        mController.setVisible(true);
+
+        // WHEN showActionToUnlock
+        mController.showActionToUnlock();
+
+        // THEN show 'swipe up to open' message
+        String swipeToOpen = mContext.getString(R.string.keyguard_unlock);
+        verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, swipeToOpen);
     }
 
     private void sendUpdateDisclosureBroadcast() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
index 562c970..fe1cd97 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
@@ -1,6 +1,5 @@
 package com.android.systemui.statusbar
 
-import org.mockito.Mockito.`when` as whenever
 import android.test.suitebuilder.annotation.SmallTest
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
@@ -14,6 +13,7 @@
 import com.android.systemui.media.MediaHierarchyManager
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.plugins.qs.QS
+import com.android.systemui.shade.NotificationPanelViewController
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper
 import com.android.systemui.statusbar.notification.stack.AmbientState
@@ -22,7 +22,6 @@
 import com.android.systemui.statusbar.phone.CentralSurfaces
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.phone.LSShadeTransitionLogger
-import com.android.systemui.statusbar.phone.NotificationPanelViewController
 import com.android.systemui.statusbar.phone.ScrimController
 import com.android.systemui.statusbar.policy.FakeConfigurationController
 import org.junit.After
@@ -45,6 +44,7 @@
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyZeroInteractions
+import org.mockito.Mockito.`when` as whenever
 import org.mockito.junit.MockitoJUnit
 
 private fun <T> anyObject(): T {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconListTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconListTest.java
deleted file mode 100644
index 4c20b61..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconListTest.java
+++ /dev/null
@@ -1,175 +0,0 @@
-package com.android.systemui.statusbar;
-
-import static com.android.systemui.statusbar.phone.StatusBarIconController.TAG_PRIMARY;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.test.suitebuilder.annotation.SmallTest;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.phone.StatusBarIconHolder;
-import com.android.systemui.statusbar.phone.StatusBarIconList;
-import com.android.systemui.statusbar.phone.StatusBarIconList.Slot;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class StatusBarIconListTest extends SysuiTestCase {
-
-    private final static String[] STATUS_BAR_SLOTS = {"aaa", "bbb", "ccc"};
-
-    @Test
-    public void testGetExistingSlot() {
-        StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
-        assertEquals(1, statusBarIconList.getSlotIndex("bbb"));
-        assertEquals(2, statusBarIconList.getSlotIndex("ccc"));
-    }
-
-    @Test
-    public void testGetNonexistingSlot() {
-        StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
-        assertEquals(0, statusBarIconList.getSlotIndex("aaa"));
-        assertEquals(3, statusBarIconList.size());
-        assertEquals(0, statusBarIconList.getSlotIndex("zzz")); // new content added in front
-        assertEquals(1, statusBarIconList.getSlotIndex("aaa")); // slid back
-        assertEquals(4, statusBarIconList.size());
-    }
-
-    @Test
-    public void testAddSlotSlidesIcons() {
-        StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
-        StatusBarIconHolder sbHolder = mock(StatusBarIconHolder.class);
-        statusBarIconList.setIcon(0, sbHolder);
-        statusBarIconList.getSlotIndex("zzz"); // new content added in front
-        assertNull(statusBarIconList.getIcon(0, TAG_PRIMARY));
-        assertEquals(sbHolder, statusBarIconList.getIcon(1, TAG_PRIMARY));
-    }
-
-    @Test
-    public void testGetAndSetIcon() {
-        StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
-        StatusBarIconHolder sbHolderA = mock(StatusBarIconHolder.class);
-        StatusBarIconHolder sbHolderB = mock(StatusBarIconHolder.class);
-        statusBarIconList.setIcon(0, sbHolderA);
-        statusBarIconList.setIcon(1, sbHolderB);
-        assertEquals(sbHolderA, statusBarIconList.getIcon(0, TAG_PRIMARY));
-        assertEquals(sbHolderB, statusBarIconList.getIcon(1, TAG_PRIMARY));
-        assertNull(statusBarIconList.getIcon(2, TAG_PRIMARY)); // icon not set
-    }
-
-    @Test
-    public void testRemoveIcon() {
-        StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
-        StatusBarIconHolder sbHolderA = mock(StatusBarIconHolder.class);
-        StatusBarIconHolder sbHolderB = mock(StatusBarIconHolder.class);
-        statusBarIconList.setIcon(0, sbHolderA);
-        statusBarIconList.setIcon(1, sbHolderB);
-        statusBarIconList.removeIcon(0, TAG_PRIMARY);
-        assertNull(statusBarIconList.getIcon(0, TAG_PRIMARY)); // icon not set
-    }
-
-    @Test
-    public void testGetViewIndex_NoMultiples() {
-        StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
-        StatusBarIconHolder sbHolder = mock(StatusBarIconHolder.class);
-        statusBarIconList.setIcon(2, sbHolder);
-        // Icon for item 2 is 0th child view.
-        assertEquals(0, statusBarIconList.getViewIndex(2, TAG_PRIMARY));
-        statusBarIconList.setIcon(0, sbHolder);
-        // Icon for item 0 is 0th child view,
-        assertEquals(0, statusBarIconList.getViewIndex(0, TAG_PRIMARY));
-        // and item 2 is now 1st child view.
-        assertEquals(1, statusBarIconList.getViewIndex(2, TAG_PRIMARY));
-    }
-
-    @Test
-    public void testGetViewIndex_MultipleIconsPerSlot() {
-        StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
-        StatusBarIconHolder sbHolder = mock(StatusBarIconHolder.class);
-
-        statusBarIconList.setIcon(2, sbHolder); // item 2, one icon 0th child
-
-        // All of these can be added to the same slot
-        // no tag bc it defaults to 0
-        StatusBarIconHolder sbHolder2 = mock(StatusBarIconHolder.class);
-        StatusBarIconHolder sbHolder3 = mock(StatusBarIconHolder.class);
-        int sb3Tag = 1;
-        when(sbHolder3.getTag()).thenReturn(sb3Tag);
-        StatusBarIconHolder sbHolder4 = mock(StatusBarIconHolder.class);
-        int sb4Tag = 2;
-        when(sbHolder4.getTag()).thenReturn(sb4Tag);
-
-        // Put a holder at slot 1, verify that it is first
-        statusBarIconList.setIcon(1, sbHolder2);
-        assertEquals(0, statusBarIconList.getViewIndex(1, TAG_PRIMARY));
-
-        // Put another holder at slot 1, verify it's index 0 and the rest come after
-        statusBarIconList.setIcon(1, sbHolder3);
-        assertEquals(0, statusBarIconList.getViewIndex(1, sb3Tag));
-        assertEquals(1, statusBarIconList.getViewIndex(1, TAG_PRIMARY));
-        // First icon should be at the end
-        assertEquals(2, statusBarIconList.getViewIndex(2, TAG_PRIMARY));
-
-        // Put another one in there just for good measure
-        statusBarIconList.setIcon(1, sbHolder4);
-        assertEquals(0, statusBarIconList.getViewIndex(1, sb4Tag));
-        assertEquals(1, statusBarIconList.getViewIndex(1, sb3Tag));
-        assertEquals(2, statusBarIconList.getViewIndex(1, TAG_PRIMARY));
-        assertEquals(3, statusBarIconList.getViewIndex(2, TAG_PRIMARY));
-    }
-
-    /**
-     * StatusBarIconList.Slot tests
-     */
-
-    @Test
-    public void testSlot_ViewOrder() {
-        Slot testSlot = new Slot("test_name", null);
-
-        // no tag bc it defaults to 0
-        StatusBarIconHolder sbHolder1 = mock(StatusBarIconHolder.class);
-        StatusBarIconHolder sbHolder2 = mock(StatusBarIconHolder.class);
-        int sb2Tag = 1;
-        when(sbHolder2.getTag()).thenReturn(sb2Tag);
-        StatusBarIconHolder sbHolder3 = mock(StatusBarIconHolder.class);
-        int sb3Tag = 2;
-        when(sbHolder3.getTag()).thenReturn(sb3Tag);
-
-        // Add 3 icons in the same slot, and verify that the list we get is equal to what we gave
-        testSlot.addHolder(sbHolder1);
-        testSlot.addHolder(sbHolder2);
-        testSlot.addHolder(sbHolder3);
-
-        // View order is reverse of the order added
-        ArrayList<StatusBarIconHolder> expected = new ArrayList<>();
-        expected.add(sbHolder3);
-        expected.add(sbHolder2);
-        expected.add(sbHolder1);
-
-        assertTrue(listsEqual(expected, testSlot.getHolderListInViewOrder()));
-    }
-
-    private boolean listsEqual(List<StatusBarIconHolder> list1, List<StatusBarIconHolder> list2) {
-        if (list1.size() != list2.size())  return false;
-
-        for (int i = 0; i < list1.size(); i++) {
-            if (!list1.get(i).equals(list2.get(i))) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
index 20747a0..790865b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
@@ -56,6 +56,7 @@
 import com.android.systemui.util.settings.SecureSettings
 import com.android.systemui.util.time.FakeSystemClock
 import java.util.Optional
+import java.util.concurrent.Executor
 import org.junit.Before
 import org.junit.Test
 import org.mockito.ArgumentCaptor
@@ -105,6 +106,9 @@
     private lateinit var deviceProvisionedController: DeviceProvisionedController
 
     @Mock
+    private lateinit var bgExecutor: Executor
+
+    @Mock
     private lateinit var handler: Handler
 
     @Mock
@@ -203,6 +207,7 @@
                 keyguardBypassController,
                 execution,
                 executor,
+                bgExecutor,
                 handler,
                 Optional.of(plugin)
         )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index 16b0376..aeef6b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -19,6 +19,8 @@
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
 import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED;
 import static android.service.notification.NotificationListenerService.REASON_CANCEL;
+import static android.service.notification.NotificationStats.DISMISSAL_SHADE;
+import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
 
 import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON;
 
@@ -41,6 +43,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.ActivityManager;
@@ -50,6 +53,7 @@
 import android.content.Intent;
 import android.graphics.drawable.Icon;
 import android.os.Handler;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.service.notification.NotificationListenerService.Ranking;
 import android.service.notification.NotificationListenerService.RankingMap;
@@ -91,7 +95,9 @@
 import com.android.systemui.statusbar.notification.row.RowInflaterTask;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.leak.LeakDetector;
+import com.android.systemui.util.time.FakeSystemClock;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -138,9 +144,14 @@
     @Mock private NotificationMediaManager mNotificationMediaManager;
     @Mock private NotificationRowBinder mNotificationRowBinder;
     @Mock private NotificationListener mNotificationListener;
+    @Mock private IStatusBarService mStatusBarService;
+
+    private FakeSystemClock mFakeSystemClock = new FakeSystemClock();
+    private FakeExecutor mBgExecutor = new FakeExecutor(mFakeSystemClock);
 
     private int mId;
     private NotificationEntry mEntry;
+    private DismissedByUserStats mStats;
     private StatusBarNotification mSbn;
     private NotificationEntryManager mEntryManager;
 
@@ -191,6 +202,7 @@
                 Handler.createAsync(TestableLooper.get(this).getLooper()));
 
         mEntry = createNotification();
+        mStats = defaultStats(mEntry);
         mSbn = mEntry.getSbn();
 
         when(mNotifPipelineFlags.isNewPipelineEnabled()).thenReturn(false);
@@ -201,9 +213,10 @@
                 () -> mNotificationRowBinder,
                 () -> mRemoteInputManager,
                 mLeakDetector,
-                mock(IStatusBarService.class),
+                mStatusBarService,
                 NotifLiveDataStoreMocksKt.createNotifLiveDataStoreImplMock(),
-                mock(DumpManager.class)
+                mock(DumpManager.class),
+                mBgExecutor
         );
         mEntryManager.initialize(
                 mNotificationListener,
@@ -316,6 +329,31 @@
     }
 
     @Test
+    public void testPerformRemoveNotification_sendRemovalToServer() throws RemoteException {
+        // GIVEN an entry manager with a notification
+        mEntryManager.addActiveNotificationForTest(mEntry);
+
+        // GIVEN interceptor that doesn't intercept
+        when(mRemoveInterceptor.onNotificationRemoveRequested(
+                eq(mEntry.getKey()), argThat(matchEntryOnKey()), anyInt()))
+                .thenReturn(false);
+
+        // WHEN the notification entry is removed
+        mEntryManager.performRemoveNotification(mSbn, mStats, REASON_CANCEL);
+
+        // THEN notification removal is sent to the server
+        FakeExecutor.exhaustExecutors(mBgExecutor);
+        verify(mStatusBarService).onNotificationClear(
+                mSbn.getPackageName(),
+                mSbn.getUser().getIdentifier(),
+                mSbn.getKey(),
+                mStats.dismissalSurface,
+                mStats.dismissalSentiment,
+                mStats.notificationVisibility);
+        verifyNoMoreInteractions(mStatusBarService);
+    }
+
+    @Test
     public void testRemoveNotification_onEntryRemoveNotFiredIfEntryDoesntExist() {
 
         mEntryManager.removeNotification("not_a_real_key", mRankingMap, UNDEFINED_DISMISS_REASON);
@@ -573,23 +611,6 @@
                 any(NotificationVisibility.class), anyBoolean(), eq(UNDEFINED_DISMISS_REASON));
     }
 
-    private NotificationEntry createNotification() {
-        Notification.Builder n = new Notification.Builder(mContext, "id")
-                .setSmallIcon(R.drawable.ic_person)
-                .setContentTitle("Title")
-                .setContentText("Text");
-
-        return new NotificationEntryBuilder()
-                .setPkg(TEST_PACKAGE_NAME)
-                .setOpPkg(TEST_PACKAGE_NAME)
-                .setUid(TEST_UID)
-                .setId(mId++)
-                .setNotification(n.build())
-                .setChannel(new NotificationChannel("id", "", IMPORTANCE_DEFAULT))
-                .setUser(new UserHandle(ActivityManager.getCurrentUser()))
-                .build();
-    }
-
     /* Tests annexed from NotificationDataTest go here */
 
     @Test
@@ -713,4 +734,28 @@
             return mManagedNotifs.contains(notificationKey);
         }
     }
+
+    private NotificationEntry createNotification() {
+        Notification.Builder n = new Notification.Builder(mContext, "id")
+                .setSmallIcon(R.drawable.ic_person)
+                .setContentTitle("Title")
+                .setContentText("Text");
+
+        return new NotificationEntryBuilder()
+                .setPkg(TEST_PACKAGE_NAME)
+                .setOpPkg(TEST_PACKAGE_NAME)
+                .setUid(TEST_UID)
+                .setId(mId++)
+                .setNotification(n.build())
+                .setChannel(new NotificationChannel("id", "", IMPORTANCE_DEFAULT))
+                .setUser(new UserHandle(ActivityManager.getCurrentUser()))
+                .build();
+    }
+
+    private static DismissedByUserStats defaultStats(NotificationEntry entry) {
+        return new DismissedByUserStats(
+                DISMISSAL_SHADE,
+                DISMISS_SENTIMENT_NEUTRAL,
+                NotificationVisibility.obtain(entry.getKey(), 7, 2, true));
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
index 9f82a567..f4458bb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
@@ -6,11 +6,11 @@
 import androidx.test.filters.SmallTest
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.shade.NotificationShadeWindowViewController
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
-import com.android.systemui.statusbar.phone.NotificationShadeWindowViewController
 import com.android.systemui.statusbar.policy.HeadsUpUtil
 import junit.framework.Assert.assertFalse
 import junit.framework.Assert.assertTrue
@@ -19,8 +19,8 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
-import org.mockito.Mockito.`when`
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
 import org.mockito.junit.MockitoJUnit
 
 @SmallTest
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
index ef763d9..4df99be 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
@@ -92,6 +92,7 @@
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionLogger;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifDismissInterceptor;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender;
+import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.time.FakeSystemClock;
 
 import org.junit.Before;
@@ -146,6 +147,7 @@
 
     private NoManSimulator mNoMan;
     private FakeSystemClock mClock = new FakeSystemClock();
+    private FakeExecutor mBgExecutor = new FakeExecutor(mClock);
 
     @Before
     public void setUp() {
@@ -162,6 +164,7 @@
                 mNotifPipelineFlags,
                 mLogger,
                 mMainHandler,
+                mBgExecutor,
                 mEulogizer,
                 mock(DumpManager.class));
         mCollection.attach(mGroupCoalescer);
@@ -461,6 +464,8 @@
         DismissedByUserStats stats = defaultStats(entry2);
         mCollection.dismissNotification(entry2, defaultStats(entry2));
 
+        FakeExecutor.exhaustExecutors(mBgExecutor);
+
         // THEN we send the dismissal to system server
         verify(mStatusBarService).onNotificationClear(
                 notif2.sbn.getPackageName(),
@@ -674,6 +679,8 @@
         mInterceptor1.onEndInterceptionCallback.onEndDismissInterception(mInterceptor1, entry,
                 stats);
 
+        FakeExecutor.exhaustExecutors(mBgExecutor);
+
         // THEN we send the dismissal to system server
         verify(mStatusBarService).onNotificationClear(
                 eq(notif.sbn.getPackageName()),
@@ -1211,6 +1218,7 @@
                         new Pair<>(entry2, defaultStats(entry2))));
 
         // THEN we send the dismissals to system server
+        FakeExecutor.exhaustExecutors(mBgExecutor);
         verify(mStatusBarService).onNotificationClear(
                 notif1.sbn.getPackageName(),
                 notif1.sbn.getUser().getIdentifier(),
@@ -1577,6 +1585,7 @@
 
         // WHEN finally dismissing
         onDismiss.run();
+        FakeExecutor.exhaustExecutors(mBgExecutor);
         verify(mStatusBarService).onNotificationClear(any(), anyInt(), eq(notifEvent.key),
                 anyInt(), anyInt(), any());
         verifyNoMoreInteractions(mStatusBarService);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
index 555adfd..dfa38ab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
@@ -1028,37 +1028,37 @@
         // WHEN each pluggable is invalidated THEN the list is re-rendered
 
         clearInvocations(mOnRenderListListener);
-        packageFilter.invalidateList();
+        packageFilter.invalidateList(null);
         assertTrue(mPipelineChoreographer.isScheduled());
         mPipelineChoreographer.runIfScheduled();
         verify(mOnRenderListListener).onRenderList(anyList());
 
         clearInvocations(mOnRenderListListener);
-        idPromoter.invalidateList();
+        idPromoter.invalidateList(null);
         assertTrue(mPipelineChoreographer.isScheduled());
         mPipelineChoreographer.runIfScheduled();
         verify(mOnRenderListListener).onRenderList(anyList());
 
         clearInvocations(mOnRenderListListener);
-        section.invalidateList();
+        section.invalidateList(null);
         assertTrue(mPipelineChoreographer.isScheduled());
         mPipelineChoreographer.runIfScheduled();
         verify(mOnRenderListListener).onRenderList(anyList());
 
         clearInvocations(mOnRenderListListener);
-        hypeComparator.invalidateList();
+        hypeComparator.invalidateList(null);
         assertTrue(mPipelineChoreographer.isScheduled());
         mPipelineChoreographer.runIfScheduled();
         verify(mOnRenderListListener).onRenderList(anyList());
 
         clearInvocations(mOnRenderListListener);
-        sectionComparator.invalidateList();
+        sectionComparator.invalidateList(null);
         assertTrue(mPipelineChoreographer.isScheduled());
         mPipelineChoreographer.runIfScheduled();
         verify(mOnRenderListListener).onRenderList(anyList());
 
         clearInvocations(mOnRenderListListener);
-        preRenderInvalidator.invalidateList();
+        preRenderInvalidator.invalidateList(null);
         assertTrue(mPipelineChoreographer.isScheduled());
         mPipelineChoreographer.runIfScheduled();
         verify(mOnRenderListListener).onRenderList(anyList());
@@ -1584,7 +1584,7 @@
 
         // WHEN visual stability manager allows group changes again
         mStabilityManager.setAllowGroupChanges(true);
-        mStabilityManager.invalidateList();
+        mStabilityManager.invalidateList(null);
         mPipelineChoreographer.runIfScheduled();
 
         // THEN entries are grouped
@@ -1623,7 +1623,7 @@
 
         // WHEN section changes are allowed again
         mStabilityManager.setAllowSectionChanges(true);
-        mStabilityManager.invalidateList();
+        mStabilityManager.invalidateList(null);
         mPipelineChoreographer.runIfScheduled();
 
         // THEN the section updates
@@ -1719,7 +1719,7 @@
     public void testOutOfOrderPreGroupFilterInvalidationThrows() {
         // GIVEN a PreGroupNotifFilter that gets invalidated during the grouping stage
         NotifFilter filter = new PackageFilter(PACKAGE_5);
-        OnBeforeTransformGroupsListener listener = (list) -> filter.invalidateList();
+        OnBeforeTransformGroupsListener listener = (list) -> filter.invalidateList(null);
         mListBuilder.addPreGroupFilter(filter);
         mListBuilder.addOnBeforeTransformGroupsListener(listener);
 
@@ -1735,7 +1735,7 @@
         // GIVEN a NotifPromoter that gets invalidated during the sorting stage
         NotifPromoter promoter = new IdPromoter(47);
         OnBeforeSortListener listener =
-                (list) -> promoter.invalidateList();
+                (list) -> promoter.invalidateList(null);
         mListBuilder.addPromoter(promoter);
         mListBuilder.addOnBeforeSortListener(listener);
 
@@ -1751,7 +1751,7 @@
         // GIVEN a NotifComparator that gets invalidated during the finalizing stage
         NotifComparator comparator = new HypeComparator(PACKAGE_5);
         OnBeforeRenderListListener listener =
-                (list) -> comparator.invalidateList();
+                (list) -> comparator.invalidateList(null);
         mListBuilder.setComparators(singletonList(comparator));
         mListBuilder.addOnBeforeRenderListListener(listener);
 
@@ -1766,7 +1766,7 @@
     public void testOutOfOrderPreRenderFilterInvalidationThrows() {
         // GIVEN a PreRenderNotifFilter that gets invalidated during the finalizing stage
         NotifFilter filter = new PackageFilter(PACKAGE_5);
-        OnBeforeRenderListListener listener = (list) -> filter.invalidateList();
+        OnBeforeRenderListListener listener = (list) -> filter.invalidateList(null);
         mListBuilder.addFinalizeFilter(filter);
         mListBuilder.addOnBeforeRenderListListener(listener);
 
@@ -1903,7 +1903,7 @@
     public void testInOrderPreRenderFilter() {
         // GIVEN a PreRenderFilter that gets invalidated during the grouping stage
         NotifFilter filter = new PackageFilter(PACKAGE_5);
-        OnBeforeTransformGroupsListener listener = (list) -> filter.invalidateList();
+        OnBeforeTransformGroupsListener listener = (list) -> filter.invalidateList(null);
         mListBuilder.addFinalizeFilter(filter);
         mListBuilder.addOnBeforeTransformGroupsListener(listener);
 
@@ -1936,8 +1936,8 @@
         mListBuilder.addFinalizeFilter(filter2);
 
         // WHEN both filters invalidate
-        filter1.invalidateList();
-        filter2.invalidateList();
+        filter1.invalidateList(null);
+        filter2.invalidateList(null);
 
         // THEN the pipeline choreographer is scheduled to evaluate, AND the pipeline hasn't
         // actually run.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java
index d21053b..27542a4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java
@@ -18,7 +18,9 @@
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -51,7 +53,6 @@
     @Mock private NotificationLockscreenUserManager mLockscreenUserManager;
     @Mock private NotifPipeline mNotifPipeline;
     @Mock private PluggableListener<NotifFilter> mInvalidationListener;
-    @Mock private SharedCoordinatorLogger mLogger;
 
     @Captor private ArgumentCaptor<UserChangedListener> mUserChangedListenerCaptor;
     @Captor private ArgumentCaptor<NotifFilter> mNotifFilterCaptor;
@@ -66,7 +67,7 @@
         MockitoAnnotations.initMocks(this);
 
         HideNotifsForOtherUsersCoordinator coordinator =
-                new HideNotifsForOtherUsersCoordinator(mLockscreenUserManager, mLogger);
+                new HideNotifsForOtherUsersCoordinator(mLockscreenUserManager);
         coordinator.attach(mNotifPipeline);
 
         verify(mLockscreenUserManager).addUserChangedListener(mUserChangedListenerCaptor.capture());
@@ -102,6 +103,6 @@
         mCapturedUserChangeListener.onCurrentProfilesChanged(new SparseArray<>());
 
         // THEN the filter is invalidated
-        verify(mInvalidationListener).onPluggableInvalidated(mCapturedNotifFilter);
+        verify(mInvalidationListener).onPluggableInvalidated(eq(mCapturedNotifFilter), any());
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
index 8c506a6..7e2e6f6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
@@ -41,7 +41,6 @@
     private val notifPipeline: NotifPipeline = mock()
     private val keyguardNotifVisibilityProvider: KeyguardNotificationVisibilityProvider = mock()
     private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider = mock()
-    private val sharedCoordinatorLogger: SharedCoordinatorLogger = mock()
     private val statusBarStateController: StatusBarStateController = mock()
 
     private lateinit var onStateChangeListener: Consumer<String>
@@ -52,7 +51,6 @@
         val keyguardCoordinator = KeyguardCoordinator(
             keyguardNotifVisibilityProvider,
             sectionHeaderVisibilityProvider,
-            sharedCoordinatorLogger,
             statusBarStateController
         )
         keyguardCoordinator.attach(notifPipeline)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
index a6d3719..f4adf69 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
@@ -463,7 +463,8 @@
         }
 
         @Override
-        public void abortInflation(@NonNull NotificationEntry entry) {
+        public boolean abortInflation(@NonNull NotificationEntry entry) {
+            return false;
         }
 
         public InflationCallback getInflateCallback(NotificationEntry entry) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
index a2d8e3d..27be4c8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
@@ -34,6 +34,7 @@
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.withArgCaptor
 import dagger.BindsInstance
@@ -79,7 +80,7 @@
 
         dynamicPrivacyListener.onDynamicPrivacyChanged()
 
-        verify(invalidationListener).onPluggableInvalidated(invalidator)
+        verify(invalidationListener).onPluggableInvalidated(eq(invalidator), any())
     }
 
     @Test
@@ -265,4 +266,4 @@
             @BindsInstance keyguardStateController: KeyguardStateController
         ): TestSensitiveContentCoordinatorComponent
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinatorTest.kt
index fdff6e9..d4f0505 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinatorTest.kt
@@ -35,21 +35,23 @@
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
 import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.withArgCaptor
 import com.android.systemui.util.time.FakeSystemClock
+import java.util.concurrent.TimeUnit
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
 import org.junit.Before
 import org.junit.Test
 import org.mockito.Mock
-import org.mockito.Mockito.`when`
 import org.mockito.Mockito.anyString
 import org.mockito.Mockito.clearInvocations
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
-import java.util.concurrent.TimeUnit
 
 @SmallTest
 class SmartspaceDedupingCoordinatorTest : SysuiTestCase() {
@@ -349,7 +351,7 @@
 
         // THEN the new pipeline is invalidated (but the old one isn't because it's not
         // necessary) because the notif should no longer be filtered out
-        verify(pluggableListener).onPluggableInvalidated(filter)
+        verify(pluggableListener).onPluggableInvalidated(eq(filter), any())
         verify(notificationEntryManager, never()).updateNotifications(anyString())
         assertFalse(filter.shouldFilterOut(entry2HasNotRecentlyAlerted, now))
     }
@@ -387,7 +389,7 @@
     }
 
     private fun verifyPipelinesInvalidated() {
-        verify(pluggableListener).onPluggableInvalidated(filter)
+        verify(pluggableListener).onPluggableInvalidated(eq(filter), any())
         verify(notificationEntryManager).updateNotifications(anyString())
     }
 
@@ -396,7 +398,7 @@
     }
 
     private fun verifyPipelinesNotInvalidated() {
-        verify(pluggableListener, never()).onPluggableInvalidated(filter)
+        verify(pluggableListener, never()).onPluggableInvalidated(eq(filter), any())
         verify(notificationEntryManager, never()).updateNotifications(anyString())
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
index 2f37f89..c961cec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
@@ -19,6 +19,7 @@
 import static junit.framework.Assert.assertFalse;
 
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.never;
@@ -35,6 +36,7 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shade.NotifPanelEvents;
 import com.android.systemui.statusbar.notification.collection.GroupEntry;
 import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
@@ -43,7 +45,6 @@
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable;
 import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
-import com.android.systemui.statusbar.phone.NotifPanelEvents;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.time.FakeSystemClock;
@@ -55,6 +56,7 @@
 import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.mockito.verification.VerificationMode;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
@@ -130,7 +132,7 @@
         doAnswer(i -> {
             mNotifStabilityManager.onBeginRun();
             return null;
-        }).when(mInvalidateListener).onPluggableInvalidated(eq(mNotifStabilityManager));
+        }).when(mInvalidateListener).onPluggableInvalidated(eq(mNotifStabilityManager), any());
     }
 
     @Test
@@ -280,7 +282,7 @@
         mCoordinator.temporarilyAllowSectionChanges(mEntry, mFakeSystemClock.uptimeMillis());
 
         // THEN the notification list is invalidated
-        verify(mInvalidateListener, times(1)).onPluggableInvalidated(mNotifStabilityManager);
+        verifyStabilityManagerWasInvalidated(times(1));
     }
 
     @Test
@@ -295,7 +297,7 @@
         mCoordinator.temporarilyAllowSectionChanges(mEntry, mFakeSystemClock.currentTimeMillis());
 
         // THEN invalidate is not called because this entry was never suppressed from reordering
-        verify(mInvalidateListener, never()).onPluggableInvalidated(mNotifStabilityManager);
+        verifyStabilityManagerWasInvalidated(never());
     }
 
     @Test
@@ -312,7 +314,7 @@
 
         // THEN invalidate is not called because this entry was never suppressed from reordering;
         // THEN section changes are allowed for this notification
-        verify(mInvalidateListener, never()).onPluggableInvalidated(mNotifStabilityManager);
+        verifyStabilityManagerWasInvalidated(never());
         assertTrue(mNotifStabilityManager.isSectionChangeAllowed(mEntry));
 
         // WHEN we're pulsing (now disallowing reordering)
@@ -341,13 +343,13 @@
         // WHEN we temporarily allow section changes for this notification entry
         mCoordinator.temporarilyAllowSectionChanges(mEntry, mFakeSystemClock.currentTimeMillis());
         // can now reorder, so invalidates
-        verify(mInvalidateListener, times(1)).onPluggableInvalidated(mNotifStabilityManager);
+        verifyStabilityManagerWasInvalidated(times(1));
 
         // WHEN reordering is now allowed because device isn't pulsing anymore
         setPulsing(false);
 
         // THEN invalidate isn't called a second time since reordering was already allowed
-        verify(mInvalidateListener, times(1)).onPluggableInvalidated(mNotifStabilityManager);
+        verifyStabilityManagerWasInvalidated(times(1));
     }
 
     @Test
@@ -368,7 +370,7 @@
 
         // THEN we never see any calls to invalidate since there weren't any notifications that
         // were being suppressed from grouping or section changes
-        verify(mInvalidateListener, never()).onPluggableInvalidated(mNotifStabilityManager);
+        verifyStabilityManagerWasInvalidated(never());
     }
 
     @Test
@@ -386,7 +388,7 @@
         setPanelExpanded(false);
 
         //  invalidate is called because we were previously suppressing a group change
-        verify(mInvalidateListener, times(1)).onPluggableInvalidated(mNotifStabilityManager);
+        verifyStabilityManagerWasInvalidated(times(1));
     }
 
     @Test
@@ -400,7 +402,7 @@
         setActivityLaunching(false);
 
         // invalidate is called, b/c we were previously suppressing the pipeline from running
-        verify(mInvalidateListener, times(1)).onPluggableInvalidated(mNotifStabilityManager);
+        verifyStabilityManagerWasInvalidated(times(1));
     }
 
     @Test
@@ -414,7 +416,7 @@
         setPanelCollapsing(false);
 
         // invalidate is called, b/c we were previously suppressing the pipeline from running
-        verify(mInvalidateListener, times(1)).onPluggableInvalidated(mNotifStabilityManager);
+        verifyStabilityManagerWasInvalidated(times(1));
     }
 
     @Test
@@ -426,7 +428,7 @@
         setPanelCollapsing(false);
 
         // THEN invalidate is not called, b/c nothing has been suppressed
-        verify(mInvalidateListener, never()).onPluggableInvalidated(mNotifStabilityManager);
+        verifyStabilityManagerWasInvalidated(never());
     }
 
     @Test
@@ -438,7 +440,7 @@
         setActivityLaunching(false);
 
         // THEN invalidate is not called, b/c nothing has been suppressed
-        verify(mInvalidateListener, never()).onPluggableInvalidated(mNotifStabilityManager);
+        verifyStabilityManagerWasInvalidated(never());
     }
 
     @Test
@@ -457,7 +459,7 @@
         setPanelExpanded(false);
 
         //  invalidate is called because we were previously suppressing an entry reorder
-        verify(mInvalidateListener, times(1)).onPluggableInvalidated(mNotifStabilityManager);
+        verifyStabilityManagerWasInvalidated(times(1));
     }
 
     @Test
@@ -474,7 +476,7 @@
         setPanelExpanded(false);
 
         // invalidate is not called because we were not told that an entry reorder was suppressed
-        verify(mInvalidateListener, never()).onPluggableInvalidated(mNotifStabilityManager);
+        verifyStabilityManagerWasInvalidated(never());
     }
 
     @Test
@@ -499,6 +501,10 @@
         assertFalse(mNotifStabilityManager.isGroupPruneAllowed(mGroupEntry));
     }
 
+    private void verifyStabilityManagerWasInvalidated(VerificationMode mode) {
+        verify(mInvalidateListener, mode).onPluggableInvalidated(eq(mNotifStabilityManager), any());
+    }
+
     private void setActivityLaunching(boolean activityLaunching) {
         mNotifPanelEventsCallback.onLaunchingActivityChanged(activityLaunching);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
index 3f56cf9..72d3c2e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
@@ -25,6 +25,7 @@
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
 
 import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking;
+import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
 import static com.android.systemui.statusbar.StatusBarState.SHADE;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -32,6 +33,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -96,6 +98,8 @@
     NotifPipelineFlags mFlags;
     @Mock
     KeyguardNotificationVisibilityProvider mKeyguardNotificationVisibilityProvider;
+    @Mock
+    PendingIntent mPendingIntent;
 
     private NotificationInterruptStateProviderImpl mNotifInterruptionStateProvider;
 
@@ -197,7 +201,7 @@
         ensureStateForHeadsUpWhenAwake();
 
         // WHEN this entry should be filtered out
-        NotificationEntry entry  = createNotification(IMPORTANCE_DEFAULT);
+        NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
         when(mNotificationFilter.shouldFilterOut(entry)).thenReturn(true);
 
         // THEN we shouldn't heads up this entry
@@ -206,11 +210,9 @@
 
     @Test
     public void testDoNotRunFilterOnNewPipeline() {
-        when(mFlags.isNewPipelineEnabled()).thenReturn(true);
         // WHEN this entry should be filtered out
-        NotificationEntry entry  = createNotification(IMPORTANCE_DEFAULT);
+        NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
         mNotifInterruptionStateProvider.shouldHeadsUp(entry);
-        verify(mFlags, times(1)).isNewPipelineEnabled();
         verify(mNotificationFilter, times(0)).shouldFilterOut(eq(entry));
     }
 
@@ -326,7 +328,8 @@
     public void testShouldNotHeadsUp_filtered() throws RemoteException {
         ensureStateForHeadsUpWhenAwake();
         // Make canAlertCommon false by saying it's filtered out
-        when(mNotificationFilter.shouldFilterOut(any())).thenReturn(true);
+        when(mKeyguardNotificationVisibilityProvider.shouldHideNotification(any()))
+                .thenReturn(true);
 
         NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
         assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
@@ -423,6 +426,122 @@
         assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
     }
 
+    @Test
+    public void testShouldNotFullScreen_notPendingIntent() throws RemoteException {
+        NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
+        when(mPowerManager.isInteractive()).thenReturn(true);
+        when(mDreamManager.isDreaming()).thenReturn(false);
+        when(mStatusBarStateController.getState()).thenReturn(SHADE);
+
+        assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
+                .isFalse();
+        verify(mLogger, never()).logNoFullscreen(any(), any());
+        verify(mLogger, never()).logNoFullscreenWarning(any(), any());
+        verify(mLogger, never()).logFullscreen(any(), any());
+    }
+
+    @Test
+    public void testShouldNotFullScreen_notHighImportance() throws RemoteException {
+        NotificationEntry entry = createFsiNotification(IMPORTANCE_DEFAULT, /* silenced */ false);
+        when(mPowerManager.isInteractive()).thenReturn(true);
+        when(mDreamManager.isDreaming()).thenReturn(false);
+        when(mStatusBarStateController.getState()).thenReturn(SHADE);
+
+        assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
+                .isFalse();
+        verify(mLogger).logNoFullscreen(entry, "Not important enough");
+        verify(mLogger, never()).logNoFullscreenWarning(any(), any());
+        verify(mLogger, never()).logFullscreen(any(), any());
+    }
+
+    @Test
+    public void testShouldNotFullScreen_isGroupAlertSilenced() throws RemoteException {
+        NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ true);
+        when(mPowerManager.isInteractive()).thenReturn(false);
+        when(mDreamManager.isDreaming()).thenReturn(true);
+        when(mStatusBarStateController.getState()).thenReturn(KEYGUARD);
+
+        assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
+                .isFalse();
+        verify(mLogger, never()).logNoFullscreen(any(), any());
+        verify(mLogger).logNoFullscreenWarning(entry, "GroupAlertBehavior will prevent HUN");
+        verify(mLogger, never()).logFullscreen(any(), any());
+    }
+
+    @Test
+    public void testShouldFullScreen_notInteractive() throws RemoteException {
+        NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
+        when(mPowerManager.isInteractive()).thenReturn(false);
+        when(mDreamManager.isDreaming()).thenReturn(false);
+        when(mStatusBarStateController.getState()).thenReturn(SHADE);
+
+        assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
+                .isTrue();
+        verify(mLogger, never()).logNoFullscreen(any(), any());
+        verify(mLogger, never()).logNoFullscreenWarning(any(), any());
+        verify(mLogger).logFullscreen(entry, "Device is not interactive");
+    }
+
+    @Test
+    public void testShouldFullScreen_isDreaming() throws RemoteException {
+        NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
+        when(mPowerManager.isInteractive()).thenReturn(true);
+        when(mDreamManager.isDreaming()).thenReturn(true);
+        when(mStatusBarStateController.getState()).thenReturn(SHADE);
+
+        assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
+                .isTrue();
+        verify(mLogger, never()).logNoFullscreen(any(), any());
+        verify(mLogger, never()).logNoFullscreenWarning(any(), any());
+        verify(mLogger).logFullscreen(entry, "Device is dreaming");
+    }
+
+    @Test
+    public void testShouldFullScreen_onKeyguard() throws RemoteException {
+        NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
+        when(mPowerManager.isInteractive()).thenReturn(true);
+        when(mDreamManager.isDreaming()).thenReturn(false);
+        when(mStatusBarStateController.getState()).thenReturn(KEYGUARD);
+
+        assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
+                .isTrue();
+        verify(mLogger, never()).logNoFullscreen(any(), any());
+        verify(mLogger, never()).logNoFullscreenWarning(any(), any());
+        verify(mLogger).logFullscreen(entry, "Keyguard is showing");
+    }
+
+    @Test
+    public void testShouldNotFullScreen_willHun() throws RemoteException {
+        NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
+        when(mPowerManager.isInteractive()).thenReturn(true);
+        when(mPowerManager.isScreenOn()).thenReturn(true);
+        when(mDreamManager.isDreaming()).thenReturn(false);
+        when(mStatusBarStateController.getState()).thenReturn(SHADE);
+
+        assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
+                .isFalse();
+        verify(mLogger).logNoFullscreen(entry, "Expected to HUN");
+        verify(mLogger, never()).logNoFullscreenWarning(any(), any());
+        verify(mLogger, never()).logFullscreen(any(), any());
+    }
+
+    @Test
+    public void testShouldFullScreen_packageSnoozed() throws RemoteException {
+        NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
+        when(mPowerManager.isInteractive()).thenReturn(true);
+        when(mPowerManager.isScreenOn()).thenReturn(true);
+        when(mDreamManager.isDreaming()).thenReturn(false);
+        when(mStatusBarStateController.getState()).thenReturn(SHADE);
+        when(mHeadsUpManager.isSnoozed("a")).thenReturn(true);
+
+        assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
+                .isTrue();
+        verify(mLogger).logNoHeadsUpPackageSnoozed(entry);
+        verify(mLogger, never()).logNoFullscreen(any(), any());
+        verify(mLogger, never()).logNoFullscreenWarning(any(), any());
+        verify(mLogger).logFullscreen(entry, "Expected not to HUN");
+    }
+
     /**
      * Bubbles can happen.
      */
@@ -504,7 +623,8 @@
         ensureStateForBubbleUp();
 
         // Make canAlertCommon false by saying it's filtered out
-        when(mNotificationFilter.shouldFilterOut(any())).thenReturn(true);
+        when(mKeyguardNotificationVisibilityProvider.shouldHideNotification(any()))
+                .thenReturn(true);
 
         assertThat(mNotifInterruptionStateProvider.shouldBubbleUp(createBubble())).isFalse();
     }
@@ -516,8 +636,8 @@
     private NotificationEntry createBubble(String groupKey, Integer groupAlert) {
         Notification.BubbleMetadata data = new Notification.BubbleMetadata.Builder(
                 PendingIntent.getActivity(mContext, 0, new Intent(),
-                    PendingIntent.FLAG_MUTABLE),
-                        Icon.createWithResource(mContext.getResources(), R.drawable.android))
+                        PendingIntent.FLAG_MUTABLE),
+                Icon.createWithResource(mContext.getResources(), R.drawable.android))
                 .build();
         Notification.Builder nb = new Notification.Builder(getContext(), "a")
                 .setContentTitle("title")
@@ -549,6 +669,10 @@
                 .setContentText("content text")
                 .build();
 
+        return createNotification(importance, n);
+    }
+
+    private NotificationEntry createNotification(int importance, Notification n) {
         return new NotificationEntryBuilder()
                 .setPkg("a")
                 .setOpPkg("a")
@@ -559,45 +683,57 @@
                 .build();
     }
 
+    private NotificationEntry createFsiNotification(int importance, boolean silent) {
+        Notification n = new Notification.Builder(getContext(), "a")
+                .setContentTitle("title")
+                .setContentText("content text")
+                .setFullScreenIntent(mPendingIntent, true)
+                .setGroup("fsi")
+                .setGroupAlertBehavior(silent ? GROUP_ALERT_SUMMARY : Notification.GROUP_ALERT_ALL)
+                .build();
+
+        return createNotification(importance, n);
+    }
+
     private final NotificationInterruptSuppressor
             mSuppressAwakeHeadsUp =
             new NotificationInterruptSuppressor() {
-        @Override
-        public String getName() {
-            return "suppressAwakeHeadsUp";
-        }
+                @Override
+                public String getName() {
+                    return "suppressAwakeHeadsUp";
+                }
 
-        @Override
-        public boolean suppressAwakeHeadsUp(NotificationEntry entry) {
-            return true;
-        }
-    };
+                @Override
+                public boolean suppressAwakeHeadsUp(NotificationEntry entry) {
+                    return true;
+                }
+            };
 
     private final NotificationInterruptSuppressor
             mSuppressAwakeInterruptions =
             new NotificationInterruptSuppressor() {
-        @Override
-        public String getName() {
-            return "suppressAwakeInterruptions";
-        }
+                @Override
+                public String getName() {
+                    return "suppressAwakeInterruptions";
+                }
 
-        @Override
-        public boolean suppressAwakeInterruptions(NotificationEntry entry) {
-            return true;
-        }
-    };
+                @Override
+                public boolean suppressAwakeInterruptions(NotificationEntry entry) {
+                    return true;
+                }
+            };
 
     private final NotificationInterruptSuppressor
             mSuppressInterruptions =
             new NotificationInterruptSuppressor() {
-        @Override
-        public String getName() {
-            return "suppressInterruptions";
-        }
+                @Override
+                public String getName() {
+                    return "suppressInterruptions";
+                }
 
-        @Override
-        public boolean suppressInterruptions(NotificationEntry entry) {
-            return true;
-        }
-    };
+                @Override
+                public boolean suppressInterruptions(NotificationEntry entry) {
+                    return true;
+                }
+            };
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerLegacyTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerLegacyTest.java
deleted file mode 100644
index 429d2ed..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerLegacyTest.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification.logging;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Notification;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.UserHandle;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.logging.InstanceId;
-import com.android.internal.statusbar.IStatusBarService;
-import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.NotificationListener;
-import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.StatusBarStateControllerImpl;
-import com.android.systemui.statusbar.notification.NotifPipelineFlags;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.collection.NotifLiveData;
-import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore;
-import com.android.systemui.statusbar.notification.collection.NotifPipeline;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
-import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
-import com.android.systemui.statusbar.notification.logging.nano.Notifications;
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.time.FakeSystemClock;
-
-import com.google.android.collect.Lists;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.util.List;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.Executor;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class NotificationLoggerLegacyTest extends SysuiTestCase {
-    private static final String TEST_PACKAGE_NAME = "test";
-    private static final int TEST_UID = 0;
-
-    @Mock private NotificationListContainer mListContainer;
-    @Mock private IStatusBarService mBarService;
-    @Mock private ExpandableNotificationRow mRow;
-    @Mock private NotificationLogger.ExpansionStateLogger mExpansionStateLogger;
-
-    // Dependency mocks:
-    @Mock private NotifPipelineFlags mNotifPipelineFlags;
-    @Mock private NotifLiveDataStore mNotifLiveDataStore;
-    @Mock private NotifLiveData<List<NotificationEntry>> mActiveNotifList;
-    @Mock private NotificationVisibilityProvider mVisibilityProvider;
-    @Mock private NotificationEntryManager mEntryManager;
-    @Mock private NotifPipeline mNotifPipeline;
-    @Mock private NotificationListener mListener;
-
-    private NotificationEntry mEntry;
-    private TestableNotificationLogger mLogger;
-    private ConcurrentLinkedQueue<AssertionError> mErrorQueue = new ConcurrentLinkedQueue<>();
-    private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
-    private NotificationPanelLoggerFake mNotificationPanelLoggerFake =
-            new NotificationPanelLoggerFake();
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        when(mNotifLiveDataStore.getActiveNotifList()).thenReturn(mActiveNotifList);
-
-        mEntry = new NotificationEntryBuilder()
-                .setPkg(TEST_PACKAGE_NAME)
-                .setOpPkg(TEST_PACKAGE_NAME)
-                .setUid(TEST_UID)
-                .setNotification(new Notification())
-                .setUser(UserHandle.CURRENT)
-                .setInstanceId(InstanceId.fakeInstanceId(1))
-                .build();
-        mEntry.setRow(mRow);
-
-        mLogger = new TestableNotificationLogger(
-                mListener,
-                mUiBgExecutor,
-                mNotifPipelineFlags,
-                mNotifLiveDataStore,
-                mVisibilityProvider,
-                mEntryManager,
-                mNotifPipeline,
-                mock(StatusBarStateControllerImpl.class),
-                mBarService,
-                mExpansionStateLogger
-        );
-        mLogger.setUpWithContainer(mListContainer);
-        verify(mEntryManager).addNotificationEntryListener(any());
-        verify(mNotifPipeline, never()).addCollectionListener(any());
-    }
-
-    @After
-    public void tearDown() {
-        mLogger.mHandler.removeCallbacksAndMessages(null);
-    }
-
-    @Test
-    public void testOnChildLocationsChangedReportsVisibilityChanged() throws Exception {
-        NotificationVisibility[] newlyVisibleKeys = {
-                NotificationVisibility.obtain(mEntry.getKey(), 0, 1, true)
-        };
-        NotificationVisibility[] noLongerVisibleKeys = {};
-        doAnswer(invocation -> {
-                    try {
-                        assertArrayEquals(newlyVisibleKeys,
-                                (NotificationVisibility[]) invocation.getArguments()[0]);
-                        assertArrayEquals(noLongerVisibleKeys,
-                                (NotificationVisibility[]) invocation.getArguments()[1]);
-                    } catch (AssertionError error) {
-                        mErrorQueue.offer(error);
-                    }
-                    return null;
-                }
-        ).when(mBarService).onNotificationVisibilityChanged(any(NotificationVisibility[].class),
-                any(NotificationVisibility[].class));
-
-        when(mListContainer.isInVisibleLocation(any())).thenReturn(true);
-        when(mActiveNotifList.getValue()).thenReturn(Lists.newArrayList(mEntry));
-        mLogger.getChildLocationsChangedListenerForTest().onChildLocationsChanged();
-        TestableLooper.get(this).processAllMessages();
-        mUiBgExecutor.runAllReady();
-
-        if (!mErrorQueue.isEmpty()) {
-            throw mErrorQueue.poll();
-        }
-
-        // |mEntry| won't change visibility, so it shouldn't be reported again:
-        Mockito.reset(mBarService);
-        mLogger.getChildLocationsChangedListenerForTest().onChildLocationsChanged();
-        TestableLooper.get(this).processAllMessages();
-        mUiBgExecutor.runAllReady();
-
-        verify(mBarService, never()).onNotificationVisibilityChanged(any(), any());
-    }
-
-    @Test
-    public void testStoppingNotificationLoggingReportsCurrentNotifications()
-            throws Exception {
-        when(mListContainer.isInVisibleLocation(any())).thenReturn(true);
-        when(mActiveNotifList.getValue()).thenReturn(Lists.newArrayList(mEntry));
-        mLogger.getChildLocationsChangedListenerForTest().onChildLocationsChanged();
-        TestableLooper.get(this).processAllMessages();
-        mUiBgExecutor.runAllReady();
-        Mockito.reset(mBarService);
-
-        setStateAsleep();
-        mLogger.onDozingChanged(false);  // Wake to lockscreen
-        mLogger.onDozingChanged(true);  // And go back to sleep, turning off logging
-        mUiBgExecutor.runAllReady();
-        // The visibility objects are recycled by NotificationLogger, so we can't use specific
-        // matchers here.
-        verify(mBarService, times(1)).onNotificationVisibilityChanged(any(), any());
-    }
-
-    private void setStateAsleep() {
-        mLogger.onPanelExpandedChanged(true);
-        mLogger.onDozingChanged(true);
-        mLogger.onStateChanged(StatusBarState.KEYGUARD);
-    }
-
-    private void setStateAwake() {
-        mLogger.onPanelExpandedChanged(false);
-        mLogger.onDozingChanged(false);
-        mLogger.onStateChanged(StatusBarState.SHADE);
-    }
-
-    @Test
-    public void testLogPanelShownOnWake() {
-        when(mActiveNotifList.getValue()).thenReturn(Lists.newArrayList(mEntry));
-        setStateAsleep();
-        mLogger.onDozingChanged(false);  // Wake to lockscreen
-        assertEquals(1, mNotificationPanelLoggerFake.getCalls().size());
-        assertTrue(mNotificationPanelLoggerFake.get(0).isLockscreen);
-        assertEquals(1, mNotificationPanelLoggerFake.get(0).list.notifications.length);
-        Notifications.Notification n = mNotificationPanelLoggerFake.get(0).list.notifications[0];
-        assertEquals(TEST_PACKAGE_NAME, n.packageName);
-        assertEquals(TEST_UID, n.uid);
-        assertEquals(1, n.instanceId);
-        assertFalse(n.isGroupSummary);
-        assertEquals(Notifications.Notification.SECTION_ALERTING, n.section);
-    }
-
-    @Test
-    public void testLogPanelShownOnShadePull() {
-        when(mActiveNotifList.getValue()).thenReturn(Lists.newArrayList(mEntry));
-        setStateAwake();
-        // Now expand panel
-        mLogger.onPanelExpandedChanged(true);
-        assertEquals(1, mNotificationPanelLoggerFake.getCalls().size());
-        assertFalse(mNotificationPanelLoggerFake.get(0).isLockscreen);
-        assertEquals(1, mNotificationPanelLoggerFake.get(0).list.notifications.length);
-        Notifications.Notification n = mNotificationPanelLoggerFake.get(0).list.notifications[0];
-        assertEquals(TEST_PACKAGE_NAME, n.packageName);
-        assertEquals(TEST_UID, n.uid);
-        assertEquals(1, n.instanceId);
-        assertFalse(n.isGroupSummary);
-        assertEquals(Notifications.Notification.SECTION_ALERTING, n.section);
-    }
-
-
-    @Test
-    public void testLogPanelShownHandlesNullInstanceIds() {
-        // Construct a NotificationEntry like mEntry, but with a null instance id.
-        NotificationEntry entry = new NotificationEntryBuilder()
-                .setPkg(TEST_PACKAGE_NAME)
-                .setOpPkg(TEST_PACKAGE_NAME)
-                .setUid(TEST_UID)
-                .setNotification(new Notification())
-                .setUser(UserHandle.CURRENT)
-                .build();
-        entry.setRow(mRow);
-
-        when(mActiveNotifList.getValue()).thenReturn(Lists.newArrayList(entry));
-        setStateAsleep();
-        mLogger.onDozingChanged(false);  // Wake to lockscreen
-        assertEquals(1, mNotificationPanelLoggerFake.getCalls().size());
-        assertEquals(1, mNotificationPanelLoggerFake.get(0).list.notifications.length);
-        Notifications.Notification n = mNotificationPanelLoggerFake.get(0).list.notifications[0];
-        assertEquals(0, n.instanceId);
-    }
-
-    private class TestableNotificationLogger extends NotificationLogger {
-
-        TestableNotificationLogger(NotificationListener notificationListener,
-                Executor uiBgExecutor,
-                NotifPipelineFlags notifPipelineFlags,
-                NotifLiveDataStore notifLiveDataStore,
-                NotificationVisibilityProvider visibilityProvider,
-                NotificationEntryManager entryManager,
-                NotifPipeline notifPipeline,
-                StatusBarStateControllerImpl statusBarStateController,
-                IStatusBarService barService,
-                ExpansionStateLogger expansionStateLogger) {
-            super(
-                    notificationListener,
-                    uiBgExecutor,
-                    notifPipelineFlags,
-                    notifLiveDataStore,
-                    visibilityProvider,
-                    entryManager,
-                    notifPipeline,
-                    statusBarStateController,
-                    expansionStateLogger,
-                    mNotificationPanelLoggerFake
-            );
-            mBarService = barService;
-            mHandler.removeCallbacksAndMessages(null);
-            // Make this on the current thread so we can wait for it during tests.
-            mHandler = Handler.createAsync(Looper.myLooper());
-        }
-
-        OnChildLocationsChangedListener getChildLocationsChangedListenerForTest() {
-            return mNotificationLocationsChangedListener;
-        }
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
index b69bd8d..8a7b9d3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
@@ -103,7 +103,6 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        when(mNotifPipelineFlags.isNewPipelineEnabled()).thenReturn(true);
         when(mNotifLiveDataStore.getActiveNotifList()).thenReturn(mActiveNotifEntries);
 
         mEntry = new NotificationEntryBuilder()
@@ -278,10 +277,8 @@
             super(
                     notificationListener,
                     uiBgExecutor,
-                    notifPipelineFlags,
                     notifLiveDataStore,
                     visibilityProvider,
-                    entryManager,
                     notifPipeline,
                     statusBarStateController,
                     expansionStateLogger,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
index 251ac7d..bf7549a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
@@ -194,7 +194,8 @@
                 mLeakDetector,
                 mock(IStatusBarService.class),
                 NotifLiveDataStoreMocksKt.createNotifLiveDataStoreImplMock(),
-                mock(DumpManager.class)
+                mock(DumpManager.class),
+                mBgExecutor
         );
         mEntryManager.initialize(
                 mNotificationListener,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
index 4efd5c9..c199147 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
@@ -52,6 +52,7 @@
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shade.transition.ShadeTransitionController;
 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener;
@@ -75,7 +76,6 @@
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.phone.shade.transition.ShadeTransitionController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.ZenModeController;
@@ -150,7 +150,6 @@
         MockitoAnnotations.initMocks(this);
 
         when(mNotificationSwipeHelperBuilder.build()).thenReturn(mNotificationSwipeHelper);
-        when(mNotifPipelineFlags.isNewPipelineEnabled()).thenReturn(false);
 
         mController = new NotificationStackScrollLayoutController(
                 true,
@@ -166,7 +165,6 @@
                 mKeyguardMediaController,
                 mKeyguardBypassController,
                 mZenModeController,
-                mColorExtractor,
                 mNotificationLockscreenUserManager,
                 mMetricsLogger,
                 mDumpManager,
@@ -179,15 +177,12 @@
                 mLegacyGroupManager,
                 mLegacyGroupManager,
                 mSilentHeaderController,
-                mNotifPipelineFlags,
                 mNotifPipeline,
                 mNotifCollection,
                 mEntryManager,
                 mLockscreenShadeTransitionController,
                 mShadeTransitionController,
-                mIStatusBarService,
                 mUiEventLogger,
-                mLayoutInflater,
                 mRemoteInputManager,
                 mVisualStabilityManager,
                 mShadeController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
index 9bfb2c4..d79f336 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
@@ -37,6 +37,8 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.shade.NotificationPanelViewController;
+import com.android.systemui.shade.NotificationShadeWindowView;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.DisableFlagsLogger;
 import com.android.systemui.statusbar.StatusBarStateControllerImpl;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index 2e26a2b..b75c52a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -19,6 +19,8 @@
 import static android.app.NotificationManager.IMPORTANCE_HIGH;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
 import static junit.framework.TestCase.fail;
@@ -44,6 +46,7 @@
 import android.app.trust.TrustManager;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
+import android.content.Intent;
 import android.content.IntentFilter;
 import android.hardware.devicestate.DeviceStateManager;
 import android.hardware.display.AmbientDisplayConfiguration;
@@ -89,7 +92,6 @@
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.demomode.DemoModeController;
-import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.fragments.FragmentService;
@@ -103,6 +105,10 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.recents.ScreenPinningRequest;
 import com.android.systemui.settings.brightness.BrightnessSliderController;
+import com.android.systemui.shade.NotificationPanelView;
+import com.android.systemui.shade.NotificationPanelViewController;
+import com.android.systemui.shade.NotificationShadeWindowView;
+import com.android.systemui.shade.NotificationShadeWindowViewController;
 import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.KeyguardIndicationController;
@@ -118,7 +124,6 @@
 import com.android.systemui.statusbar.PulseExpansionHandler;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.StatusBarStateControllerImpl;
-import com.android.systemui.statusbar.connectivity.NetworkController;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
 import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -129,7 +134,6 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
 import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.init.NotificationsController;
 import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
@@ -159,7 +163,6 @@
 import com.android.systemui.util.concurrency.MessageRouterImpl;
 import com.android.systemui.util.time.FakeSystemClock;
 import com.android.systemui.volume.VolumeComponent;
-import com.android.systemui.wmshell.BubblesManager;
 import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.startingsurface.StartingSurface;
 
@@ -223,7 +226,6 @@
     @Mock private NotificationShadeWindowView mNotificationShadeWindowView;
     @Mock private BroadcastDispatcher mBroadcastDispatcher;
     @Mock private AssistManager mAssistManager;
-    @Mock private NotifShadeEventSource mNotifShadeEventSource;
     @Mock private NotificationEntryManager mNotificationEntryManager;
     @Mock private NotificationGutsManager mNotificationGutsManager;
     @Mock private NotificationMediaManager mNotificationMediaManager;
@@ -240,15 +242,12 @@
     @Mock private StatusBarWindowStateController mStatusBarWindowStateController;
     @Mock private NotificationViewHierarchyManager mNotificationViewHierarchyManager;
     @Mock private UserSwitcherController mUserSwitcherController;
-    @Mock private NetworkController mNetworkController;
-    @Mock private BubblesManager mBubblesManager;
     @Mock private Bubbles mBubbles;
     @Mock private NotificationShadeWindowController mNotificationShadeWindowController;
     @Mock private NotificationIconAreaController mNotificationIconAreaController;
     @Mock private NotificationShadeWindowViewController mNotificationShadeWindowViewController;
     @Mock private DozeParameters mDozeParameters;
     @Mock private Lazy<LockscreenWallpaper> mLockscreenWallpaperLazy;
-    @Mock private LockscreenGestureLogger mLockscreenGestureLogger;
     @Mock private LockscreenWallpaper mLockscreenWallpaper;
     @Mock private DozeServiceHost mDozeServiceHost;
     @Mock private ViewMediatorCallback mKeyguardVieMediatorCallback;
@@ -286,7 +285,6 @@
     @Mock private NotifLiveDataStore mNotifLiveDataStore;
     @Mock private InteractionJankMonitor mJankMonitor;
     @Mock private DeviceStateManager mDeviceStateManager;
-    @Mock private DreamOverlayStateController mDreamOverlayStateController;
     @Mock private WiredChargingRippleController mWiredChargingRippleController;
     private ShadeController mShadeController;
     private final FakeSystemClock mFakeSystemClock = new FakeSystemClock();
@@ -322,10 +320,8 @@
         NotificationLogger notificationLogger = new NotificationLogger(
                 mNotificationListener,
                 mUiBgExecutor,
-                mNotifPipelineFlags,
                 mNotifLiveDataStore,
                 mVisibilityProvider,
-                mock(NotificationEntryManager.class),
                 mock(NotifPipeline.class),
                 mStatusBarStateController,
                 mExpansionStateLogger,
@@ -403,7 +399,6 @@
                 new FalsingManagerFake(),
                 new FalsingCollectorFake(),
                 mBroadcastDispatcher,
-                mNotifShadeEventSource,
                 mNotificationEntryManager,
                 mNotificationGutsManager,
                 notificationLogger,
@@ -418,13 +413,11 @@
                 mLockscreenUserManager,
                 mRemoteInputManager,
                 mUserSwitcherController,
-                mNetworkController,
                 mBatteryController,
                 mColorExtractor,
                 new ScreenLifecycle(mDumpManager),
                 wakefulnessLifecycle,
                 mStatusBarStateController,
-                Optional.of(mBubblesManager),
                 Optional.of(mBubbles),
                 mVisualStabilityManager,
                 mDeviceProvisionedController,
@@ -436,7 +429,6 @@
                 mDozeParameters,
                 mScrimController,
                 mLockscreenWallpaperLazy,
-                mLockscreenGestureLogger,
                 mBiometricUnlockControllerLazy,
                 mDozeServiceHost,
                 mPowerManager, mScreenPinningRequest,
@@ -468,7 +460,6 @@
                 mLockscreenTransitionController,
                 mFeatureFlags,
                 mKeyguardUnlockAnimationController,
-                new Handler(TestableLooper.get(this).getLooper()),
                 mMainExecutor,
                 new MessageRouterImpl(mMainExecutor),
                 mWallpaperManager,
@@ -477,7 +468,6 @@
                 mNotifPipelineFlags,
                 mJankMonitor,
                 mDeviceStateManager,
-                mDreamOverlayStateController,
                 mWiredChargingRippleController, mDreamManager);
         when(mKeyguardViewMediator.registerCentralSurfaces(
                 any(CentralSurfacesImpl.class),
@@ -1001,6 +991,22 @@
         verify(mStatusBarStateController, never()).setLeaveOpenOnKeyguardHide(true);
     }
 
+    @Test
+    public void startActivityDismissingKeyguard_isShowingandIsOccluded() {
+        when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
+        when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(true);
+        mCentralSurfaces.startActivityDismissingKeyguard(
+                new Intent(),
+                /* onlyProvisioned = */false,
+                /* dismissShade = */false);
+        verify(mStatusBarKeyguardViewManager).addAfterKeyguardGoneRunnable(any(Runnable.class));
+        ArgumentCaptor<OnDismissAction> onDismissActionCaptor =
+                ArgumentCaptor.forClass(OnDismissAction.class);
+        verify(mStatusBarKeyguardViewManager)
+                .dismissWithAction(onDismissActionCaptor.capture(), any(Runnable.class), eq(true));
+        assertThat(onDismissActionCaptor.getValue().onDismiss()).isFalse();
+    }
+
     private void setDeviceState(int state) {
         ArgumentCaptor<DeviceStateManager.DeviceStateCallback> callbackCaptor =
                 ArgumentCaptor.forClass(DeviceStateManager.DeviceStateCallback.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
index 26ac70c..5c9871a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
@@ -41,6 +41,8 @@
 import com.android.systemui.doze.DozeLog;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.shade.NotificationPanelViewController;
+import com.android.systemui.shade.NotificationShadeWindowViewController;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.PulseExpansionHandler;
 import com.android.systemui.statusbar.StatusBarState;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
index ed22cd3..103b7b42 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
@@ -34,6 +34,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.HeadsUpStatusBarView;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt
index 4b557dc..3440fa5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt
@@ -42,7 +42,6 @@
 
         mKeyguardBottomArea = LayoutInflater.from(mContext).inflate(
                 R.layout.keyguard_bottom_area, null, false) as KeyguardBottomAreaView
-        mKeyguardBottomArea.setCentralSurfaces(mCentralSurfaces)
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
index 39021d8..60a3d95 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
@@ -230,6 +230,15 @@
     }
 
     @Test
+    public void show_notifiesKeyguardViewController() {
+        mBouncer.ensureView();
+
+        mBouncer.show(/* resetSecuritySelection= */ false);
+
+        verify(mKeyguardHostViewController).onBouncerVisibilityChanged(View.VISIBLE);
+    }
+
+    @Test
     public void testHide_notifiesFalsingManager() {
         mBouncer.hide(false);
         verify(mFalsingCollector).onBouncerHidden();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
index 4e1a708..11e502f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
@@ -49,6 +49,7 @@
 import com.android.systemui.battery.BatteryMeterViewController;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
 import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserInfoTracker;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt
deleted file mode 100644
index 7e245fc..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt
+++ /dev/null
@@ -1,281 +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 com.android.systemui.statusbar.phone
-
-import android.testing.AndroidTestingRunner
-import android.testing.TestableLooper.RunWithLooper
-import android.view.MotionEvent
-import androidx.test.filters.SmallTest
-import com.android.keyguard.LockIconViewController
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.classifier.FalsingCollectorFake
-import com.android.systemui.dock.DockManager
-import com.android.systemui.keyguard.KeyguardUnlockAnimationController
-import com.android.systemui.lowlightclock.LowLightClockController
-import com.android.systemui.statusbar.LockscreenShadeTransitionController
-import com.android.systemui.statusbar.NotificationShadeDepthController
-import com.android.systemui.statusbar.NotificationShadeWindowController
-import com.android.systemui.statusbar.SysuiStatusBarStateController
-import com.android.systemui.statusbar.notification.stack.AmbientState
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
-import com.android.systemui.statusbar.phone.NotificationShadeWindowView.InteractionEventHandler
-import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager
-import com.android.systemui.statusbar.window.StatusBarWindowStateController
-import com.android.systemui.tuner.TunerService
-import com.google.common.truth.Truth.assertThat
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.ArgumentCaptor
-import org.mockito.ArgumentMatchers
-import org.mockito.Mock
-import org.mockito.MockitoAnnotations
-import org.mockito.Mockito.anyFloat
-import org.mockito.Mockito.never
-import org.mockito.Mockito.verify
-import java.util.Optional
-import org.mockito.Mockito.`when` as whenever
-
-@RunWith(AndroidTestingRunner::class)
-@RunWithLooper(setAsMainLooper = true)
-@SmallTest
-class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
-    private lateinit var mController: NotificationShadeWindowViewController
-
-    @Mock
-    private lateinit var mView: NotificationShadeWindowView
-    @Mock
-    private lateinit var mTunerService: TunerService
-    @Mock
-    private lateinit var mStatusBarStateController: SysuiStatusBarStateController
-    @Mock
-    private lateinit var mCentralSurfaces: CentralSurfaces
-    @Mock
-    private lateinit var mDockManager: DockManager
-    @Mock
-    private lateinit var mNotificationPanelViewController: NotificationPanelViewController
-    @Mock
-    private lateinit var mNotificationShadeDepthController: NotificationShadeDepthController
-    @Mock
-    private lateinit var mNotificationShadeWindowController: NotificationShadeWindowController
-    @Mock
-    private lateinit var mKeyguardUnlockAnimationController: KeyguardUnlockAnimationController
-    @Mock
-    private lateinit var mAmbientState: AmbientState
-    @Mock
-    private lateinit var stackScrollLayoutController: NotificationStackScrollLayoutController
-    @Mock
-    private lateinit var mStatusBarKeyguardViewManager: StatusBarKeyguardViewManager
-    @Mock
-    private lateinit var mStatusBarWindowStateController: StatusBarWindowStateController
-    @Mock
-    private lateinit var mLockscreenShadeTransitionController: LockscreenShadeTransitionController
-    @Mock
-    private lateinit var mLockIconViewController: LockIconViewController
-    @Mock
-    private lateinit var mPhoneStatusBarViewController: PhoneStatusBarViewController
-    @Mock
-    private lateinit var mLowLightClockController: LowLightClockController
-
-    private lateinit var mInteractionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
-    private lateinit var mInteractionEventHandler: InteractionEventHandler
-
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-        whenever(mView.bottom).thenReturn(VIEW_BOTTOM)
-
-        mController = NotificationShadeWindowViewController(
-            mLockscreenShadeTransitionController,
-            FalsingCollectorFake(),
-            mTunerService,
-            mStatusBarStateController,
-            mDockManager,
-            mNotificationShadeDepthController,
-            mView,
-            mNotificationPanelViewController,
-            PanelExpansionStateManager(),
-            stackScrollLayoutController,
-            mStatusBarKeyguardViewManager,
-            mStatusBarWindowStateController,
-            mLockIconViewController,
-            Optional.of(mLowLightClockController),
-            mCentralSurfaces,
-            mNotificationShadeWindowController,
-            mKeyguardUnlockAnimationController,
-            mAmbientState
-        )
-        mController.setupExpandedStatusBar()
-
-        mInteractionEventHandlerCaptor =
-            ArgumentCaptor.forClass(InteractionEventHandler::class.java)
-        verify(mView).setInteractionEventHandler(mInteractionEventHandlerCaptor.capture())
-            mInteractionEventHandler = mInteractionEventHandlerCaptor.value
-    }
-
-    // Note: So far, these tests only cover interactions with the status bar view controller. More
-    // tests need to be added to test the rest of handleDispatchTouchEvent.
-
-    @Test
-    fun handleDispatchTouchEvent_nullStatusBarViewController_returnsFalse() {
-        mController.setStatusBarViewController(null)
-
-        val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(downEv)
-
-        assertThat(returnVal).isFalse()
-    }
-
-    @Test
-    fun handleDispatchTouchEvent_downTouchBelowView_sendsTouchToSb() {
-        mController.setStatusBarViewController(mPhoneStatusBarViewController)
-        val ev = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, VIEW_BOTTOM + 4f, 0)
-        whenever(mPhoneStatusBarViewController.sendTouchToView(ev)).thenReturn(true)
-
-        val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(ev)
-
-        verify(mPhoneStatusBarViewController).sendTouchToView(ev)
-        assertThat(returnVal).isTrue()
-    }
-
-    @Test
-    fun handleDispatchTouchEvent_downTouchBelowViewThenAnotherTouch_sendsTouchToSb() {
-        mController.setStatusBarViewController(mPhoneStatusBarViewController)
-        val downEvBelow = MotionEvent.obtain(
-            0L, 0L, MotionEvent.ACTION_DOWN, 0f, VIEW_BOTTOM + 4f, 0
-        )
-        mInteractionEventHandler.handleDispatchTouchEvent(downEvBelow)
-
-        val nextEvent = MotionEvent.obtain(
-            0L, 0L, MotionEvent.ACTION_MOVE, 0f, VIEW_BOTTOM + 5f, 0
-        )
-        whenever(mPhoneStatusBarViewController.sendTouchToView(nextEvent)).thenReturn(true)
-
-        val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(nextEvent)
-
-        verify(mPhoneStatusBarViewController).sendTouchToView(nextEvent)
-        assertThat(returnVal).isTrue()
-    }
-
-    @Test
-    fun handleDispatchTouchEvent_downAndPanelCollapsedAndInSbBoundAndSbWindowShow_sendsTouchToSb() {
-        mController.setStatusBarViewController(mPhoneStatusBarViewController)
-        whenever(mStatusBarWindowStateController.windowIsShowing()).thenReturn(true)
-        whenever(mNotificationPanelViewController.isFullyCollapsed).thenReturn(true)
-        whenever(mPhoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
-            .thenReturn(true)
-        whenever(mPhoneStatusBarViewController.sendTouchToView(downEv)).thenReturn(true)
-
-        val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(downEv)
-
-        verify(mPhoneStatusBarViewController).sendTouchToView(downEv)
-        assertThat(returnVal).isTrue()
-    }
-
-    @Test
-    fun handleDispatchTouchEvent_panelNotCollapsed_returnsNull() {
-        mController.setStatusBarViewController(mPhoneStatusBarViewController)
-        whenever(mStatusBarWindowStateController.windowIsShowing()).thenReturn(true)
-        whenever(mPhoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
-            .thenReturn(true)
-        // Item we're testing
-        whenever(mNotificationPanelViewController.isFullyCollapsed).thenReturn(false)
-
-        val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(downEv)
-
-        verify(mPhoneStatusBarViewController, never()).sendTouchToView(downEv)
-        assertThat(returnVal).isNull()
-    }
-
-    @Test
-    fun handleDispatchTouchEvent_touchNotInSbBounds_returnsNull() {
-        mController.setStatusBarViewController(mPhoneStatusBarViewController)
-        whenever(mStatusBarWindowStateController.windowIsShowing()).thenReturn(true)
-        whenever(mNotificationPanelViewController.isFullyCollapsed).thenReturn(true)
-        // Item we're testing
-        whenever(mPhoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
-            .thenReturn(false)
-
-        val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(downEv)
-
-        verify(mPhoneStatusBarViewController, never()).sendTouchToView(downEv)
-        assertThat(returnVal).isNull()
-    }
-
-    @Test
-    fun handleDispatchTouchEvent_sbWindowNotShowing_noSendTouchToSbAndReturnsTrue() {
-        mController.setStatusBarViewController(mPhoneStatusBarViewController)
-        whenever(mNotificationPanelViewController.isFullyCollapsed).thenReturn(true)
-        whenever(mPhoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
-            .thenReturn(true)
-        // Item we're testing
-        whenever(mStatusBarWindowStateController.windowIsShowing()).thenReturn(false)
-
-        val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(downEv)
-
-        verify(mPhoneStatusBarViewController, never()).sendTouchToView(downEv)
-        assertThat(returnVal).isTrue()
-    }
-
-    @Test
-    fun handleDispatchTouchEvent_downEventSentToSbThenAnotherEvent_sendsTouchToSb() {
-        mController.setStatusBarViewController(mPhoneStatusBarViewController)
-        whenever(mStatusBarWindowStateController.windowIsShowing()).thenReturn(true)
-        whenever(mNotificationPanelViewController.isFullyCollapsed).thenReturn(true)
-        whenever(mPhoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
-            .thenReturn(true)
-
-        // Down event first
-        mInteractionEventHandler.handleDispatchTouchEvent(downEv)
-
-        // Then another event
-        val nextEvent = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0)
-        whenever(mPhoneStatusBarViewController.sendTouchToView(nextEvent)).thenReturn(true)
-
-        val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(nextEvent)
-
-        verify(mPhoneStatusBarViewController).sendTouchToView(nextEvent)
-        assertThat(returnVal).isTrue()
-    }
-
-    @Test
-    fun testLowLightClockAttachedWhenExpandedStatusBarSetup() {
-        verify(mLowLightClockController).attachLowLightClockView(ArgumentMatchers.any())
-    }
-
-    @Test
-    fun testLowLightClockShownWhenDozing() {
-        mController.setDozing(true)
-        verify(mLowLightClockController).showLowLightClock(true)
-    }
-
-    @Test
-    fun testLowLightClockDozeTimeTickCalled() {
-        mController.dozeTimeTick()
-        verify(mLowLightClockController).dozeTimeTick()
-    }
-
-    @Test
-    fun testLowLightClockHiddenWhenNotDozing() {
-        mController.setDozing(true)
-        verify(mLowLightClockController).showLowLightClock(true)
-        mController.setDozing(false)
-        verify(mLowLightClockController).showLowLightClock(false)
-    }
-}
-
-private val downEv = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
-private const val VIEW_BOTTOM = 100
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 837b045..7cd275d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -1553,6 +1553,15 @@
                 mScrimInFront.shouldBlendWithMainColor());
     }
 
+    @Test
+    public void applyState_unlocked_bouncerShowing() {
+        mScrimController.transitionTo(ScrimState.UNLOCKED);
+        mScrimController.setBouncerHiddenFraction(0.99f);
+        mScrimController.setRawPanelExpansionFraction(0f);
+        finishAnimationsImmediately();
+        assertScrimAlpha(mScrimBehind, 0);
+    }
+
     private void assertAlphaAfterExpansion(ScrimView scrim, float expectedAlpha, float expansion) {
         mScrimController.setRawPanelExpansionFraction(expansion);
         finishAnimationsImmediately();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconListTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconListTest.java
new file mode 100644
index 0000000..f0a4f3f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconListTest.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import static com.android.systemui.statusbar.phone.StatusBarIconController.TAG_PRIMARY;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.phone.StatusBarIconList.Slot;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class StatusBarIconListTest extends SysuiTestCase {
+
+    private final static String[] STATUS_BAR_SLOTS = {"aaa", "bbb", "ccc"};
+
+    @Test
+    public void testGetExistingSlot() {
+        StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
+
+        List<Slot> slots = statusBarIconList.getSlots();
+        assertEquals(3, slots.size());
+        assertEquals("aaa", slots.get(0).getName());
+        assertEquals("bbb", slots.get(1).getName());
+        assertEquals("ccc", slots.get(2).getName());
+    }
+
+    @Test
+    public void testGetNonexistingSlot() {
+        StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
+
+        statusBarIconList.getSlot("zzz");
+
+        List<Slot> slots = statusBarIconList.getSlots();
+        assertEquals(4, slots.size());
+        // new content added in front, so zzz should be first and aaa should slide back to second
+        assertEquals("zzz", slots.get(0).getName());
+        assertEquals("aaa", slots.get(1).getName());
+    }
+
+    @Test
+    public void testAddSlotSlidesIcons() {
+        StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
+        StatusBarIconHolder sbHolder = mock(StatusBarIconHolder.class);
+        statusBarIconList.setIcon("aaa", sbHolder);
+
+        statusBarIconList.getSlot("zzz");
+
+        List<Slot> slots = statusBarIconList.getSlots();
+        // new content added in front, so the holder we set on "aaa" should show up at index 1
+        assertNull(slots.get(0).getHolderForTag(TAG_PRIMARY));
+        assertEquals(sbHolder, slots.get(1).getHolderForTag(TAG_PRIMARY));
+    }
+
+    @Test
+    public void testGetAndSetIcon() {
+        StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
+        StatusBarIconHolder sbHolderA = mock(StatusBarIconHolder.class);
+        StatusBarIconHolder sbHolderB = mock(StatusBarIconHolder.class);
+
+        statusBarIconList.setIcon("aaa", sbHolderA);
+        statusBarIconList.setIcon("bbb", sbHolderB);
+
+        assertEquals(sbHolderA, statusBarIconList.getIconHolder("aaa", TAG_PRIMARY));
+        assertEquals(sbHolderB, statusBarIconList.getIconHolder("bbb", TAG_PRIMARY));
+        assertNull(statusBarIconList.getIconHolder("ccc", TAG_PRIMARY)); // icon not set
+    }
+
+    @Test
+    public void testRemoveIcon() {
+        StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
+        StatusBarIconHolder sbHolderA = mock(StatusBarIconHolder.class);
+        StatusBarIconHolder sbHolderB = mock(StatusBarIconHolder.class);
+
+        statusBarIconList.setIcon("aaa", sbHolderA);
+        statusBarIconList.setIcon("bbb", sbHolderB);
+
+        statusBarIconList.removeIcon("aaa", TAG_PRIMARY);
+
+        assertNull(statusBarIconList.getIconHolder("aaa", TAG_PRIMARY)); // icon not set
+    }
+
+    @Test
+    public void testGetViewIndex_NoMultiples() {
+        StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
+        StatusBarIconHolder sbHolder = mock(StatusBarIconHolder.class);
+
+        statusBarIconList.setIcon("ccc", sbHolder);
+
+        // Since only "ccc" has a holder set, it should be first
+        assertEquals(0, statusBarIconList.getViewIndex("ccc", TAG_PRIMARY));
+
+        // Now, also set a holder for "aaa"
+        statusBarIconList.setIcon("aaa", sbHolder);
+
+        // Then "aaa" gets the first view index and "ccc" gets the second
+        assertEquals(0, statusBarIconList.getViewIndex("aaa", TAG_PRIMARY));
+        assertEquals(1, statusBarIconList.getViewIndex("ccc", TAG_PRIMARY));
+    }
+
+    @Test
+    public void testGetViewIndex_MultipleIconsPerSlot() {
+        StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
+        StatusBarIconHolder sbHolder = mock(StatusBarIconHolder.class);
+
+        statusBarIconList.setIcon("ccc", sbHolder);
+
+        // All of these can be added to the same slot
+        // no tag bc it defaults to 0
+        StatusBarIconHolder sbHolder2 = mock(StatusBarIconHolder.class);
+        StatusBarIconHolder sbHolder3 = mock(StatusBarIconHolder.class);
+        int sb3Tag = 1;
+        when(sbHolder3.getTag()).thenReturn(sb3Tag);
+        StatusBarIconHolder sbHolder4 = mock(StatusBarIconHolder.class);
+        int sb4Tag = 2;
+        when(sbHolder4.getTag()).thenReturn(sb4Tag);
+
+        // Put a holder for "bbb", verify that it is first
+        statusBarIconList.setIcon("bbb", sbHolder2);
+        assertEquals(0, statusBarIconList.getViewIndex("bbb", TAG_PRIMARY));
+
+        // Put another holder for "bbb" at slot 1, verify its index 0 and the rest come after
+        statusBarIconList.setIcon("bbb", sbHolder3);
+        assertEquals(0, statusBarIconList.getViewIndex("bbb", sb3Tag));
+        assertEquals(1, statusBarIconList.getViewIndex("bbb", TAG_PRIMARY));
+        // "ccc" should appear at the end
+        assertEquals(2, statusBarIconList.getViewIndex("ccc", TAG_PRIMARY));
+
+        // Put another one in "bbb" just for good measure
+        statusBarIconList.setIcon("bbb", sbHolder4);
+        assertEquals(0, statusBarIconList.getViewIndex("bbb", sb4Tag));
+        assertEquals(1, statusBarIconList.getViewIndex("bbb", sb3Tag));
+        assertEquals(2, statusBarIconList.getViewIndex("bbb", TAG_PRIMARY));
+        assertEquals(3, statusBarIconList.getViewIndex("ccc", TAG_PRIMARY));
+    }
+
+    /**
+     * StatusBarIconList.Slot tests
+     */
+
+    @Test
+    public void testSlot_ViewOrder() {
+        Slot testSlot = new Slot("test_name", null);
+
+        // no tag bc it defaults to 0
+        StatusBarIconHolder sbHolder1 = mock(StatusBarIconHolder.class);
+        StatusBarIconHolder sbHolder2 = mock(StatusBarIconHolder.class);
+        int sb2Tag = 1;
+        when(sbHolder2.getTag()).thenReturn(sb2Tag);
+        StatusBarIconHolder sbHolder3 = mock(StatusBarIconHolder.class);
+        int sb3Tag = 2;
+        when(sbHolder3.getTag()).thenReturn(sb3Tag);
+
+        // Add 3 icons in the same slot, and verify that the list we get is equal to what we gave
+        testSlot.addHolder(sbHolder1);
+        testSlot.addHolder(sbHolder2);
+        testSlot.addHolder(sbHolder3);
+
+        // View order is reverse of the order added
+        ArrayList<StatusBarIconHolder> expected = new ArrayList<>();
+        expected.add(sbHolder3);
+        expected.add(sbHolder2);
+        expected.add(sbHolder1);
+
+        assertTrue(listsEqual(expected, testSlot.getHolderListInViewOrder()));
+    }
+
+    private boolean listsEqual(List<StatusBarIconHolder> list1, List<StatusBarIconHolder> list2) {
+        if (list1.size() != list2.size())  return false;
+
+        for (int i = 0; i < list1.size(); i++) {
+            if (!list1.get(i).equals(list2.get(i))) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 0c1d042..79fce82 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -47,6 +47,7 @@
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
+import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
@@ -275,21 +276,18 @@
 
         // Should be false to start, so no invocations
         mStatusBarKeyguardViewManager.setOccluded(false /* occluded */, false /* animated */);
-        verify(mKeyguardUpdateMonitor, never()).onKeyguardOccludedChanged(anyBoolean());
         verify(mKeyguardStateController, never()).notifyKeyguardState(anyBoolean(), anyBoolean());
 
         clearInvocations(mKeyguardUpdateMonitor);
         clearInvocations(mKeyguardStateController);
 
         mStatusBarKeyguardViewManager.setOccluded(true /* occluded */, false /* animated */);
-        verify(mKeyguardUpdateMonitor).onKeyguardOccludedChanged(true);
         verify(mKeyguardStateController).notifyKeyguardState(true, true);
 
         clearInvocations(mKeyguardUpdateMonitor);
         clearInvocations(mKeyguardStateController);
 
         mStatusBarKeyguardViewManager.setOccluded(true /* occluded */, false /* animated */);
-        verify(mKeyguardUpdateMonitor, never()).onKeyguardOccludedChanged(anyBoolean());
         verify(mKeyguardStateController, never()).notifyKeyguardState(anyBoolean(), anyBoolean());
     }
 
@@ -299,7 +297,6 @@
         mStatusBarKeyguardViewManager.show(null);
 
         mStatusBarKeyguardViewManager.setOccluded(true /* occluded */, false /* animated */);
-        verify(mKeyguardUpdateMonitor).onKeyguardOccludedChanged(true);
         verify(mKeyguardStateController).notifyKeyguardState(true, true);
     }
 
@@ -309,7 +306,6 @@
         mStatusBarKeyguardViewManager.show(null);
 
         mStatusBarKeyguardViewManager.setOccluded(true /* occluded */, false /* animated */);
-        verify(mKeyguardUpdateMonitor).onKeyguardOccludedChanged(true);
         verify(mKeyguardStateController).notifyKeyguardState(true, true);
     }
 
@@ -389,6 +385,16 @@
     }
 
     @Test
+    public void testBouncerIsOrWillBeShowing_whenBouncerIsInTransit() {
+        when(mBouncer.isShowing()).thenReturn(false);
+        when(mBouncer.inTransit()).thenReturn(true);
+
+        assertTrue(
+                "Is or will be showing should be true when bouncer is in transit",
+                mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing());
+    }
+
+    @Test
     public void testShowAltAuth_unlockingWithBiometricNotAllowed() {
         // GIVEN alt auth exists, unlocking with biometric isn't allowed
         mStatusBarKeyguardViewManager.setAlternateAuthInterceptor(mAlternateAuthInterceptor);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index ecea14c..7046150 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -59,18 +59,17 @@
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.shade.NotificationPanelViewController;
+import com.android.systemui.shade.NotificationShadeWindowViewController;
 import com.android.systemui.statusbar.NotificationClickNotifier;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -127,8 +126,6 @@
     @Mock
     private ShadeControllerImpl mShadeController;
     @Mock
-    private NotifPipelineFlags mNotifPipelineFlags;
-    @Mock
     private NotifPipeline mNotifPipeline;
     @Mock
     private NotificationVisibilityProvider mVisibilityProvider;
@@ -148,15 +145,13 @@
     private ActivityLaunchAnimator mActivityLaunchAnimator;
     @Mock
     private InteractionJankMonitor mJankMonitor;
-    private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
-    private NotificationTestHelper mNotificationTestHelper;
+    private final FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
     private ExpandableNotificationRow mNotificationRow;
     private ExpandableNotificationRow mBubbleNotificationRow;
 
     private final Answer<Void> mCallOnDismiss = answerVoid(
             (OnDismissAction dismissAction, Runnable cancel,
                     Boolean afterKeyguardGone) -> dismissAction.onDismiss());
-    private ArrayList<NotificationEntry> mActiveNotifications;
 
     @Before
     public void setUp() throws Exception {
@@ -165,29 +160,28 @@
         when(mContentIntent.getCreatorUserHandle()).thenReturn(UserHandle.of(1));
         when(mContentIntent.getIntent()).thenReturn(mContentIntentInner);
 
-        mNotificationTestHelper = new NotificationTestHelper(
+        NotificationTestHelper notificationTestHelper = new NotificationTestHelper(
                 mContext,
                 mDependency,
                 TestableLooper.get(this));
 
         // Create standard notification with contentIntent
-        mNotificationRow = mNotificationTestHelper.createRow();
+        mNotificationRow = notificationTestHelper.createRow();
         StatusBarNotification sbn = mNotificationRow.getEntry().getSbn();
         sbn.getNotification().contentIntent = mContentIntent;
         sbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
 
         // Create bubble notification row with contentIntent
-        mBubbleNotificationRow = mNotificationTestHelper.createBubble();
+        mBubbleNotificationRow = notificationTestHelper.createBubble();
         StatusBarNotification bubbleSbn = mBubbleNotificationRow.getEntry().getSbn();
         bubbleSbn.getNotification().contentIntent = mContentIntent;
         bubbleSbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
 
-        mActiveNotifications = new ArrayList<>();
-        mActiveNotifications.add(mNotificationRow.getEntry());
-        mActiveNotifications.add(mBubbleNotificationRow.getEntry());
-        when(mEntryManager.getVisibleNotifications()).thenReturn(mActiveNotifications);
+        ArrayList<NotificationEntry> activeNotifications = new ArrayList<>();
+        activeNotifications.add(mNotificationRow.getEntry());
+        activeNotifications.add(mBubbleNotificationRow.getEntry());
+        when(mEntryManager.getVisibleNotifications()).thenReturn(activeNotifications);
         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
-        when(mNotifPipelineFlags.isNewPipelineEnabled()).thenReturn(false);
         when(mOnUserInteractionCallback.registerFutureDismissal(eq(mNotificationRow.getEntry()),
                 anyInt())).thenReturn(mFutureDismissalRunnable);
         when(mVisibilityProvider.obtain(anyString(), anyBoolean()))
@@ -207,23 +201,19 @@
         mNotificationActivityStarter =
                 new StatusBarNotificationActivityStarter(
                         getContext(),
-                        mock(CommandQueue.class),
                         mHandler,
                         mUiBgExecutor,
-                        mEntryManager,
                         mNotifPipeline,
                         mVisibilityProvider,
                         headsUpManager,
                         mActivityStarter,
                         mClickNotifier,
-                        mock(StatusBarStateController.class),
                         mStatusBarKeyguardViewManager,
                         mock(KeyguardManager.class),
                         mock(IDreamManager.class),
                         Optional.of(mBubblesManager),
                         () -> mAssistManager,
                         mRemoteInputManager,
-                        mock(NotificationGroupManagerLegacy.class),
                         mock(NotificationLockscreenUserManager.class),
                         mShadeController,
                         mKeyguardStateController,
@@ -231,7 +221,6 @@
                         mock(LockPatternUtils.class),
                         mock(StatusBarRemoteInputCallback.class),
                         mActivityIntentHelper,
-                        mNotifPipelineFlags,
                         mock(MetricsLogger.class),
                         mock(StatusBarNotificationActivityStarterLogger.class),
                         mOnUserInteractionCallback,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
index 12c0c92..186bf8a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
@@ -33,12 +33,13 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.logging.testing.FakeMetricsLogger;
-import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.ForegroundServiceNotificationListener;
 import com.android.systemui.InitController;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shade.NotificationPanelViewController;
+import com.android.systemui.shade.NotificationShadeWindowView;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
@@ -49,7 +50,6 @@
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
 import com.android.systemui.statusbar.notification.NotifPipelineFlags;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
 import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
@@ -60,7 +60,6 @@
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
-import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import org.junit.Before;
@@ -123,15 +122,12 @@
                 mock(NotificationLockscreenUserManager.class),
                 mock(SysuiStatusBarStateController.class),
                 mock(NotifShadeEventSource.class),
-                mock(NotificationEntryManager.class),
                 mock(NotificationMediaManager.class),
                 mock(NotificationGutsManager.class),
-                mock(KeyguardUpdateMonitor.class),
                 lockscreenGestureLogger,
                 mInitController,
                 mNotificationInterruptStateProvider,
                 mock(NotificationRemoteInputManager.class),
-                mock(ConfigurationController.class),
                 mock(NotifPipelineFlags.class),
                 mock(NotificationRemoteInputManager.Callback.class),
                 mock(NotificationListContainer.class));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
index 0112797..746c92e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
@@ -27,6 +27,7 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.KeyguardViewMediator
 import com.android.systemui.keyguard.WakefulnessLifecycle
+import com.android.systemui.shade.NotificationPanelViewController
 import com.android.systemui.statusbar.LightRevealScrim
 import com.android.systemui.statusbar.StatusBarStateControllerImpl
 import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -39,12 +40,12 @@
 import org.mockito.ArgumentCaptor
 import org.mockito.Mock
 import org.mockito.Mockito
-import org.mockito.Mockito.`when`
 import org.mockito.Mockito.anyLong
 import org.mockito.Mockito.never
 import org.mockito.Mockito.spy
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
 
 @SmallTest
@@ -184,4 +185,4 @@
         controller.startAnimation()
         assertFalse(controller.isAnimationPlaying())
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
index 3d03c47..a3f329b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
@@ -44,14 +44,15 @@
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.log.LogBuffer;
 import com.android.systemui.log.LogcatEchoTracker;
+import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.DisableFlagsLogger;
 import com.android.systemui.statusbar.OperatorNameViewController;
 import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
 import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
 import com.android.systemui.statusbar.phone.NotificationIconAreaController;
-import com.android.systemui.statusbar.phone.NotificationPanelViewController;
 import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarLocationPublisher;
@@ -112,6 +113,7 @@
     @Before
     public void setup() {
         injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
+        mDependency.injectMockDependency(DarkIconDispatcher.class);
     }
 
     @Test
@@ -120,7 +122,7 @@
 
         fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
 
-        assertEquals(View.VISIBLE, getSystemIconAreaView().getVisibility());
+        assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
         assertEquals(View.VISIBLE, getClockView().getVisibility());
     }
 
@@ -130,11 +132,11 @@
 
         fragment.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_SYSTEM_INFO, 0, false);
 
-        assertEquals(View.INVISIBLE, getSystemIconAreaView().getVisibility());
+        assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility());
 
         fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
 
-        assertEquals(View.VISIBLE, getSystemIconAreaView().getVisibility());
+        assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
     }
 
     @Test
@@ -229,7 +231,7 @@
 
         fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
 
-        assertEquals(View.VISIBLE, getSystemIconAreaView().getVisibility());
+        assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
         assertEquals(View.VISIBLE, getClockView().getVisibility());
     }
 
@@ -240,7 +242,7 @@
 
         fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
 
-        assertEquals(View.VISIBLE, getSystemIconAreaView().getVisibility());
+        assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
         assertEquals(View.VISIBLE, getClockView().getVisibility());
     }
 
@@ -377,7 +379,7 @@
         return mFragment.getView().findViewById(R.id.clock);
     }
 
-    private View getSystemIconAreaView() {
-        return mFragment.getView().findViewById(R.id.system_icon_area);
+    private View getEndSideContentView() {
+        return mFragment.getView().findViewById(R.id.status_bar_end_side_content);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
index e0bf9e7..09d7c03 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
@@ -44,6 +44,7 @@
 import com.android.systemui.GuestSessionNotification
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.DialogCuj
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.broadcast.BroadcastSender
@@ -53,7 +54,7 @@
 import com.android.systemui.qs.QSUserSwitcherEvent
 import com.android.systemui.qs.user.UserSwitchDialogController
 import com.android.systemui.settings.UserTracker
-import com.android.systemui.statusbar.phone.NotificationShadeWindowView
+import com.android.systemui.shade.NotificationShadeWindowView
 import com.android.systemui.telephony.TelephonyListenerManager
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
@@ -72,12 +73,12 @@
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
-import org.mockito.Mockito.`when`
 import org.mockito.Mockito.doNothing
 import org.mockito.Mockito.doReturn
 import org.mockito.Mockito.eq
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
 
 @RunWith(AndroidTestingRunner::class)
@@ -362,7 +363,10 @@
         userSwitcherController.onUserListItemClicked(currentGuestUserRecord, dialogShower)
         assertNotNull(userSwitcherController.mExitGuestDialog)
         testableLooper.processAllMessages()
-        verify(dialogShower).showDialog(userSwitcherController.mExitGuestDialog)
+        verify(dialogShower)
+            .showDialog(
+                userSwitcherController.mExitGuestDialog,
+                DialogCuj(InteractionJankMonitor.CUJ_USER_DIALOG_OPEN, "exit_guest_mode"))
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt
index eaad69c..66367ec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt
@@ -23,6 +23,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.statusbar.policy.UserSwitcherController
@@ -46,6 +47,8 @@
     @Mock
     private lateinit var layoutInflater: LayoutInflater
     @Mock
+    private lateinit var falsingCollector: FalsingCollector
+    @Mock
     private lateinit var falsingManager: FalsingManager
     @Mock
     private lateinit var userManager: UserManager
@@ -59,6 +62,7 @@
             userSwitcherController,
             broadcastDispatcher,
             layoutInflater,
+            falsingCollector,
             falsingManager,
             userManager,
             userTracker
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/service/ObservableServiceConnectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/service/ObservableServiceConnectionTest.java
index 22d7273..046ad12 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/service/ObservableServiceConnectionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/service/ObservableServiceConnectionTest.java
@@ -145,4 +145,28 @@
         connection.unbind();
         verify(mContext, never()).unbindService(eq(connection));
     }
+
+    @Test
+    public void testUnbind() {
+        ObservableServiceConnection<Foo> connection = new ObservableServiceConnection<>(mContext,
+                mIntent, mExecutor, mTransformer);
+        connection.addCallback(mCallback);
+        connection.onServiceDisconnected(mComponentName);
+
+        // Disconnects before binds should be ignored.
+        verify(mCallback, never()).onDisconnected(eq(connection), anyInt());
+
+        when(mContext.bindService(eq(mIntent), anyInt(), eq(mExecutor), eq(connection)))
+                .thenReturn(true);
+        connection.bind();
+
+        mExecutor.runAllReady();
+
+        connection.unbind();
+
+        mExecutor.runAllReady();
+
+        verify(mCallback).onDisconnected(eq(connection),
+                eq(ObservableServiceConnection.DISCONNECT_REASON_UNBIND));
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.java
index 53d4a96..db0139c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.util.service;
 
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
 import android.testing.AndroidTestingRunner;
@@ -120,6 +121,24 @@
     }
 
     /**
+     * Ensures manual unbind does not reconnect.
+     */
+    @Test
+    public void testStopDoesNotReconnect() {
+        mConnectionManager.start();
+        ArgumentCaptor<ObservableServiceConnection.Callback<Proxy>> connectionCallbackCaptor =
+                ArgumentCaptor.forClass(ObservableServiceConnection.Callback.class);
+
+        verify(mConnection).addCallback(connectionCallbackCaptor.capture());
+        verify(mConnection).bind();
+        Mockito.clearInvocations(mConnection);
+        mConnectionManager.stop();
+        mFakeExecutor.advanceClockToNext();
+        mFakeExecutor.runAllReady();
+        verify(mConnection, never()).bind();
+    }
+
+    /**
      * Ensures rebind on package change.
      */
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index 2e58fc4..6a0124a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -71,6 +71,7 @@
 import android.util.Pair;
 import android.util.SparseArray;
 import android.view.View;
+import android.view.ViewTreeObserver;
 import android.view.WindowManager;
 
 import androidx.test.filters.SmallTest;
@@ -84,6 +85,7 @@
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shade.NotificationShadeWindowView;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.RankingBuilder;
@@ -104,7 +106,6 @@
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.NotificationShadeWindowControllerImpl;
-import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -132,6 +133,7 @@
 import com.android.wm.shell.common.TaskStackListenerImpl;
 import com.android.wm.shell.draganddrop.DragAndDropController;
 import com.android.wm.shell.onehanded.OneHandedController;
+import com.android.wm.shell.sysui.ShellController;
 
 import org.junit.Before;
 import org.junit.Ignore;
@@ -213,6 +215,8 @@
     private BubbleEntry mBubbleEntry2User11;
 
     @Mock
+    private ShellController mShellController;
+    @Mock
     private Bubbles.BubbleExpandListener mBubbleExpandListener;
     @Mock
     private PendingIntent mDeleteIntent;
@@ -265,6 +269,8 @@
         ShellExecutor syncExecutor = new SyncExecutor();
 
         when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
+        when(mNotificationShadeWindowView.getViewTreeObserver())
+                .thenReturn(mock(ViewTreeObserver.class));
 
         mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl(mContext,
                 mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController,
@@ -325,6 +331,7 @@
         when(mShellTaskOrganizer.getExecutor()).thenReturn(syncExecutor);
         mBubbleController = new TestableBubbleController(
                 mContext,
+                mShellController,
                 mBubbleData,
                 mFloatingContentCoordinator,
                 mDataRepository,
@@ -353,7 +360,6 @@
                 mNotificationShadeWindowController,
                 mock(KeyguardStateController.class),
                 mShadeController,
-                mConfigurationController,
                 mStatusBarService,
                 mock(INotificationManager.class),
                 mVisibilityProvider,
@@ -375,6 +381,11 @@
     }
 
     @Test
+    public void instantiateController_registerConfigChangeListener() {
+        verify(mShellController, times(1)).addConfigurationChangeListener(any());
+    }
+
+    @Test
     public void testAddBubble() {
         mBubbleController.updateBubble(mBubbleEntry);
         assertTrue(mBubbleController.hasBubbles());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java
index 17e5778..f901c32 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java
@@ -38,6 +38,7 @@
 import com.android.wm.shell.common.TaskStackListenerImpl;
 import com.android.wm.shell.draganddrop.DragAndDropController;
 import com.android.wm.shell.onehanded.OneHandedController;
+import com.android.wm.shell.sysui.ShellController;
 
 import java.util.Optional;
 
@@ -48,6 +49,7 @@
 
     // Let's assume surfaces can be synchronized immediately.
     TestableBubbleController(Context context,
+            ShellController shellController,
             BubbleData data,
             FloatingContentCoordinator floatingContentCoordinator,
             BubbleDataRepository dataRepository,
@@ -67,11 +69,12 @@
             Handler shellMainHandler,
             TaskViewTransitions taskViewTransitions,
             SyncTransactionQueue syncQueue) {
-        super(context, data, Runnable::run, floatingContentCoordinator, dataRepository,
-                statusBarService, windowManager, windowManagerShellWrapper, userManager,
-                launcherApps, bubbleLogger, taskStackListener, shellTaskOrganizer, positioner,
-                displayController, oneHandedOptional, dragAndDropController, shellMainExecutor,
-                shellMainHandler, new SyncExecutor(), taskViewTransitions, syncQueue);
+        super(context, shellController, data, Runnable::run, floatingContentCoordinator,
+                dataRepository, statusBarService, windowManager, windowManagerShellWrapper,
+                userManager, launcherApps, bubbleLogger, taskStackListener, shellTaskOrganizer,
+                positioner, displayController, oneHandedOptional, dragAndDropController,
+                shellMainExecutor, shellMainHandler, new SyncExecutor(), taskViewTransitions,
+                syncQueue);
         setInflateSynchronously(true);
         initialize();
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
index 185942e..72ade26 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
@@ -24,12 +24,10 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.model.SysUiState;
-import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -37,14 +35,12 @@
 import com.android.systemui.tracing.ProtoTracer;
 import com.android.wm.shell.ShellCommandHandler;
 import com.android.wm.shell.common.ShellExecutor;
-import com.android.wm.shell.compatui.CompatUI;
-import com.android.wm.shell.draganddrop.DragAndDrop;
-import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
 import com.android.wm.shell.onehanded.OneHanded;
 import com.android.wm.shell.onehanded.OneHandedEventCallback;
 import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
 import com.android.wm.shell.pip.Pip;
 import com.android.wm.shell.splitscreen.SplitScreen;
+import com.android.wm.shell.sysui.ShellInterface;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -65,35 +61,30 @@
 public class WMShellTest extends SysuiTestCase {
     WMShell mWMShell;
 
+    @Mock ShellInterface mShellInterface;
     @Mock CommandQueue mCommandQueue;
     @Mock ConfigurationController mConfigurationController;
     @Mock KeyguardStateController mKeyguardStateController;
     @Mock KeyguardUpdateMonitor mKeyguardUpdateMonitor;
-    @Mock NavigationModeController mNavigationModeController;
     @Mock ScreenLifecycle mScreenLifecycle;
     @Mock SysUiState mSysUiState;
     @Mock Pip mPip;
     @Mock SplitScreen mSplitScreen;
     @Mock OneHanded mOneHanded;
-    @Mock HideDisplayCutout mHideDisplayCutout;
     @Mock WakefulnessLifecycle mWakefulnessLifecycle;
     @Mock ProtoTracer mProtoTracer;
     @Mock ShellCommandHandler mShellCommandHandler;
-    @Mock CompatUI mCompatUI;
     @Mock UserInfoController mUserInfoController;
     @Mock ShellExecutor mSysUiMainExecutor;
-    @Mock DragAndDrop mDragAndDrop;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        mWMShell = new WMShell(mContext, Optional.of(mPip),
-                Optional.of(mSplitScreen), Optional.of(mOneHanded), Optional.of(mHideDisplayCutout),
-                Optional.of(mShellCommandHandler), Optional.of(mCompatUI),
-                Optional.of(mDragAndDrop),
-                mCommandQueue, mConfigurationController, mKeyguardStateController,
-                mKeyguardUpdateMonitor, mNavigationModeController, mScreenLifecycle, mSysUiState,
+        mWMShell = new WMShell(mContext, mShellInterface, Optional.of(mPip),
+                Optional.of(mSplitScreen), Optional.of(mOneHanded),
+                Optional.of(mShellCommandHandler), mCommandQueue, mConfigurationController,
+                mKeyguardStateController, mKeyguardUpdateMonitor, mScreenLifecycle, mSysUiState,
                 mProtoTracer, mWakefulnessLifecycle, mUserInfoController, mSysUiMainExecutor);
     }
 
@@ -105,35 +96,12 @@
     }
 
     @Test
-    public void initSplitScreen_registersCallbacks() {
-        mWMShell.initSplitScreen(mSplitScreen);
-
-        verify(mKeyguardUpdateMonitor).registerCallback(any(KeyguardUpdateMonitorCallback.class));
-    }
-
-    @Test
     public void initOneHanded_registersCallbacks() {
         mWMShell.initOneHanded(mOneHanded);
 
-        verify(mKeyguardUpdateMonitor).registerCallback(any(KeyguardUpdateMonitorCallback.class));
         verify(mCommandQueue).addCallback(any(CommandQueue.Callbacks.class));
         verify(mScreenLifecycle).addObserver(any(ScreenLifecycle.Observer.class));
         verify(mOneHanded).registerTransitionCallback(any(OneHandedTransitionCallback.class));
         verify(mOneHanded).registerEventCallback(any(OneHandedEventCallback.class));
     }
-
-    @Test
-    public void initHideDisplayCutout_registersCallbacks() {
-        mWMShell.initHideDisplayCutout(mHideDisplayCutout);
-
-        verify(mConfigurationController).addCallback(
-                any(ConfigurationController.ConfigurationListener.class));
-    }
-
-    @Test
-    public void initCompatUI_registersCallbacks() {
-        mWMShell.initCompatUi(mCompatUI);
-
-        verify(mKeyguardStateController).addCallback(any(KeyguardStateController.Callback.class));
-    }
 }
diff --git a/packages/VpnDialogs/res/values-te/strings.xml b/packages/VpnDialogs/res/values-te/strings.xml
index 8f8ff07..7884336 100644
--- a/packages/VpnDialogs/res/values-te/strings.xml
+++ b/packages/VpnDialogs/res/values-te/strings.xml
@@ -17,7 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="prompt" msgid="3183836924226407828">"కనెక్షన్ రిక్వెస్ట్‌"</string>
-    <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> నెట్‌వర్క్ ట్రాఫిక్‌ని పర్యవేక్షించగలగడానికి VPN కనెక్షన్‌ను సెటప్ చేయాలనుకుంటోంది. మీరు మూలాన్ని విశ్వసిస్తే మాత్రమే ఆమోదించండి. VPN సక్రియంగా ఉన్నప్పుడు మీ స్క్రీన్ ఎగువన &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; కనిపిస్తుంది."</string>
+    <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> నెట్‌వర్క్ ట్రాఫిక్‌ని పర్యవేక్షించగలగడానికి VPN కనెక్షన్‌ను సెటప్ చేయాలనుకుంటోంది. మీరు మూలాన్ని విశ్వసిస్తే మాత్రమే ఆమోదించండి. VPN యాక్టివ్‌గా ఉన్నప్పుడు మీ స్క్రీన్ ఎగువన &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; కనిపిస్తుంది."</string>
     <string name="warning" product="tv" msgid="5188957997628124947">"నెట్‌వర్క్ ట్రాఫిక్‌ను పర్యవేక్షించగలగడానికి, <xliff:g id="APP">%s</xliff:g> VPN కనెక్షన్‌ను సెటప్ చేయాలనుకుంటోంది. మీరు సోర్స్‌ను విశ్వసిస్తే మాత్రమే ఆమోదించండి. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; VPN యాక్టివ్‌గా ఉన్నప్పుడు మీ స్క్రీన్ పై కనిపిస్తుంది."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN కనెక్ట్ చేయబడింది"</string>
     <string name="session" msgid="6470628549473641030">"సెషన్:"</string>
diff --git a/rs/OWNERS b/rs/OWNERS
index 61853d3..fd03660 100644
--- a/rs/OWNERS
+++ b/rs/OWNERS
@@ -1,5 +1,2 @@
-butlermichael@google.com
-dgross@google.com
-jeanluc@google.com
-miaowang@google.com
-yangni@google.com
+# Bug component: 43047
+include platform/frameworks/rs:/RS_OWNERS  # RenderScript team
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index 9b29bae..b34482f 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -2300,9 +2300,9 @@
             int processId, long threadId, int callingUid, Bundle callingStack) {
         if (mTrace.isA11yTracingEnabledForTypes(loggingTypes)) {
             ArrayList<StackTraceElement> list =
-                    (ArrayList<StackTraceElement>) callingStack.getSerializable(CALL_STACK);
+                    (ArrayList<StackTraceElement>) callingStack.getSerializable(CALL_STACK, java.util.ArrayList.class);
             HashSet<String> ignoreList =
-                    (HashSet<String>) callingStack.getSerializable(IGNORE_CALL_STACK);
+                    (HashSet<String>) callingStack.getSerializable(IGNORE_CALL_STACK, java.util.HashSet.class);
             mTrace.logTrace(timestamp, where, loggingTypes, callingParams, processId, threadId,
                     callingUid, list.toArray(new StackTraceElement[list.size()]), ignoreList);
         }
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 79f590f..6eabc98 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -114,6 +114,7 @@
 import android.view.accessibility.AccessibilityInteractionClient;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowAttributes;
 import android.view.accessibility.AccessibilityWindowInfo;
 import android.view.accessibility.IAccessibilityInteractionConnection;
 import android.view.accessibility.IAccessibilityManager;
@@ -3554,6 +3555,26 @@
         }
     }
 
+    /**
+     * Sets the {@link AccessibilityWindowAttributes} to the window associated with the given
+     * window id.
+     *
+     * @param displayId The display id of the window.
+     * @param windowId The id of the window
+     * @param userId The user id.
+     * @param attributes The accessibility window attributes.
+     */
+    @Override
+    public void setAccessibilityWindowAttributes(int displayId, int windowId, int userId,
+            AccessibilityWindowAttributes attributes) {
+        if (mTraceManager.isA11yTracingEnabledForTypes(FLAGS_ACCESSIBILITY_MANAGER)) {
+            mTraceManager.logTrace(LOG_TAG + ".setAccessibilityWindowAttributes",
+                    FLAGS_ACCESSIBILITY_MANAGER);
+        }
+        mA11yWindowManager.setAccessibilityWindowAttributes(displayId, windowId, userId,
+                attributes);
+    }
+
     @Override
     @RequiresPermission(Manifest.permission.SET_SYSTEM_AUDIO_CAPTION)
     public void setSystemAudioCaptioningEnabled(boolean isEnabled, int userId) {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
index e7ade3d..676bde7 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
@@ -43,6 +43,7 @@
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowAttributes;
 import android.view.accessibility.AccessibilityWindowInfo;
 import android.view.accessibility.IAccessibilityInteractionConnection;
 
@@ -120,6 +121,43 @@
     private final SparseArray<IBinder> mWindowIdMap = new SparseArray<>();
 
     /**
+     * Map of window id and window attribute hierarchy.
+     * The key is the window id when the ViewRootImpl register to accessibility, and the value is
+     * its window attribute .
+     */
+    private final SparseArray<AccessibilityWindowAttributes> mWindowAttributes =
+            new SparseArray<>();
+
+    /**
+     * Sets the {@link AccessibilityWindowAttributes} to the window associated with the given
+     * window id.
+     *
+     * @param displayId The display id of the window.
+     * @param windowId The id of the window
+     * @param userId The user id.
+     * @param attributes The accessibility window attributes.
+     */
+    public void setAccessibilityWindowAttributes(int displayId, int windowId, int userId,
+            AccessibilityWindowAttributes attributes) {
+        boolean shouldComputeWindows = false;
+        synchronized (mLock) {
+            final int resolvedUserId =
+                    mSecurityPolicy.resolveCallingUserIdEnforcingPermissionsLocked(userId);
+            if (getWindowTokenForUserAndWindowIdLocked(resolvedUserId, windowId) == null) {
+                return;
+            }
+            final AccessibilityWindowAttributes currentAttrs = mWindowAttributes.get(windowId);
+            if (currentAttrs == null || !currentAttrs.equals(attributes)) {
+                mWindowAttributes.put(windowId, attributes);
+                shouldComputeWindows = findWindowInfoByIdLocked(windowId) != null;
+            }
+        }
+        if (shouldComputeWindows) {
+            mWindowManagerInternal.computeWindowsForAccessibility(displayId);
+        }
+    }
+
+    /**
      * This class implements {@link WindowManagerInternal.WindowsForAccessibilityCallback} to
      * receive {@link WindowInfo}s from window manager when there's an accessibility change in
      * window and holds window lists information per display.
@@ -359,6 +397,7 @@
         public void onWindowsForAccessibilityChanged(boolean forceSend, int topFocusedDisplayId,
                 IBinder topFocusedWindowToken, @NonNull List<WindowInfo> windows) {
             synchronized (mLock) {
+                updateWindowsByWindowAttributesLocked(windows);
                 if (DEBUG) {
                     Slog.i(LOG_TAG, "Display Id = " + mDisplayId);
                     Slog.i(LOG_TAG, "Windows changed: " + windows);
@@ -376,6 +415,24 @@
             }
         }
 
+        private void updateWindowsByWindowAttributesLocked(List<WindowInfo> windows) {
+            for (int i = windows.size() - 1; i >= 0; i--) {
+                final WindowInfo windowInfo = windows.get(i);
+                final IBinder token = windowInfo.token;
+                final int windowId = findWindowIdLocked(
+                        mAccessibilityUserManager.getCurrentUserIdLocked(), token);
+                updateWindowWithWindowAttributes(windowInfo, mWindowAttributes.get(windowId));
+            }
+        }
+
+        private void updateWindowWithWindowAttributes(@NonNull WindowInfo windowInfo,
+                @Nullable AccessibilityWindowAttributes attributes) {
+            if (attributes == null) {
+                return;
+            }
+            windowInfo.title = attributes.getWindowTitle();
+        }
+
         private boolean shouldUpdateWindowsLocked(boolean forceSend,
                 @NonNull List<WindowInfo> windows) {
             if (forceSend) {
@@ -1223,6 +1280,7 @@
                     binder, AccessibilityWindowInfo.UNDEFINED_WINDOW_ID);
         }
         unregisterIdLocked(windowId);
+        mWindowAttributes.remove(windowId);
     }
 
     /**
@@ -1872,5 +1930,10 @@
                 observer.dumpLocked(fd, pw, args);
             }
         }
+        pw.println();
+        pw.append("Window attributes:[");
+        pw.append(mWindowAttributes.toString());
+        pw.append("]");
+        pw.println();
     }
 }
diff --git a/services/accessibility/java/com/android/server/accessibility/PolicyWarningUIController.java b/services/accessibility/java/com/android/server/accessibility/PolicyWarningUIController.java
index af81645..7fd859c 100644
--- a/services/accessibility/java/com/android/server/accessibility/PolicyWarningUIController.java
+++ b/services/accessibility/java/com/android/server/accessibility/PolicyWarningUIController.java
@@ -227,7 +227,7 @@
         public void onReceive(Context context, Intent intent) {
             final String action = intent.getAction();
             final ComponentName componentName = intent.getParcelableExtra(
-                    Intent.EXTRA_COMPONENT_NAME);
+                    Intent.EXTRA_COMPONENT_NAME, android.content.ComponentName.class);
             if (TextUtils.isEmpty(action) || componentName == null) {
                 return;
             }
diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
index 1af8ad3..84707a8 100644
--- a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
+++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
@@ -398,18 +398,7 @@
         final IBinder.DeathRecipient mDeathRecipient;
 
         private final RemoteCallbackList<IPredictionCallback> mCallbacks =
-                new RemoteCallbackList<IPredictionCallback>() {
-                    @Override
-                    public void onCallbackDied(IPredictionCallback callback) {
-                        if (DEBUG) {
-                            Slog.d(TAG, "Binder died for session Id=" + mSessionId
-                                    + " and callback=" + callback.asBinder());
-                        }
-                        if (mCallbacks.getRegisteredCallbackCount() == 0) {
-                            destroy();
-                        }
-                    }
-                };
+                new RemoteCallbackList<>();
 
         AppPredictionSessionInfo(
                 @NonNull final AppPredictionSessionId id,
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 9466a31..9b11a68 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -125,6 +125,7 @@
 import com.android.internal.util.DumpUtils;
 import com.android.internal.widget.IRemoteViewsFactory;
 import com.android.server.LocalServices;
+import com.android.server.ServiceThread;
 import com.android.server.WidgetBackupProvider;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -270,7 +271,10 @@
         mDevicePolicyManagerInternal = LocalServices.getService(DevicePolicyManagerInternal.class);
         mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
         mSaveStateHandler = BackgroundThread.getHandler();
-        mCallbackHandler = new CallbackHandler(mContext.getMainLooper());
+        final ServiceThread serviceThread = new ServiceThread(TAG,
+                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /* allowIo */);
+        serviceThread.start();
+        mCallbackHandler = new CallbackHandler(serviceThread.getLooper());
         mBackupRestoreController = new BackupRestoreController();
         mSecurityPolicy = new SecurityPolicy();
         mIsProviderInfoPersisted = !ActivityManager.isLowRamDeviceStatic()
@@ -313,26 +317,26 @@
         packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
         packageFilter.addDataScheme("package");
         mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
-                packageFilter, null, null);
+                packageFilter, null, mCallbackHandler);
 
         // Register for events related to sdcard installation.
         IntentFilter sdFilter = new IntentFilter();
         sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
         sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
         mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
-                sdFilter, null, null);
+                sdFilter, null, mCallbackHandler);
 
         IntentFilter offModeFilter = new IntentFilter();
         offModeFilter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
         offModeFilter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
         mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
-                offModeFilter, null, null);
+                offModeFilter, null, mCallbackHandler);
 
         IntentFilter suspendPackageFilter = new IntentFilter();
         suspendPackageFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
         suspendPackageFilter.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED);
         mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
-                suspendPackageFilter, null, null);
+                suspendPackageFilter, null, mCallbackHandler);
     }
 
     private void registerOnCrossProfileProvidersChangedListener() {
@@ -1224,11 +1228,12 @@
             try {
                 // Ask ActivityManager to bind it. Notice that we are binding the service with the
                 // caller app instead of DevicePolicyManagerService.
-                if(ActivityManager.getService().bindService(
+                if (ActivityManager.getService().bindService(
                         caller, activtiyToken, intent,
                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                        connection, flags, mContext.getOpPackageName(),
-                        widget.provider.getUserId()) != 0) {
+                        connection, flags & (Context.BIND_AUTO_CREATE
+                                | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE),
+                        mContext.getOpPackageName(), widget.provider.getUserId()) != 0) {
 
                     // Add it to the mapping of RemoteViewsService to appWidgetIds so that we
                     // can determine when we can call back to the RemoteViewsService later to
diff --git a/services/art-profile b/services/art-profile
index cb9dbb5..f5be083 100644
--- a/services/art-profile
+++ b/services/art-profile
@@ -13194,23 +13194,23 @@
 HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl$$ExternalSyntheticLambda5;->accept(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
 PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl$$ExternalSyntheticLambda6;-><init>()V
 PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl$$ExternalSyntheticLambda6;->accept(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
-PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->$r8$lambda$3cUMi5AwXItCfiFDVCUXCimE1C8(Ljava/lang/Object;Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/view/IInlineSuggestionsResponseCallback;)V
+PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->$r8$lambda$3cUMi5AwXItCfiFDVCUXCimE1C8(Ljava/lang/Object;Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/inputmethod/IInlineSuggestionsResponseCallback;)V
 PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->$r8$lambda$4eD-NhaAQgAaWV4xWXp6fTTGpK8(Ljava/lang/Object;ZZ)V
-PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->$r8$lambda$93C0LeU2EHcI07fDOWJQBHwvRtc(Ljava/lang/Object;Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/view/IInlineSuggestionsResponseCallback;)V
+PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->$r8$lambda$93C0LeU2EHcI07fDOWJQBHwvRtc(Ljava/lang/Object;Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/inputmethod/IInlineSuggestionsResponseCallback;)V
 PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->$r8$lambda$T6KGeNAHRvMAx6UVwQDBgY5g03s(Ljava/lang/Object;Landroid/view/autofill/AutofillId;ZZ)V
 PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->$r8$lambda$XS1N3pz3fznES_41qVCFW0CXwhs(Ljava/lang/Object;)V
 PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->$r8$lambda$_toALHf9LhzDDXXTVXT8BjqBe_E(Ljava/lang/Object;ZZ)V
 PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->$r8$lambda$nYWwnndWe0-hXzKg3FU2C6MB78w(Ljava/lang/Object;ZZ)V
 HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;-><init>(Lcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;)V
 PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;-><init>(Lcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;Lcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl-IA;)V
-PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->lambda$onInlineSuggestionsRequest$1(Ljava/lang/Object;Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/view/IInlineSuggestionsResponseCallback;)V
+PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->lambda$onInlineSuggestionsRequest$1(Ljava/lang/Object;Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/inputmethod/IInlineSuggestionsResponseCallback;)V
 PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->lambda$onInlineSuggestionsSessionInvalidated$6(Ljava/lang/Object;)V
-PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->lambda$onInlineSuggestionsUnsupported$0(Ljava/lang/Object;Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/view/IInlineSuggestionsResponseCallback;)V
+PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->lambda$onInlineSuggestionsUnsupported$0(Ljava/lang/Object;Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/inputmethod/IInlineSuggestionsResponseCallback;)V
 HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->lambda$onInputMethodFinishInput$5(Ljava/lang/Object;ZZ)V
 PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->lambda$onInputMethodFinishInputView$4(Ljava/lang/Object;ZZ)V
 HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->lambda$onInputMethodStartInput$2(Ljava/lang/Object;Landroid/view/autofill/AutofillId;ZZ)V
 PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->lambda$onInputMethodStartInputView$3(Ljava/lang/Object;ZZ)V
-HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->onInlineSuggestionsRequest(Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/view/IInlineSuggestionsResponseCallback;)V
+HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->onInlineSuggestionsRequest(Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/inputmethod/IInlineSuggestionsResponseCallback;)V
 HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->onInlineSuggestionsSessionInvalidated()V
 PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->onInlineSuggestionsUnsupported()V
 HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->onInputMethodFinishInput()V
@@ -13219,7 +13219,7 @@
 HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->onInputMethodStartInput(Landroid/view/autofill/AutofillId;)V
 HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->onInputMethodStartInputView()V
 HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->-$$Nest$fgetmHandler(Lcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;)Landroid/os/Handler;
-PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->-$$Nest$mhandleOnReceiveImeRequest(Lcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/view/IInlineSuggestionsResponseCallback;)V
+PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->-$$Nest$mhandleOnReceiveImeRequest(Lcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/inputmethod/IInlineSuggestionsResponseCallback;)V
 PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->-$$Nest$mhandleOnReceiveImeSessionInvalidated(Lcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;)V
 PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->-$$Nest$mhandleOnReceiveImeStatusUpdated(Lcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;Landroid/view/autofill/AutofillId;ZZ)V
 HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->-$$Nest$mhandleOnReceiveImeStatusUpdated(Lcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;ZZ)V
@@ -13228,7 +13228,7 @@
 HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;-><init>(Lcom/android/server/inputmethod/InputMethodManagerInternal;ILandroid/content/ComponentName;Landroid/os/Handler;Ljava/lang/Object;Landroid/view/autofill/AutofillId;Ljava/util/function/Consumer;Landroid/os/Bundle;Lcom/android/server/autofill/ui/InlineFillUi$InlineUiEventCallback;)V
 PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->destroySessionLocked()V
 PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->getInlineSuggestionsRequestLocked()Ljava/util/Optional;
-HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->handleOnReceiveImeRequest(Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/view/IInlineSuggestionsResponseCallback;)V
+HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->handleOnReceiveImeRequest(Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/inputmethod/IInlineSuggestionsResponseCallback;)V
 PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->handleOnReceiveImeSessionInvalidated()V
 HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->handleOnReceiveImeStatusUpdated(Landroid/view/autofill/AutofillId;ZZ)V
 HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->handleOnReceiveImeStatusUpdated(ZZ)V
@@ -23835,23 +23835,23 @@
 PLcom/android/server/inputmethod/HandwritingModeController;->reset()V
 PLcom/android/server/inputmethod/HandwritingModeController;->reset(Z)V
 PLcom/android/server/inputmethod/HandwritingModeController;->startHandwritingSession(IIILandroid/os/IBinder;)Lcom/android/server/inputmethod/HandwritingModeController$HandwritingSession;
-PLcom/android/server/inputmethod/IInputMethodInvoker;-><init>(Lcom/android/internal/view/IInputMethod;)V
+PLcom/android/server/inputmethod/IInputMethodInvoker;-><init>(Lcom/android/internal/inputmethod/IInputMethod;)V
 PLcom/android/server/inputmethod/IInputMethodInvoker;->asBinder()Landroid/os/IBinder;
 HPLcom/android/server/inputmethod/IInputMethodInvoker;->bindInput(Landroid/view/inputmethod/InputBinding;)V
 PLcom/android/server/inputmethod/IInputMethodInvoker;->changeInputMethodSubtype(Landroid/view/inputmethod/InputMethodSubtype;)V
-PLcom/android/server/inputmethod/IInputMethodInvoker;->create(Lcom/android/internal/view/IInputMethod;)Lcom/android/server/inputmethod/IInputMethodInvoker;
-PLcom/android/server/inputmethod/IInputMethodInvoker;->createSession(Landroid/view/InputChannel;Lcom/android/internal/view/IInputSessionCallback;)V
+PLcom/android/server/inputmethod/IInputMethodInvoker;->create(Lcom/android/internal/inputmethod/IInputMethod;)Lcom/android/server/inputmethod/IInputMethodInvoker;
+PLcom/android/server/inputmethod/IInputMethodInvoker;->createSession(Landroid/view/InputChannel;Lcom/android/internal/inputmethod/IInputMethodSessionCallback;)V
 PLcom/android/server/inputmethod/IInputMethodInvoker;->finishStylusHandwriting()V
 PLcom/android/server/inputmethod/IInputMethodInvoker;->getBinderIdentityHashCode(Lcom/android/server/inputmethod/IInputMethodInvoker;)I
 PLcom/android/server/inputmethod/IInputMethodInvoker;->getCallerMethodName()Ljava/lang/String;
 PLcom/android/server/inputmethod/IInputMethodInvoker;->hideSoftInput(Landroid/os/IBinder;ILandroid/os/ResultReceiver;)Z
 PLcom/android/server/inputmethod/IInputMethodInvoker;->initializeInternal(Landroid/os/IBinder;Lcom/android/internal/inputmethod/IInputMethodPrivilegedOperations;IZI)V
 PLcom/android/server/inputmethod/IInputMethodInvoker;->logRemoteException(Landroid/os/RemoteException;)V
-PLcom/android/server/inputmethod/IInputMethodInvoker;->onCreateInlineSuggestionsRequest(Lcom/android/internal/view/InlineSuggestionsRequestInfo;Lcom/android/internal/view/IInlineSuggestionsRequestCallback;)V
+PLcom/android/server/inputmethod/IInputMethodInvoker;->onCreateInlineSuggestionsRequest(Lcom/android/internal/inputmethod/InlineSuggestionsRequestInfo;Lcom/android/internal/inputmethod/IInlineSuggestionsRequestCallback;)V
 PLcom/android/server/inputmethod/IInputMethodInvoker;->onNavButtonFlagsChanged(I)V
-HPLcom/android/server/inputmethod/IInputMethodInvoker;->setSessionEnabled(Lcom/android/internal/view/IInputMethodSession;Z)V
+HPLcom/android/server/inputmethod/IInputMethodInvoker;->setSessionEnabled(Lcom/android/internal/inputmethod/IInputMethodSession;Z)V
 HPLcom/android/server/inputmethod/IInputMethodInvoker;->showSoftInput(Landroid/os/IBinder;ILandroid/os/ResultReceiver;)Z
-HPLcom/android/server/inputmethod/IInputMethodInvoker;->startInput(Landroid/os/IBinder;Lcom/android/internal/view/IInputContext;Landroid/view/inputmethod/EditorInfo;ZILandroid/window/ImeOnBackInvokedDispatcher;)V
+HPLcom/android/server/inputmethod/IInputMethodInvoker;->startInput(Landroid/os/IBinder;Lcom/android/internal/inputmethod/IRemoteInputConnection;Landroid/view/inputmethod/EditorInfo;ZILandroid/window/ImeOnBackInvokedDispatcher;)V
 HPLcom/android/server/inputmethod/IInputMethodInvoker;->unbindInput()V
 HSPLcom/android/server/inputmethod/ImePlatformCompatUtils;-><init>()V
 HPLcom/android/server/inputmethod/ImePlatformCompatUtils;->isChangeEnabledByUid(JI)Z
@@ -23923,7 +23923,7 @@
 PLcom/android/server/inputmethod/InputMethodManagerInternal$1;->getInputMethodListAsUser(I)Ljava/util/List;
 PLcom/android/server/inputmethod/InputMethodManagerInternal$1;->hideCurrentInputMethod(I)V
 PLcom/android/server/inputmethod/InputMethodManagerInternal$1;->maybeFinishStylusHandwriting()V
-PLcom/android/server/inputmethod/InputMethodManagerInternal$1;->onCreateInlineSuggestionsRequest(ILcom/android/internal/view/InlineSuggestionsRequestInfo;Lcom/android/internal/view/IInlineSuggestionsRequestCallback;)V
+PLcom/android/server/inputmethod/InputMethodManagerInternal$1;->onCreateInlineSuggestionsRequest(ILcom/android/internal/inputmethod/InlineSuggestionsRequestInfo;Lcom/android/internal/inputmethod/IInlineSuggestionsRequestCallback;)V
 HSPLcom/android/server/inputmethod/InputMethodManagerInternal$1;->onImeParentChanged()V
 PLcom/android/server/inputmethod/InputMethodManagerInternal$1;->removeImeSurface()V
 PLcom/android/server/inputmethod/InputMethodManagerInternal$1;->unbindAccessibilityFromCurrentClient(I)V
@@ -23940,7 +23940,7 @@
 HSPLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLambda2;->run()V
 HSPLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLambda3;-><init>(Lcom/android/server/wm/WindowManagerInternal;)V
 PLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLambda3;->getDisplayImePolicy(I)I
-PLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLambda4;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;ILcom/android/internal/view/IInputMethodClient;)V
+PLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLambda4;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;ILcom/android/internal/inputmethod/IInputMethodClient;)V
 PLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLambda4;->getOrThrow()Ljava/lang/Object;
 HPLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLambda5;-><init>()V
 HPLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLambda5;->test(Ljava/lang/Object;)Z
@@ -23950,7 +23950,7 @@
 HSPLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLambda9;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;)V
 PLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLambda9;->accept(Ljava/lang/Object;)V
 HPLcom/android/server/inputmethod/InputMethodManagerService$1;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/server/inputmethod/IInputMethodInvoker;Landroid/view/InputChannel;)V
-HPLcom/android/server/inputmethod/InputMethodManagerService$1;->sessionCreated(Lcom/android/internal/view/IInputMethodSession;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService$1;->sessionCreated(Lcom/android/internal/inputmethod/IInputMethodSession;)V
 HSPLcom/android/server/inputmethod/InputMethodManagerService$2;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;)V
 PLcom/android/server/inputmethod/InputMethodManagerService$2;->dumpAsProtoNoCheck(Ljava/io/FileDescriptor;)V
 PLcom/android/server/inputmethod/InputMethodManagerService$2;->dumpCritical(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;Z)V
@@ -23958,11 +23958,11 @@
 PLcom/android/server/inputmethod/InputMethodManagerService$2;->dumpNormal(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;Z)V
 PLcom/android/server/inputmethod/InputMethodManagerService$AccessibilitySessionState;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;ILcom/android/internal/inputmethod/IAccessibilityInputMethodSession;)V
 PLcom/android/server/inputmethod/InputMethodManagerService$AccessibilitySessionState;->toString()Ljava/lang/String;
-HSPLcom/android/server/inputmethod/InputMethodManagerService$ClientDeathRecipient;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/internal/view/IInputMethodClient;)V
+HSPLcom/android/server/inputmethod/InputMethodManagerService$ClientDeathRecipient;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/internal/inputmethod/IInputMethodClient;)V
 HPLcom/android/server/inputmethod/InputMethodManagerService$ClientDeathRecipient;->binderDied()V
-HSPLcom/android/server/inputmethod/InputMethodManagerService$ClientState;-><init>(Lcom/android/internal/view/IInputMethodClient;Lcom/android/internal/view/IInputContext;IIILcom/android/server/inputmethod/InputMethodManagerService$ClientDeathRecipient;)V
+HSPLcom/android/server/inputmethod/InputMethodManagerService$ClientState;-><init>(Lcom/android/internal/inputmethod/IInputMethodClient;Lcom/android/internal/inputmethod/IRemoteInputConnection;IIILcom/android/server/inputmethod/InputMethodManagerService$ClientDeathRecipient;)V
 HPLcom/android/server/inputmethod/InputMethodManagerService$ClientState;->toString()Ljava/lang/String;
-HPLcom/android/server/inputmethod/InputMethodManagerService$CreateInlineSuggestionsRequest;-><init>(Lcom/android/internal/view/InlineSuggestionsRequestInfo;Lcom/android/internal/view/IInlineSuggestionsRequestCallback;Ljava/lang/String;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService$CreateInlineSuggestionsRequest;-><init>(Lcom/android/internal/inputmethod/InlineSuggestionsRequestInfo;Lcom/android/internal/inputmethod/IInlineSuggestionsRequestCallback;Ljava/lang/String;)V
 HSPLcom/android/server/inputmethod/InputMethodManagerService$ImmsBroadcastReceiverForAllUsers;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;)V
 HSPLcom/android/server/inputmethod/InputMethodManagerService$ImmsBroadcastReceiverForAllUsers;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/server/inputmethod/InputMethodManagerService$ImmsBroadcastReceiverForAllUsers-IA;)V
 HPLcom/android/server/inputmethod/InputMethodManagerService$ImmsBroadcastReceiverForAllUsers;->onReceive(Landroid/content/Context;Landroid/content/Intent;)V
@@ -23972,8 +23972,8 @@
 HSPLcom/android/server/inputmethod/InputMethodManagerService$InkWindowInitializer;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;)V
 HSPLcom/android/server/inputmethod/InputMethodManagerService$InkWindowInitializer;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/server/inputmethod/InputMethodManagerService$InkWindowInitializer-IA;)V
 PLcom/android/server/inputmethod/InputMethodManagerService$InkWindowInitializer;->run()V
-HPLcom/android/server/inputmethod/InputMethodManagerService$InlineSuggestionsRequestCallbackDecorator;-><init>(Lcom/android/internal/view/IInlineSuggestionsRequestCallback;Ljava/lang/String;ILandroid/os/IBinder;Lcom/android/server/inputmethod/InputMethodManagerService;)V
-HPLcom/android/server/inputmethod/InputMethodManagerService$InlineSuggestionsRequestCallbackDecorator;->onInlineSuggestionsRequest(Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/view/IInlineSuggestionsResponseCallback;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService$InlineSuggestionsRequestCallbackDecorator;-><init>(Lcom/android/internal/inputmethod/IInlineSuggestionsRequestCallback;Ljava/lang/String;ILandroid/os/IBinder;Lcom/android/server/inputmethod/InputMethodManagerService;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService$InlineSuggestionsRequestCallbackDecorator;->onInlineSuggestionsRequest(Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/inputmethod/IInlineSuggestionsResponseCallback;)V
 PLcom/android/server/inputmethod/InputMethodManagerService$InlineSuggestionsRequestCallbackDecorator;->onInlineSuggestionsSessionInvalidated()V
 PLcom/android/server/inputmethod/InputMethodManagerService$InlineSuggestionsRequestCallbackDecorator;->onInlineSuggestionsUnsupported()V
 HPLcom/android/server/inputmethod/InputMethodManagerService$InlineSuggestionsRequestCallbackDecorator;->onInputMethodFinishInput()V
@@ -24008,7 +24008,7 @@
 PLcom/android/server/inputmethod/InputMethodManagerService$LocalServiceImpl;->getInputMethodListAsUser(I)Ljava/util/List;
 PLcom/android/server/inputmethod/InputMethodManagerService$LocalServiceImpl;->hideCurrentInputMethod(I)V
 HPLcom/android/server/inputmethod/InputMethodManagerService$LocalServiceImpl;->maybeFinishStylusHandwriting()V
-HPLcom/android/server/inputmethod/InputMethodManagerService$LocalServiceImpl;->onCreateInlineSuggestionsRequest(ILcom/android/internal/view/InlineSuggestionsRequestInfo;Lcom/android/internal/view/IInlineSuggestionsRequestCallback;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService$LocalServiceImpl;->onCreateInlineSuggestionsRequest(ILcom/android/internal/inputmethod/InlineSuggestionsRequestInfo;Lcom/android/internal/inputmethod/IInlineSuggestionsRequestCallback;)V
 HPLcom/android/server/inputmethod/InputMethodManagerService$LocalServiceImpl;->onImeParentChanged()V
 PLcom/android/server/inputmethod/InputMethodManagerService$LocalServiceImpl;->onSessionForAccessibilityCreated(ILcom/android/internal/inputmethod/IAccessibilityInputMethodSession;)V
 PLcom/android/server/inputmethod/InputMethodManagerService$LocalServiceImpl;->removeImeSurface()V
@@ -24035,7 +24035,7 @@
 PLcom/android/server/inputmethod/InputMethodManagerService$MyPackageMonitor;->onPackagesUnsuspended([Ljava/lang/String;)V
 PLcom/android/server/inputmethod/InputMethodManagerService$MyPackageMonitor;->onUidRemoved(I)V
 HPLcom/android/server/inputmethod/InputMethodManagerService$MyPackageMonitor;->shouldRebuildInputMethodListLocked()Z+]Landroid/util/ArraySet;Landroid/util/ArraySet;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HPLcom/android/server/inputmethod/InputMethodManagerService$SessionState;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;Lcom/android/server/inputmethod/IInputMethodInvoker;Lcom/android/internal/view/IInputMethodSession;Landroid/view/InputChannel;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService$SessionState;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;Lcom/android/server/inputmethod/IInputMethodInvoker;Lcom/android/internal/inputmethod/IInputMethodSession;Landroid/view/InputChannel;)V
 PLcom/android/server/inputmethod/InputMethodManagerService$SessionState;->toString()Ljava/lang/String;
 HSPLcom/android/server/inputmethod/InputMethodManagerService$SettingsObserver;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/Handler;)V
 PLcom/android/server/inputmethod/InputMethodManagerService$SettingsObserver;->onChange(ZLandroid/net/Uri;)V
@@ -24064,7 +24064,7 @@
 HSPLcom/android/server/inputmethod/InputMethodManagerService$StartInputHistory;->getEntrySize()I
 PLcom/android/server/inputmethod/InputMethodManagerService$StartInputInfo;-><clinit>()V
 HPLcom/android/server/inputmethod/InputMethodManagerService$StartInputInfo;-><init>(ILandroid/os/IBinder;ILjava/lang/String;IZIILandroid/os/IBinder;Landroid/view/inputmethod/EditorInfo;II)V
-HPLcom/android/server/inputmethod/InputMethodManagerService$UserSwitchHandlerTask;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;ILcom/android/internal/view/IInputMethodClient;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService$UserSwitchHandlerTask;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;ILcom/android/internal/inputmethod/IInputMethodClient;)V
 HPLcom/android/server/inputmethod/InputMethodManagerService$UserSwitchHandlerTask;->run()V
 PLcom/android/server/inputmethod/InputMethodManagerService$VirtualDisplayInfo;->-$$Nest$fgetmMatrix(Lcom/android/server/inputmethod/InputMethodManagerService$VirtualDisplayInfo;)Landroid/graphics/Matrix;
 PLcom/android/server/inputmethod/InputMethodManagerService$VirtualDisplayInfo;->-$$Nest$fgetmParentClient(Lcom/android/server/inputmethod/InputMethodManagerService$VirtualDisplayInfo;)Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;
@@ -24072,7 +24072,7 @@
 HSPLcom/android/server/inputmethod/InputMethodManagerService;->$r8$lambda$AhkKGaXMb2go3kAOJFxNNwN_Wcw(Lcom/android/server/inputmethod/InputMethodManagerService;I)V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->$r8$lambda$F9EIkbJ0j0nkV0RkbPOhyw9yI_8(Ljava/util/List;ILcom/android/server/inputmethod/InputMethodManagerInternal$InputMethodListListener;)V
 PLcom/android/server/inputmethod/InputMethodManagerService;->$r8$lambda$XUIWnM1I-xqMtdWJBk3rvGL6t0I(Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/server/inputmethod/OverlayableSystemBooleanResourceWrapper;)V
-PLcom/android/server/inputmethod/InputMethodManagerService;->$r8$lambda$bNnzxTzGOLxDTcZA3PdLo_4mWHU(Lcom/android/server/inputmethod/InputMethodManagerService;ILcom/android/internal/view/IInputMethodClient;)Ljava/lang/Integer;
+PLcom/android/server/inputmethod/InputMethodManagerService;->$r8$lambda$bNnzxTzGOLxDTcZA3PdLo_4mWHU(Lcom/android/server/inputmethod/InputMethodManagerService;ILcom/android/internal/inputmethod/IInputMethodClient;)Ljava/lang/Integer;
 PLcom/android/server/inputmethod/InputMethodManagerService;->$r8$lambda$vz_z57ulRhr4T1Ld16KRvnRuVVc(Lcom/android/server/inputmethod/InputMethodManagerService;Z)V
 PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$fgetmAccessibilityManager(Lcom/android/server/inputmethod/InputMethodManagerService;)Landroid/view/accessibility/AccessibilityManager;
 PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$fgetmAccessibilityRequestingNoSoftKeyboard(Lcom/android/server/inputmethod/InputMethodManagerService;)Z
@@ -24093,7 +24093,7 @@
 PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mcreateInputContentUriToken(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/IBinder;Landroid/net/Uri;Ljava/lang/String;)Lcom/android/internal/inputmethod/IInputContentUriToken;
 PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mdumpAsStringNoCheck(Lcom/android/server/inputmethod/InputMethodManagerService;Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;Z)V
 PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mdumpDebug(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/util/proto/ProtoOutputStream;J)V
-PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mexecuteOrSendMessage(Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/internal/view/IInputMethodClient;Landroid/os/Message;)V
+PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mexecuteOrSendMessage(Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/internal/inputmethod/IInputMethodClient;Landroid/os/Message;)V
 PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mgetCurMethodLocked(Lcom/android/server/inputmethod/InputMethodManagerService;)Lcom/android/server/inputmethod/IInputMethodInvoker;
 PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mgetEnabledInputMethodListLocked(Lcom/android/server/inputmethod/InputMethodManagerService;I)Ljava/util/List;
 PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mgetInputMethodListLocked(Lcom/android/server/inputmethod/InputMethodManagerService;II)Ljava/util/List;
@@ -24101,7 +24101,7 @@
 PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mhandleShellCommandTraceInputMethod(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/ShellCommand;)I
 PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mhideMySoftInput(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/IBinder;I)V
 PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mnotifyUserAction(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/IBinder;)V
-PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$monCreateInlineSuggestionsRequestLocked(Lcom/android/server/inputmethod/InputMethodManagerService;ILcom/android/internal/view/InlineSuggestionsRequestInfo;Lcom/android/internal/view/IInlineSuggestionsRequestCallback;Z)V
+PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$monCreateInlineSuggestionsRequestLocked(Lcom/android/server/inputmethod/InputMethodManagerService;ILcom/android/internal/inputmethod/InlineSuggestionsRequestInfo;Lcom/android/internal/inputmethod/IInlineSuggestionsRequestCallback;Z)V
 HSPLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mpublishLocalService(Lcom/android/server/inputmethod/InputMethodManagerService;)V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mreportFullscreenMode(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/IBinder;Z)V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mreportStartInput(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/IBinder;Landroid/os/IBinder;)V
@@ -24110,10 +24110,10 @@
 PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mshouldOfferSwitchingToNextInputMethod(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/IBinder;)Z
 PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mshowMySoftInput(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/IBinder;I)V
 PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mswitchToPreviousInputMethod(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/IBinder;)Z
-PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mswitchUserOnHandlerLocked(Lcom/android/server/inputmethod/InputMethodManagerService;ILcom/android/internal/view/IInputMethodClient;)V
+PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mswitchUserOnHandlerLocked(Lcom/android/server/inputmethod/InputMethodManagerService;ILcom/android/internal/inputmethod/IInputMethodClient;)V
 PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mupdateStatusIcon(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/IBinder;Ljava/lang/String;I)V
 HSPLcom/android/server/inputmethod/InputMethodManagerService;-><init>(Landroid/content/Context;)V
-HSPLcom/android/server/inputmethod/InputMethodManagerService;->addClient(Lcom/android/internal/view/IInputMethodClient;Lcom/android/internal/view/IInputContext;I)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Lcom/android/internal/view/IInputMethodClient;Lcom/android/internal/view/IInputMethodClient$Stub$Proxy;
+HSPLcom/android/server/inputmethod/InputMethodManagerService;->addClient(Lcom/android/internal/inputmethod/IInputMethodClient;Lcom/android/internal/inputmethod/IRemoteInputConnection;I)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Lcom/android/internal/inputmethod/IInputMethodClient;Lcom/android/internal/view/IInputMethodClient$Stub$Proxy;
 HPLcom/android/server/inputmethod/InputMethodManagerService;->advanceSequenceNumberLocked()V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->applyImeVisibility(Landroid/os/IBinder;Landroid/os/IBinder;Z)V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->attachNewAccessibilityLocked(IZI)Lcom/android/internal/inputmethod/InputBindResult;
@@ -24121,8 +24121,8 @@
 HSPLcom/android/server/inputmethod/InputMethodManagerService;->buildInputMethodListLocked(Z)V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->calledFromValidUserLocked()Z+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/content/Context;Landroid/app/ContextImpl;]Lcom/android/server/inputmethod/InputMethodUtils$InputMethodSettings;Lcom/android/server/inputmethod/InputMethodUtils$InputMethodSettings;
 HPLcom/android/server/inputmethod/InputMethodManagerService;->calledWithValidTokenLocked(Landroid/os/IBinder;)Z
-HPLcom/android/server/inputmethod/InputMethodManagerService;->canInteractWithImeLocked(ILcom/android/internal/view/IInputMethodClient;Ljava/lang/String;)Z
-PLcom/android/server/inputmethod/InputMethodManagerService;->canShowInputMethodPickerLocked(Lcom/android/internal/view/IInputMethodClient;)Z
+HPLcom/android/server/inputmethod/InputMethodManagerService;->canInteractWithImeLocked(ILcom/android/internal/inputmethod/IInputMethodClient;Ljava/lang/String;)Z
+PLcom/android/server/inputmethod/InputMethodManagerService;->canShowInputMethodPickerLocked(Lcom/android/internal/inputmethod/IInputMethodClient;)Z
 PLcom/android/server/inputmethod/InputMethodManagerService;->chooseNewDefaultIMELocked()Z
 HPLcom/android/server/inputmethod/InputMethodManagerService;->clearClientSessionForAccessibilityLocked(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;)V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->clearClientSessionForAccessibilityLocked(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;I)V
@@ -24136,7 +24136,7 @@
 PLcom/android/server/inputmethod/InputMethodManagerService;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->dumpAsStringNoCheck(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;Z)V
 PLcom/android/server/inputmethod/InputMethodManagerService;->dumpDebug(Landroid/util/proto/ProtoOutputStream;J)V
-HPLcom/android/server/inputmethod/InputMethodManagerService;->executeOrSendMessage(Lcom/android/internal/view/IInputMethodClient;Landroid/os/Message;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService;->executeOrSendMessage(Lcom/android/internal/inputmethod/IInputMethodClient;Landroid/os/Message;)V
 PLcom/android/server/inputmethod/InputMethodManagerService;->finishSessionForAccessibilityLocked(Lcom/android/server/inputmethod/InputMethodManagerService$AccessibilitySessionState;)V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->finishSessionLocked(Lcom/android/server/inputmethod/InputMethodManagerService$SessionState;)V
 PLcom/android/server/inputmethod/InputMethodManagerService;->getAppShowFlagsLocked()I
@@ -24159,7 +24159,7 @@
 HPLcom/android/server/inputmethod/InputMethodManagerService;->getInputMethodListInternal(II)Ljava/util/List;
 HPLcom/android/server/inputmethod/InputMethodManagerService;->getInputMethodListLocked(II)Ljava/util/List;
 HPLcom/android/server/inputmethod/InputMethodManagerService;->getInputMethodNavButtonFlagsLocked()I
-PLcom/android/server/inputmethod/InputMethodManagerService;->getInputMethodWindowVisibleHeight(Lcom/android/internal/view/IInputMethodClient;)I
+PLcom/android/server/inputmethod/InputMethodManagerService;->getInputMethodWindowVisibleHeight(Lcom/android/internal/inputmethod/IInputMethodClient;)I
 PLcom/android/server/inputmethod/InputMethodManagerService;->getLastBindTimeLocked()J
 PLcom/android/server/inputmethod/InputMethodManagerService;->getLastInputMethodSubtype()Landroid/view/inputmethod/InputMethodSubtype;
 PLcom/android/server/inputmethod/InputMethodManagerService;->getLastSwitchUserId(Landroid/os/ShellCommand;)I
@@ -24167,7 +24167,7 @@
 HSPLcom/android/server/inputmethod/InputMethodManagerService;->getSelectedMethodIdLocked()Ljava/lang/String;
 HPLcom/android/server/inputmethod/InputMethodManagerService;->getSequenceNumberLocked()I
 PLcom/android/server/inputmethod/InputMethodManagerService;->getVirtualDisplayToScreenMatrixLocked(II)Landroid/graphics/Matrix;
-HSPLcom/android/server/inputmethod/InputMethodManagerService;->handleMessage(Landroid/os/Message;)Z+]Landroid/media/AudioManagerInternal;Lcom/android/server/audio/AudioService$AudioServiceInternal;]Ljava/util/OptionalInt;Ljava/util/OptionalInt;]Lcom/android/server/inputmethod/InputMethodBindingController;Lcom/android/server/inputmethod/InputMethodBindingController;]Lcom/android/internal/view/IInputMethodSession;Lcom/android/internal/view/IInputMethodSession$Stub$Proxy;]Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/server/inputmethod/InputMethodManagerService;]Ljava/lang/Integer;Ljava/lang/Integer;]Landroid/view/InputChannel;Landroid/view/InputChannel;]Lcom/android/server/inputmethod/HandwritingModeController;Lcom/android/server/inputmethod/HandwritingModeController;]Lcom/android/internal/view/IInputMethodClient;Lcom/android/internal/view/IInputMethodClient$Stub$Proxy;]Lcom/android/internal/os/SomeArgs;Lcom/android/internal/os/SomeArgs;]Ljava/util/concurrent/CopyOnWriteArrayList;Ljava/util/concurrent/CopyOnWriteArrayList;
+HSPLcom/android/server/inputmethod/InputMethodManagerService;->handleMessage(Landroid/os/Message;)Z+]Landroid/media/AudioManagerInternal;Lcom/android/server/audio/AudioService$AudioServiceInternal;]Ljava/util/OptionalInt;Ljava/util/OptionalInt;]Lcom/android/server/inputmethod/InputMethodBindingController;Lcom/android/server/inputmethod/InputMethodBindingController;]Lcom/android/internal/inputmethod/IInputMethodSession;Lcom/android/internal/view/IInputMethodSession$Stub$Proxy;]Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/server/inputmethod/InputMethodManagerService;]Ljava/lang/Integer;Ljava/lang/Integer;]Landroid/view/InputChannel;Landroid/view/InputChannel;]Lcom/android/server/inputmethod/HandwritingModeController;Lcom/android/server/inputmethod/HandwritingModeController;]Lcom/android/internal/inputmethod/IInputMethodClient;Lcom/android/internal/view/IInputMethodClient$Stub$Proxy;]Lcom/android/internal/os/SomeArgs;Lcom/android/internal/os/SomeArgs;]Ljava/util/concurrent/CopyOnWriteArrayList;Ljava/util/concurrent/CopyOnWriteArrayList;
 PLcom/android/server/inputmethod/InputMethodManagerService;->handleOptionsForCommandsThatOnlyHaveUserOption(Landroid/os/ShellCommand;)I
 PLcom/android/server/inputmethod/InputMethodManagerService;->handleSetInteractive(Z)V
 PLcom/android/server/inputmethod/InputMethodManagerService;->handleShellCommandEnableDisableInputMethod(Landroid/os/ShellCommand;Z)I
@@ -24179,7 +24179,7 @@
 PLcom/android/server/inputmethod/InputMethodManagerService;->hasConnectionLocked()Z
 HPLcom/android/server/inputmethod/InputMethodManagerService;->hideCurrentInputLocked(Landroid/os/IBinder;ILandroid/os/ResultReceiver;I)Z+]Lcom/android/server/inputmethod/InputMethodBindingController;Lcom/android/server/inputmethod/InputMethodBindingController;]Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/server/inputmethod/InputMethodManagerService;]Lcom/android/server/inputmethod/IInputMethodInvoker;Lcom/android/server/inputmethod/IInputMethodInvoker;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;
 HPLcom/android/server/inputmethod/InputMethodManagerService;->hideMySoftInput(Landroid/os/IBinder;I)V
-HPLcom/android/server/inputmethod/InputMethodManagerService;->hideSoftInput(Lcom/android/internal/view/IInputMethodClient;Landroid/os/IBinder;ILandroid/os/ResultReceiver;I)Z+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/server/inputmethod/InputMethodManagerService;]Lcom/android/internal/view/IInputMethodClient;Lcom/android/internal/view/IInputMethodClient$Stub$Proxy;]Lcom/android/internal/inputmethod/ImeTracing;Lcom/android/internal/inputmethod/ImeTracingServerImpl;
+HPLcom/android/server/inputmethod/InputMethodManagerService;->hideSoftInput(Lcom/android/internal/inputmethod/IInputMethodClient;Landroid/os/IBinder;ILandroid/os/ResultReceiver;I)Z+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/server/inputmethod/InputMethodManagerService;]Lcom/android/internal/inputmethod/IInputMethodClient;Lcom/android/internal/view/IInputMethodClient$Stub$Proxy;]Lcom/android/internal/inputmethod/ImeTracing;Lcom/android/internal/inputmethod/ImeTracingServerImpl;
 HSPLcom/android/server/inputmethod/InputMethodManagerService;->hideStatusBarIconLocked()V
 PLcom/android/server/inputmethod/InputMethodManagerService;->initializeImeLocked(Lcom/android/server/inputmethod/IInputMethodInvoker;Landroid/os/IBinder;IZ)V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->isImeClientFocused(Landroid/os/IBinder;Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;)Z
@@ -24188,7 +24188,7 @@
 PLcom/android/server/inputmethod/InputMethodManagerService;->isInputMethodPickerShownForTest()Z
 PLcom/android/server/inputmethod/InputMethodManagerService;->isNonPreemptibleImeLocked(Ljava/lang/String;)Z
 HPLcom/android/server/inputmethod/InputMethodManagerService;->isSelectedMethodBoundLocked()Z
-PLcom/android/server/inputmethod/InputMethodManagerService;->lambda$getInputMethodWindowVisibleHeight$3(ILcom/android/internal/view/IInputMethodClient;)Ljava/lang/Integer;
+PLcom/android/server/inputmethod/InputMethodManagerService;->lambda$getInputMethodWindowVisibleHeight$3(ILcom/android/internal/inputmethod/IInputMethodClient;)Ljava/lang/Integer;
 PLcom/android/server/inputmethod/InputMethodManagerService;->lambda$handleMessage$4(Ljava/util/List;ILcom/android/server/inputmethod/InputMethodManagerInternal$InputMethodListListener;)V
 PLcom/android/server/inputmethod/InputMethodManagerService;->lambda$handleShellCommandResetInputMethod$5(Lcom/android/server/inputmethod/InputMethodUtils$InputMethodSettings;Landroid/view/inputmethod/InputMethodInfo;)V
 PLcom/android/server/inputmethod/InputMethodManagerService;->lambda$handleShellCommandResetInputMethod$6(Ljava/io/PrintWriter;Landroid/view/inputmethod/InputMethodInfo;)V
@@ -24200,8 +24200,8 @@
 HPLcom/android/server/inputmethod/InputMethodManagerService;->obtainMessageIIIO(IIIILjava/lang/Object;)Landroid/os/Message;
 HPLcom/android/server/inputmethod/InputMethodManagerService;->obtainMessageOO(ILjava/lang/Object;Ljava/lang/Object;)Landroid/os/Message;
 PLcom/android/server/inputmethod/InputMethodManagerService;->onActionLocaleChanged()V
-HPLcom/android/server/inputmethod/InputMethodManagerService;->onCreateInlineSuggestionsRequestLocked(ILcom/android/internal/view/InlineSuggestionsRequestInfo;Lcom/android/internal/view/IInlineSuggestionsRequestCallback;Z)V
-HPLcom/android/server/inputmethod/InputMethodManagerService;->onSessionCreated(Lcom/android/server/inputmethod/IInputMethodInvoker;Lcom/android/internal/view/IInputMethodSession;Landroid/view/InputChannel;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService;->onCreateInlineSuggestionsRequestLocked(ILcom/android/internal/inputmethod/InlineSuggestionsRequestInfo;Lcom/android/internal/inputmethod/IInlineSuggestionsRequestCallback;Z)V
+HPLcom/android/server/inputmethod/InputMethodManagerService;->onSessionCreated(Lcom/android/server/inputmethod/IInputMethodInvoker;Lcom/android/internal/inputmethod/IInputMethodSession;Landroid/view/InputChannel;)V
 PLcom/android/server/inputmethod/InputMethodManagerService;->onShellCommand(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;[Ljava/lang/String;Landroid/os/ShellCallback;Landroid/os/ResultReceiver;)V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->onShowHideSoftInputRequested(ZLandroid/os/IBinder;I)V
 HSPLcom/android/server/inputmethod/InputMethodManagerService;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
@@ -24212,13 +24212,13 @@
 HSPLcom/android/server/inputmethod/InputMethodManagerService;->queryInputMethodServicesInternal(Landroid/content/Context;ILandroid/util/ArrayMap;Landroid/util/ArrayMap;Ljava/util/ArrayList;I)V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->queryMethodMapForUser(I)Landroid/util/ArrayMap;
 HPLcom/android/server/inputmethod/InputMethodManagerService;->reRequestCurrentClientSessionLocked()V
-HPLcom/android/server/inputmethod/InputMethodManagerService;->removeClient(Lcom/android/internal/view/IInputMethodClient;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService;->removeClient(Lcom/android/internal/inputmethod/IInputMethodClient;)V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->removeImeSurface()V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->removeImeSurfaceFromWindowAsync(Landroid/os/IBinder;)V+]Landroid/os/Handler;Landroid/os/Handler;]Landroid/os/Message;Landroid/os/Message;
 HPLcom/android/server/inputmethod/InputMethodManagerService;->reportFullscreenMode(Landroid/os/IBinder;Z)V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->reportPerceptibleAsync(Landroid/os/IBinder;Z)V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->reportStartInput(Landroid/os/IBinder;Landroid/os/IBinder;)V
-PLcom/android/server/inputmethod/InputMethodManagerService;->reportVirtualDisplayGeometryAsync(Lcom/android/internal/view/IInputMethodClient;I[F)V
+PLcom/android/server/inputmethod/InputMethodManagerService;->reportVirtualDisplayGeometryAsync(Lcom/android/internal/inputmethod/IInputMethodClient;I[F)V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->requestClientSessionForAccessibilityLocked(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;)V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->requestClientSessionLocked(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;)V
 PLcom/android/server/inputmethod/InputMethodManagerService;->resetCurrentMethodAndClientLocked(I)V
@@ -24229,7 +24229,7 @@
 HPLcom/android/server/inputmethod/InputMethodManagerService;->scheduleNotifyImeUidToAudioService(I)V
 PLcom/android/server/inputmethod/InputMethodManagerService;->scheduleResetStylusHandwriting()V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->scheduleSetActiveToClient(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;ZZZ)V
-HPLcom/android/server/inputmethod/InputMethodManagerService;->scheduleSwitchUserTaskLocked(ILcom/android/internal/view/IInputMethodClient;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService;->scheduleSwitchUserTaskLocked(ILcom/android/internal/inputmethod/IInputMethodClient;)V
 HSPLcom/android/server/inputmethod/InputMethodManagerService;->sendOnNavButtonFlagsChangedLocked()V
 PLcom/android/server/inputmethod/InputMethodManagerService;->setAdditionalInputMethodSubtypes(Ljava/lang/String;[Landroid/view/inputmethod/InputMethodSubtype;)V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->setCurHostInputToken(Landroid/os/IBinder;Landroid/os/IBinder;)V
@@ -24249,20 +24249,20 @@
 PLcom/android/server/inputmethod/InputMethodManagerService;->shouldRestoreImeVisibility(Landroid/os/IBinder;I)Z
 HPLcom/android/server/inputmethod/InputMethodManagerService;->shouldShowImeSwitcherLocked(I)Z+]Landroid/view/inputmethod/InputMethodSubtype;Landroid/view/inputmethod/InputMethodSubtype;]Ljava/util/List;Ljava/util/ArrayList;]Lcom/android/server/wm/WindowManagerInternal;Lcom/android/server/wm/WindowManagerService$LocalService;]Lcom/android/server/inputmethod/InputMethodUtils$InputMethodSettings;Lcom/android/server/inputmethod/InputMethodUtils$InputMethodSettings;]Landroid/app/KeyguardManager;Landroid/app/KeyguardManager;]Lcom/android/server/inputmethod/InputMethodMenuController;Lcom/android/server/inputmethod/InputMethodMenuController;
 HPLcom/android/server/inputmethod/InputMethodManagerService;->showCurrentInputLocked(Landroid/os/IBinder;ILandroid/os/ResultReceiver;I)Z
-PLcom/android/server/inputmethod/InputMethodManagerService;->showInputMethodAndSubtypeEnablerFromClient(Lcom/android/internal/view/IInputMethodClient;Ljava/lang/String;)V
-PLcom/android/server/inputmethod/InputMethodManagerService;->showInputMethodPickerFromClient(Lcom/android/internal/view/IInputMethodClient;I)V
+PLcom/android/server/inputmethod/InputMethodManagerService;->showInputMethodAndSubtypeEnablerFromClient(Lcom/android/internal/inputmethod/IInputMethodClient;Ljava/lang/String;)V
+PLcom/android/server/inputmethod/InputMethodManagerService;->showInputMethodPickerFromClient(Lcom/android/internal/inputmethod/IInputMethodClient;I)V
 PLcom/android/server/inputmethod/InputMethodManagerService;->showMySoftInput(Landroid/os/IBinder;I)V
-HPLcom/android/server/inputmethod/InputMethodManagerService;->showSoftInput(Lcom/android/internal/view/IInputMethodClient;Landroid/os/IBinder;ILandroid/os/ResultReceiver;I)Z
+HPLcom/android/server/inputmethod/InputMethodManagerService;->showSoftInput(Lcom/android/internal/inputmethod/IInputMethodClient;Landroid/os/IBinder;ILandroid/os/ResultReceiver;I)Z
 HPLcom/android/server/inputmethod/InputMethodManagerService;->startImeTrace()V
-HPLcom/android/server/inputmethod/InputMethodManagerService;->startInputOrWindowGainedFocus(ILcom/android/internal/view/IInputMethodClient;Landroid/os/IBinder;IIILandroid/view/inputmethod/EditorInfo;Lcom/android/internal/view/IInputContext;Lcom/android/internal/inputmethod/IRemoteAccessibilityInputConnection;ILandroid/window/ImeOnBackInvokedDispatcher;)Lcom/android/internal/inputmethod/InputBindResult;
-HPLcom/android/server/inputmethod/InputMethodManagerService;->startInputOrWindowGainedFocusInternal(ILcom/android/internal/view/IInputMethodClient;Landroid/os/IBinder;IIILandroid/view/inputmethod/EditorInfo;Lcom/android/internal/view/IInputContext;Lcom/android/internal/inputmethod/IRemoteAccessibilityInputConnection;ILandroid/window/ImeOnBackInvokedDispatcher;)Lcom/android/internal/inputmethod/InputBindResult;
-HPLcom/android/server/inputmethod/InputMethodManagerService;->startInputOrWindowGainedFocusInternalLocked(ILcom/android/internal/view/IInputMethodClient;Landroid/os/IBinder;IIILandroid/view/inputmethod/EditorInfo;Lcom/android/internal/view/IInputContext;Lcom/android/internal/inputmethod/IRemoteAccessibilityInputConnection;IILandroid/window/ImeOnBackInvokedDispatcher;)Lcom/android/internal/inputmethod/InputBindResult;
-HPLcom/android/server/inputmethod/InputMethodManagerService;->startInputUncheckedLocked(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;Lcom/android/internal/view/IInputContext;Lcom/android/internal/inputmethod/IRemoteAccessibilityInputConnection;Landroid/view/inputmethod/EditorInfo;IIILandroid/window/ImeOnBackInvokedDispatcher;)Lcom/android/internal/inputmethod/InputBindResult;
+HPLcom/android/server/inputmethod/InputMethodManagerService;->startInputOrWindowGainedFocus(ILcom/android/internal/inputmethod/IInputMethodClient;Landroid/os/IBinder;IIILandroid/view/inputmethod/EditorInfo;Lcom/android/internal/inputmethod/IRemoteInputConnection;Lcom/android/internal/inputmethod/IRemoteAccessibilityInputConnection;ILandroid/window/ImeOnBackInvokedDispatcher;)Lcom/android/internal/inputmethod/InputBindResult;
+HPLcom/android/server/inputmethod/InputMethodManagerService;->startInputOrWindowGainedFocusInternal(ILcom/android/internal/inputmethod/IInputMethodClient;Landroid/os/IBinder;IIILandroid/view/inputmethod/EditorInfo;Lcom/android/internal/inputmethod/IRemoteInputConnection;Lcom/android/internal/inputmethod/IRemoteAccessibilityInputConnection;ILandroid/window/ImeOnBackInvokedDispatcher;)Lcom/android/internal/inputmethod/InputBindResult;
+HPLcom/android/server/inputmethod/InputMethodManagerService;->startInputOrWindowGainedFocusInternalLocked(ILcom/android/internal/inputmethod/IInputMethodClient;Landroid/os/IBinder;IIILandroid/view/inputmethod/EditorInfo;Lcom/android/internal/inputmethod/IRemoteInputConnection;Lcom/android/internal/inputmethod/IRemoteAccessibilityInputConnection;IILandroid/window/ImeOnBackInvokedDispatcher;)Lcom/android/internal/inputmethod/InputBindResult;
+HPLcom/android/server/inputmethod/InputMethodManagerService;->startInputUncheckedLocked(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;Lcom/android/internal/inputmethod/IRemoteInputConnection;Lcom/android/internal/inputmethod/IRemoteAccessibilityInputConnection;Landroid/view/inputmethod/EditorInfo;IIILandroid/window/ImeOnBackInvokedDispatcher;)Lcom/android/internal/inputmethod/InputBindResult;
 PLcom/android/server/inputmethod/InputMethodManagerService;->startProtoDump([BILjava/lang/String;)V
 PLcom/android/server/inputmethod/InputMethodManagerService;->stopImeTrace()V
 PLcom/android/server/inputmethod/InputMethodManagerService;->switchToNextInputMethod(Landroid/os/IBinder;Z)Z
 PLcom/android/server/inputmethod/InputMethodManagerService;->switchToPreviousInputMethod(Landroid/os/IBinder;)Z
-HPLcom/android/server/inputmethod/InputMethodManagerService;->switchUserOnHandlerLocked(ILcom/android/internal/view/IInputMethodClient;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService;->switchUserOnHandlerLocked(ILcom/android/internal/inputmethod/IInputMethodClient;)V
 HSPLcom/android/server/inputmethod/InputMethodManagerService;->systemRunning(Lcom/android/server/statusbar/StatusBarManagerService;)V
 HPLcom/android/server/inputmethod/InputMethodManagerService;->tryReuseConnectionLocked(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;)Lcom/android/internal/inputmethod/InputBindResult;
 HSPLcom/android/server/inputmethod/InputMethodManagerService;->unbindCurrentClientLocked(I)V
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
index 1eaa59a..b09cb00 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
@@ -251,7 +251,7 @@
 
         final CountDownLatch latch = new CountDownLatch(1);
         mService.calculateScore(algorithm, value1, value2, new RemoteCallback((result) -> {
-            final Scores scores = result.getParcelable(EXTRA_SCORES);
+            final Scores scores = result.getParcelable(EXTRA_SCORES, android.service.autofill.AutofillFieldClassificationService.Scores.class);
             if (scores == null) {
                 pw.println("no score");
             } else {
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 9f98461..1fea539 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -395,7 +395,7 @@
                     Slog.v(TAG, "mDelayedFillBroadcastReceiver delayed fill action received");
                     synchronized (mLock) {
                         int requestId = intent.getIntExtra(EXTRA_REQUEST_ID, 0);
-                        FillResponse response = intent.getParcelableExtra(EXTRA_FILL_RESPONSE);
+                        FillResponse response = intent.getParcelableExtra(EXTRA_FILL_RESPONSE, android.service.autofill.FillResponse.class);
                         mAssistReceiver.processDelayedFillLocked(requestId, response);
                     }
                 }
@@ -559,7 +559,7 @@
                 return;
             }
 
-            final AssistStructure structure = resultData.getParcelable(ASSIST_KEY_STRUCTURE);
+            final AssistStructure structure = resultData.getParcelable(ASSIST_KEY_STRUCTURE, android.app.assist.AssistStructure.class);
             if (structure == null) {
                 Slog.e(TAG, "No assist structure - app might have crashed providing it");
                 return;
@@ -1811,7 +1811,7 @@
     @GuardedBy("mLock")
     void setAuthenticationResultForAugmentedAutofillLocked(Bundle data, int authId) {
         final Dataset dataset = (data == null) ? null :
-                data.getParcelable(AutofillManager.EXTRA_AUTHENTICATION_RESULT);
+                data.getParcelable(AutofillManager.EXTRA_AUTHENTICATION_RESULT, android.service.autofill.Dataset.class);
         if (sDebug) {
             Slog.d(TAG, "Auth result for augmented autofill: sessionId=" + id
                     + ", authId=" + authId + ", dataset=" + dataset);
@@ -2251,7 +2251,7 @@
                 logContextCommitted(null, null, saveDialogNotShowReason, commitReason);
                 return;
             }
-            final Scores scores = result.getParcelable(EXTRA_SCORES);
+            final Scores scores = result.getParcelable(EXTRA_SCORES, android.service.autofill.AutofillFieldClassificationService.Scores.class);
             if (scores == null) {
                 Slog.w(TAG, "No field classification score on " + result);
                 return;
diff --git a/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java b/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java
index 5457ef9..b3314ed 100644
--- a/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java
+++ b/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java
@@ -300,10 +300,10 @@
                 return;
             }
 
-            final AssociationRequest request = data.getParcelable(EXTRA_ASSOCIATION_REQUEST);
+            final AssociationRequest request = data.getParcelable(EXTRA_ASSOCIATION_REQUEST, android.companion.AssociationRequest.class);
             final IAssociationRequestCallback callback = IAssociationRequestCallback.Stub
                     .asInterface(data.getBinder(EXTRA_APPLICATION_CALLBACK));
-            final ResultReceiver resultReceiver = data.getParcelable(EXTRA_RESULT_RECEIVER);
+            final ResultReceiver resultReceiver = data.getParcelable(EXTRA_RESULT_RECEIVER, android.os.ResultReceiver.class);
 
             requireNonNull(request);
             requireNonNull(callback);
@@ -313,7 +313,7 @@
             if (request.isSelfManaged()) {
                 macAddress = null;
             } else {
-                macAddress = data.getParcelable(EXTRA_MAC_ADDRESS);
+                macAddress = data.getParcelable(EXTRA_MAC_ADDRESS, android.net.MacAddress.class);
                 requireNonNull(macAddress);
             }
 
diff --git a/services/companion/java/com/android/server/companion/PackageUtils.java b/services/companion/java/com/android/server/companion/PackageUtils.java
index 622396cc..9bad45b 100644
--- a/services/companion/java/com/android/server/companion/PackageUtils.java
+++ b/services/companion/java/com/android/server/companion/PackageUtils.java
@@ -30,6 +30,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.FeatureInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.PackageInfoFlags;
@@ -39,8 +40,6 @@
 import android.os.Binder;
 import android.util.Slog;
 
-import com.android.internal.util.ArrayUtils;
-
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -65,15 +64,20 @@
 
     static void enforceUsesCompanionDeviceFeature(@NonNull Context context,
             @UserIdInt int userId, @NonNull String packageName) {
-        final boolean requested = ArrayUtils.contains(
-                getPackageInfo(context, userId, packageName).reqFeatures,
-                FEATURE_COMPANION_DEVICE_SETUP);
+        String requiredFeature = FEATURE_COMPANION_DEVICE_SETUP;
 
-        if (requested) {
-            throw new IllegalStateException("Must declare uses-feature "
-                    + FEATURE_COMPANION_DEVICE_SETUP
-                    + " in manifest to use this API");
+        FeatureInfo[] requestedFeatures = getPackageInfo(context, userId, packageName).reqFeatures;
+        if (requestedFeatures != null) {
+            for (int i = 0; i < requestedFeatures.length; i++) {
+                if (requiredFeature.equals(requestedFeatures[i].name)) {
+                    return;
+                }
+            }
         }
+
+        throw new IllegalStateException("Must declare uses-feature "
+                + requiredFeature
+                + " in manifest to use this API");
     }
 
     /**
diff --git a/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java
index 88ebb97..be81b67 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java
@@ -182,7 +182,11 @@
             }
         }
         if (!hasConsented) {
-            Slog.e(LOG_TAG, "User " + userId + " hasn't consented permission sync.");
+            String message = "User " + userId + " hasn't consented permission sync.";
+            Slog.e(LOG_TAG, message);
+            try {
+                callback.onError(message);
+            } catch (RemoteException ignored) { }
             return;
         }
 
diff --git a/services/contentcapture/Android.bp b/services/contentcapture/Android.bp
index 434f239..5392c2c 100644
--- a/services/contentcapture/Android.bp
+++ b/services/contentcapture/Android.bp
@@ -17,6 +17,9 @@
 java_library_static {
     name: "services.contentcapture",
     defaults: ["platform_service_defaults"],
-    srcs: [":services.contentcapture-sources"],
+    srcs: [
+        ":services.contentcapture-sources",
+        "java/**/*.logtags",
+    ],
     libs: ["services.core"],
 }
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
index 41a7592..1ca68d7 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
@@ -60,6 +60,7 @@
 import android.service.voice.VoiceInteractionManagerInternal;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.EventLog;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
@@ -88,6 +89,11 @@
 
     private static final String TAG = ContentCapturePerUserService.class.getSimpleName();
 
+    private static final int EVENT_LOG_CONNECT_STATE_DIED = 0;
+    static final int EVENT_LOG_CONNECT_STATE_CONNECTED = 1;
+    static final int EVENT_LOG_CONNECT_STATE_DISCONNECTED = 2;
+
+
     @GuardedBy("mLock")
     private final SparseArray<ContentCaptureServerSession> mSessions = new SparseArray<>();
 
@@ -190,9 +196,13 @@
         Slog.w(TAG, "remote service died: " + service);
         synchronized (mLock) {
             mZombie = true;
+            ComponentName serviceComponent = getServiceComponentName();
             writeServiceEvent(
                     FrameworkStatsLog.CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__ON_REMOTE_SERVICE_DIED,
-                    getServiceComponentName());
+                    serviceComponent);
+            EventLog.writeEvent(EventLogTags.CC_CONNECT_STATE_CHANGED, mUserId,
+                    serviceComponent != null ? serviceComponent.flattenToShortString() : "",
+                    EVENT_LOG_CONNECT_STATE_DIED);
         }
     }
 
@@ -446,8 +456,8 @@
             @NonNull Bundle data) {
         final int id = getSessionId(activityToken);
         final Bundle assistData = data.getBundle(ASSIST_KEY_DATA);
-        final AssistStructure assistStructure = data.getParcelable(ASSIST_KEY_STRUCTURE);
-        final AssistContent assistContent = data.getParcelable(ASSIST_KEY_CONTENT);
+        final AssistStructure assistStructure = data.getParcelable(ASSIST_KEY_STRUCTURE, android.app.assist.AssistStructure.class);
+        final AssistContent assistContent = data.getParcelable(ASSIST_KEY_CONTENT, android.app.assist.AssistContent.class);
         final SnapshotData snapshotData = new SnapshotData(assistData,
                 assistStructure, assistContent);
         if (id != NO_SESSION_ID) {
@@ -614,11 +624,16 @@
                         ? "null_activities" : activities.size() + " activities") + ")"
                         + " for user " + mUserId);
             }
+            int packageCount = packages != null ? packages.size() : 0;
+            int activityCount = activities != null ? activities.size() : 0;
 
             ArraySet<String> oldList =
                     mMaster.mGlobalContentCaptureOptions.getWhitelistedPackages(mUserId);
+            EventLog.writeEvent(EventLogTags.CC_CURRENT_ALLOWLIST, mUserId, oldList.size());
 
             mMaster.mGlobalContentCaptureOptions.setWhitelist(mUserId, packages, activities);
+            EventLog.writeEvent(EventLogTags.CC_SET_ALLOWLIST, mUserId,
+                    packageCount, activityCount);
             writeSetWhitelistEvent(getServiceComponentName(), packages, activities);
 
             updateContentCaptureOptions(oldList);
@@ -699,12 +714,14 @@
         private void updateContentCaptureOptions(@Nullable ArraySet<String> oldList) {
             ArraySet<String> adding = mMaster.mGlobalContentCaptureOptions
                     .getWhitelistedPackages(mUserId);
+            EventLog.writeEvent(EventLogTags.CC_CURRENT_ALLOWLIST, mUserId, adding.size());
 
             if (oldList != null && adding != null) {
                 adding.removeAll(oldList);
             }
 
             int N = adding != null ? adding.size() : 0;
+            EventLog.writeEvent(EventLogTags.CC_UPDATE_OPTIONS, mUserId, N);
             for (int i = 0; i < N; i++) {
                 String packageName = adding.valueAt(i);
                 ContentCaptureOptions options = mMaster.mGlobalContentCaptureOptions
diff --git a/services/contentcapture/java/com/android/server/contentcapture/EventLogTags.logtags b/services/contentcapture/java/com/android/server/contentcapture/EventLogTags.logtags
new file mode 100644
index 0000000..6722b9e
--- /dev/null
+++ b/services/contentcapture/java/com/android/server/contentcapture/EventLogTags.logtags
@@ -0,0 +1,8 @@
+# See system/logging/logcat/event.logtags for a description of the format of this file.
+
+option java_package com.android.server.contentcapture
+
+53200 cc_connect_state_changed (User|1|5),(component|3),(type|1)
+53201 cc_set_allowlist (User|1|5),(package_count|1),(activity_count|1)
+53202 cc_current_allowlist (User|1|5),(count|1)
+53203 cc_update_options (User|1|5),(count|1)
diff --git a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
index 1efe55a..e22a9d0 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
@@ -31,6 +31,7 @@
 import android.service.contentcapture.IContentCaptureServiceCallback;
 import android.service.contentcapture.IDataShareCallback;
 import android.service.contentcapture.SnapshotData;
+import android.util.EventLog;
 import android.util.Slog;
 import android.view.contentcapture.ContentCaptureContext;
 import android.view.contentcapture.DataRemovalRequest;
@@ -47,6 +48,7 @@
     private final IBinder mServerCallback;
     private final int mIdleUnbindTimeoutMs;
     private final ContentCapturePerUserService mPerUserService;
+    private final int mUserId;
 
     RemoteContentCaptureService(Context context, String serviceInterface,
             ComponentName serviceComponentName, IContentCaptureServiceCallback callback, int userId,
@@ -61,6 +63,7 @@
         mPerUserService = perUserService;
         mServerCallback = callback.asBinder();
         mIdleUnbindTimeoutMs = idleUnbindTimeoutMs;
+        mUserId = userId;
 
         // Bind right away, which will trigger a onConnected() on service's
         ensureBoundLocked();
@@ -88,6 +91,9 @@
                     writeServiceEvent(
                             FrameworkStatsLog.CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__ON_CONNECTED,
                             mComponentName);
+                    EventLog.writeEvent(EventLogTags.CC_CONNECT_STATE_CHANGED, mUserId,
+                            mComponentName != null ? mComponentName.flattenToShortString() : "",
+                            ContentCapturePerUserService.EVENT_LOG_CONNECT_STATE_CONNECTED);
                 } finally {
                     // Update the system-service state, in case the service reconnected after
                     // dying
@@ -98,6 +104,9 @@
                 writeServiceEvent(
                         FrameworkStatsLog.CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__ON_DISCONNECTED,
                         mComponentName);
+                EventLog.writeEvent(EventLogTags.CC_CONNECT_STATE_CHANGED, mUserId,
+                        mComponentName != null ? mComponentName.flattenToShortString() : "",
+                        ContentCapturePerUserService.EVENT_LOG_CONNECT_STATE_DISCONNECTED);
             }
         } catch (Exception e) {
             Slog.w(mTag, "Exception calling onConnectedStateChanged(" + connected + "): " + e);
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index 6063668..9758204 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -503,12 +503,6 @@
     public abstract void pruneInstantApps();
 
     /**
-     * Prunes the cache of the APKs in the given APEXes.
-     * @param apexPackageNames The list of APEX package names that may contain APK-in-APEX.
-     */
-    public abstract void pruneCachedApksInApex(@NonNull List<String> apexPackageNames);
-
-    /**
      * @return The SetupWizard package name.
      */
     public abstract String getSetupWizardPackageName();
diff --git a/services/core/java/com/android/server/ExplicitHealthCheckController.java b/services/core/java/com/android/server/ExplicitHealthCheckController.java
index 77059d9..20de40e 100644
--- a/services/core/java/com/android/server/ExplicitHealthCheckController.java
+++ b/services/core/java/com/android/server/ExplicitHealthCheckController.java
@@ -246,7 +246,7 @@
             try {
                 mRemoteService.getSupportedPackages(new RemoteCallback(result -> {
                     List<PackageConfig> packages =
-                            result.getParcelableArrayList(EXTRA_SUPPORTED_PACKAGES);
+                            result.getParcelableArrayList(EXTRA_SUPPORTED_PACKAGES, android.service.watchdog.ExplicitHealthCheckService.PackageConfig.class);
                     Slog.i(TAG, "Explicit health check supported packages " + packages);
                     consumer.accept(packages);
                 }));
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index ce3502c..83e3b49 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -351,6 +351,10 @@
     private static final float DEFAULT_LOW_BATTERY_LEVEL = 20F;
     // Decide whether charging is required to turn on the feature
     private static final boolean DEFAULT_CHARGING_REQUIRED = true;
+    // Minimum GC interval sleep time in ms
+    private static final int DEFAULT_MIN_GC_SLEEPTIME = 10000;
+    // Target dirty segment ratio to aim to
+    private static final int DEFAULT_TARGET_DIRTY_RATIO = 80;
 
     private volatile int mLifetimePercentThreshold;
     private volatile int mMinSegmentsThreshold;
@@ -358,6 +362,8 @@
     private volatile float mSegmentReclaimWeight;
     private volatile float mLowBatteryLevel;
     private volatile boolean mChargingRequired;
+    private volatile int mMinGCSleepTime;
+    private volatile int mTargetDirtyRatio;
     private volatile boolean mNeedGC;
 
     private volatile boolean mPassedLifetimeThresh;
@@ -1245,10 +1251,10 @@
         mHandler.sendMessage(mHandler.obtainMessage(H_FSTRIM, callback));
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
     // Binder entry point for kicking off an immediate fstrim
     @Override
     public void runMaintenance() {
-        enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
         runIdleMaintenance(null);
     }
 
@@ -2162,17 +2168,17 @@
         mCallbacks.unregister(listener);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.SHUTDOWN)
     @Override
     public void shutdown(final IStorageShutdownObserver observer) {
-        enforcePermission(android.Manifest.permission.SHUTDOWN);
 
         Slog.i(TAG, "Shutting down");
         mHandler.obtainMessage(H_SHUTDOWN, observer).sendToTarget();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
     @Override
     public void mount(String volId) {
-        enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
 
         final VolumeInfo vol = findVolumeByIdOrThrow(volId);
         if (isMountDisallowed(vol)) {
@@ -2238,9 +2244,9 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
     @Override
     public void unmount(String volId) {
-        enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
 
         final VolumeInfo vol = findVolumeByIdOrThrow(volId);
         unmount(vol);
@@ -2262,9 +2268,9 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS)
     @Override
     public void format(String volId) {
-        enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
 
         final VolumeInfo vol = findVolumeByIdOrThrow(volId);
         final String fsUuid = vol.fsUuid;
@@ -2281,9 +2287,9 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS)
     @Override
     public void benchmark(String volId, IVoldTaskListener listener) {
-        enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
 
         try {
             mVold.benchmark(volId, new IVoldTaskListener.Stub() {
@@ -2320,9 +2326,9 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS)
     @Override
     public void partitionPublic(String diskId) {
-        enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
 
         final CountDownLatch latch = findOrCreateDiskScanLatch(diskId);
         try {
@@ -2333,9 +2339,9 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS)
     @Override
     public void partitionPrivate(String diskId) {
-        enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
         enforceAdminUser();
 
         final CountDownLatch latch = findOrCreateDiskScanLatch(diskId);
@@ -2347,9 +2353,9 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS)
     @Override
     public void partitionMixed(String diskId, int ratio) {
-        enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
         enforceAdminUser();
 
         final CountDownLatch latch = findOrCreateDiskScanLatch(diskId);
@@ -2361,9 +2367,9 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
     @Override
     public void setVolumeNickname(String fsUuid, String nickname) {
-        enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
 
         Objects.requireNonNull(fsUuid);
         synchronized (mLock) {
@@ -2374,9 +2380,9 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
     @Override
     public void setVolumeUserFlags(String fsUuid, int flags, int mask) {
-        enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
 
         Objects.requireNonNull(fsUuid);
         synchronized (mLock) {
@@ -2387,9 +2393,9 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
     @Override
     public void forgetVolume(String fsUuid) {
-        enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
 
         Objects.requireNonNull(fsUuid);
 
@@ -2411,9 +2417,9 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
     @Override
     public void forgetAllVolumes() {
-        enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
 
         synchronized (mLock) {
             for (int i = 0; i < mRecords.size(); i++) {
@@ -2443,9 +2449,9 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS)
     @Override
     public void fstrim(int flags, IVoldTaskListener listener) {
-        enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
 
         try {
             // Block based checkpoint process runs fstrim. So, if checkpoint is in progress
@@ -2576,6 +2582,10 @@
                 "low_battery_level", DEFAULT_LOW_BATTERY_LEVEL);
             mChargingRequired = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
                 "charging_required", DEFAULT_CHARGING_REQUIRED);
+            mMinGCSleepTime = DeviceConfig.getInt(DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
+                "min_gc_sleeptime", DEFAULT_MIN_GC_SLEEPTIME);
+            mTargetDirtyRatio = DeviceConfig.getInt(DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
+                "target_dirty_ratio", DEFAULT_TARGET_DIRTY_RATIO);
 
             // If we use the smart idle maintenance, we need to turn off GC in the traditional idle
             // maintenance to avoid the conflict
@@ -2693,6 +2703,14 @@
         enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
 
         try {
+            int latestWrite = mVold.getWriteAmount();
+            if (latestWrite == -1) {
+                Slog.w(TAG, "Failed to get storage write record");
+                return;
+            }
+
+            updateStorageWriteRecords(latestWrite);
+
             // Block based checkpoint process runs fstrim. So, if checkpoint is in progress
             // (first boot after OTA), We skip the smart idle maintenance
             if (!needsCheckpoint() || !supportsBlockCheckpoint()) {
@@ -2700,13 +2718,6 @@
                     return;
                 }
 
-                int latestWrite = mVold.getWriteAmount();
-                if (latestWrite == -1) {
-                    Slog.w(TAG, "Failed to get storage write record");
-                    return;
-                }
-
-                updateStorageWriteRecords(latestWrite);
                 int avgWriteAmount = getAverageWriteAmount();
 
                 Slog.i(TAG, "Set smart idle maintenance: " + "latest write amount: " +
@@ -2714,9 +2725,12 @@
                             ", min segment threshold: " + mMinSegmentsThreshold +
                             ", dirty reclaim rate: " + mDirtyReclaimRate +
                             ", segment reclaim weight: " + mSegmentReclaimWeight +
-                            ", period: " + sSmartIdleMaintPeriod);
+                            ", period(min): " + sSmartIdleMaintPeriod +
+                            ", min gc sleep time(ms): " + mMinGCSleepTime +
+                            ", target dirty ratio: " + mTargetDirtyRatio);
                 mVold.setGCUrgentPace(avgWriteAmount, mMinSegmentsThreshold, mDirtyReclaimRate,
-                                      mSegmentReclaimWeight, sSmartIdleMaintPeriod);
+                                      mSegmentReclaimWeight, sSmartIdleMaintPeriod,
+                                      mMinGCSleepTime, mTargetDirtyRatio);
             } else {
                 Slog.i(TAG, "Skipping smart idle maintenance - block based checkpoint in progress");
             }
@@ -2729,9 +2743,9 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
     @Override
     public void setDebugFlags(int flags, int mask) {
-        enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
 
         if ((mask & (StorageManager.DEBUG_ADOPTABLE_FORCE_ON
                 | StorageManager.DEBUG_ADOPTABLE_FORCE_OFF)) != 0) {
@@ -2799,9 +2813,9 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
     @Override
     public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback) {
-        enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
 
         final VolumeInfo from;
         final VolumeInfo to;
@@ -3005,12 +3019,12 @@
         mVold.commitChanges();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS)
     /**
      * Check if we should be mounting with checkpointing or are checkpointing now
      */
     @Override
     public boolean needsCheckpoint() throws RemoteException {
-        enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
         return mVold.needsCheckpoint();
     }
 
@@ -3027,9 +3041,9 @@
         mVold.abortChanges(message, retry);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
     @Override
     public void createUserKey(int userId, int serialNumber, boolean ephemeral) {
-        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
 
         try {
             mVold.createUserKey(userId, serialNumber, ephemeral);
@@ -3038,9 +3052,9 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
     @Override
     public void destroyUserKey(int userId) {
-        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
 
         try {
             mVold.destroyUserKey(userId);
@@ -3057,6 +3071,7 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
     /*
      * Add this secret to the set of ways we can recover a user's disk
      * encryption key.  Changing the secret for a disk encryption key is done in
@@ -3067,7 +3082,6 @@
      */
     @Override
     public void addUserKeyAuth(int userId, int serialNumber, byte[] secret) {
-        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
 
         try {
             mVold.addUserKeyAuth(userId, serialNumber, encodeBytes(secret));
@@ -3076,6 +3090,7 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
     /*
      * Store a user's disk encryption key without secret binding.  Removing the
      * secret for a disk encryption key is done in two phases.  First, this
@@ -3085,7 +3100,6 @@
      */
     @Override
     public void clearUserKeyAuth(int userId, int serialNumber, byte[] secret) {
-        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
 
         try {
             mVold.clearUserKeyAuth(userId, serialNumber, encodeBytes(secret));
@@ -3094,13 +3108,13 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
     /*
      * Delete all bindings of a user's disk encryption key except the most
      * recently added one.
      */
     @Override
     public void fixateNewestUserKeyAuth(int userId) {
-        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
 
         try {
             mVold.fixateNewestUserKeyAuth(userId);
@@ -3144,6 +3158,7 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
     @Override
     public void lockUserKey(int userId) {
         //  Do not lock user 0 data for headless system user
@@ -3152,7 +3167,6 @@
             throw new IllegalArgumentException("Headless system user data cannot be locked..");
         }
 
-        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
 
         if (!isUserKeyUnlocked(userId)) {
             Slog.d(TAG, "User " + userId + "'s CE storage is already locked");
@@ -3207,9 +3221,9 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
     @Override
     public void prepareUserStorage(String volumeUuid, int userId, int serialNumber, int flags) {
-        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
 
         try {
             prepareUserStorageInternal(volumeUuid, userId, serialNumber, flags);
@@ -3250,9 +3264,9 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
     @Override
     public void destroyUserStorage(String volumeUuid, int userId, int flags) {
-        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
 
         try {
             mVold.destroyUserStorage(volumeUuid, userId, flags);
@@ -4297,9 +4311,9 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.WRITE_MEDIA_STORAGE)
     @Override
     public int getExternalStorageMountMode(int uid, String packageName) {
-        enforcePermission(android.Manifest.permission.WRITE_MEDIA_STORAGE);
         return mStorageManagerInternal.getExternalStorageMountMode(uid, packageName);
     }
 
diff --git a/services/core/java/com/android/server/VpnManagerService.java b/services/core/java/com/android/server/VpnManagerService.java
index 07b6843..c9a420e 100644
--- a/services/core/java/com/android/server/VpnManagerService.java
+++ b/services/core/java/com/android/server/VpnManagerService.java
@@ -769,8 +769,7 @@
         }
     };
 
-    @VisibleForTesting
-    void onUserStarted(int userId) {
+    private void onUserStarted(int userId) {
         synchronized (mVpns) {
             Vpn userVpn = mVpns.get(userId);
             if (userVpn != null) {
@@ -854,8 +853,7 @@
         }
     }
 
-    @VisibleForTesting
-    void onPackageRemoved(String packageName, int uid, boolean isReplacing) {
+    private void onPackageRemoved(String packageName, int uid, boolean isReplacing) {
         if (TextUtils.isEmpty(packageName) || uid < 0) {
             Log.wtf(TAG, "Invalid package in onPackageRemoved: " + packageName + " | " + uid);
             return;
@@ -878,8 +876,7 @@
         }
     }
 
-    @VisibleForTesting
-    void onPackageAdded(String packageName, int uid, boolean isReplacing) {
+    private void onPackageAdded(String packageName, int uid, boolean isReplacing) {
         if (TextUtils.isEmpty(packageName) || uid < 0) {
             Log.wtf(TAG, "Invalid package in onPackageAdded: " + packageName + " | " + uid);
             return;
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 76c897a..ef784bb 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -160,6 +160,7 @@
     public static final String[] AIDL_INTERFACE_PREFIXES_OF_INTEREST = new String[] {
             "android.hardware.biometrics.face.IFace/",
             "android.hardware.biometrics.fingerprint.IFingerprint/",
+            "android.hardware.input.processor.IInputProcessor/",
             "android.hardware.light.ILights/",
             "android.hardware.power.IPower/",
             "android.hardware.power.stats.IPowerStats/",
@@ -230,10 +231,10 @@
         private final String mName;
         private final ArrayList<Monitor> mMonitors = new ArrayList<Monitor>();
         private final ArrayList<Monitor> mMonitorQueue = new ArrayList<Monitor>();
-        private long mWaitMax;
+        private long mWaitMaxMillis;
         private boolean mCompleted;
         private Monitor mCurrentMonitor;
-        private long mStartTime;
+        private long mStartTimeMillis;
         private int mPauseCount;
 
         HandlerChecker(Handler handler, String name) {
@@ -254,7 +255,7 @@
          * @param handlerCheckerTimeoutMillis the timeout to use for this run
          */
         public void scheduleCheckLocked(long handlerCheckerTimeoutMillis) {
-            mWaitMax = handlerCheckerTimeoutMillis;
+            mWaitMaxMillis = handlerCheckerTimeoutMillis;
             if (mCompleted) {
                 // Safe to update monitors in queue, Handler is not in the middle of work
                 mMonitors.addAll(mMonitorQueue);
@@ -279,7 +280,7 @@
 
             mCompleted = false;
             mCurrentMonitor = null;
-            mStartTime = SystemClock.uptimeMillis();
+            mStartTimeMillis = SystemClock.uptimeMillis();
             mHandler.postAtFrontOfQueue(this);
         }
 
@@ -287,10 +288,10 @@
             if (mCompleted) {
                 return COMPLETED;
             } else {
-                long latency = SystemClock.uptimeMillis() - mStartTime;
-                if (latency < mWaitMax/2) {
+                long latency = SystemClock.uptimeMillis() - mStartTimeMillis;
+                if (latency < mWaitMaxMillis / 2) {
                     return WAITING;
-                } else if (latency < mWaitMax) {
+                } else if (latency < mWaitMaxMillis) {
                     return WAITED_HALF;
                 }
             }
@@ -306,14 +307,17 @@
         }
 
         String describeBlockedStateLocked() {
+            final String prefix;
+            if (mCurrentMonitor == null) {
+                prefix = "Blocked in handler on ";
+            } else {
+                prefix =  "Blocked in monitor " + mCurrentMonitor.getClass().getName();
+            }
             Thread thread = getThread();
             String threadIdentifier = thread.getName() + ", tid=" + thread.getId();
-            if (mCurrentMonitor == null) {
-                return "Blocked in handler on " + mName + " (" + threadIdentifier + ")";
-            } else {
-                return "Blocked in monitor " + mCurrentMonitor.getClass().getName()
-                        + " on " + mName + " (" + threadIdentifier + ")";
-            }
+            long latencySeconds = (SystemClock.uptimeMillis() - mStartTimeMillis) / 1000;
+            return prefix + " on " + mName + " (" + threadIdentifier + ")"
+                + " for " + latencySeconds + "s";
         }
 
         @Override
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 6b731c3..eb0f3f0 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -3090,7 +3090,7 @@
                             }
                         }
 
-                        Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
+                        Intent intent = result.getParcelable(AccountManager.KEY_INTENT, android.content.Intent.class);
                         if (intent != null && notifyOnAuthFailure && !customTokens) {
                             /*
                              * Make sure that the supplied intent is owned by the authenticator
@@ -3516,7 +3516,7 @@
             mNumResults++;
             Intent intent = null;
             if (result != null
-                    && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) {
+                    && (intent = result.getParcelable(AccountManager.KEY_INTENT, android.content.Intent.class)) != null) {
                 if (!checkKeyIntent(
                         Binder.getCallingUid(),
                         intent)) {
@@ -5048,7 +5048,7 @@
                 }
             }
             if (result != null
-                    && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) {
+                    && (intent = result.getParcelable(AccountManager.KEY_INTENT, android.content.Intent.class)) != null) {
                 if (!checkKeyIntent(
                         Binder.getCallingUid(),
                         intent)) {
diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
index 049f4be..2eaf323 100644
--- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java
+++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
@@ -649,7 +649,7 @@
                 } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
                     // We only care about wifi type connections
                     NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra(
-                            WifiManager.EXTRA_NETWORK_INFO);
+                            WifiManager.EXTRA_NETWORK_INFO, android.net.NetworkInfo.class);
                     if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
                         // Check for network disconnect
                         if (!networkInfo.isConnected()) {
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 8368b4d..c5b5fb9 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -140,6 +140,7 @@
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.os.Trace;
 import android.os.TransactionTooLargeException;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -2855,6 +2856,14 @@
             return -1;
         }
         ServiceRecord s = res.record;
+        final AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
+        final ProcessServiceRecord clientPsr = b.client.mServices;
+        if (clientPsr.numberOfConnections() >= mAm.mConstants.mMaxServiceConnectionsPerProcess) {
+            Slog.w(TAG, "bindService exceeded max service connection number per process, "
+                    + "callerApp:" + callerApp.processName
+                    + " intent:" + service);
+            return 0;
+        }
 
         // The package could be frozen (meaning it's doing surgery), defer the actual
         // binding until the package is unfrozen.
@@ -2905,7 +2914,6 @@
             mAm.grantImplicitAccess(callerApp.userId, service,
                     callerApp.uid, UserHandle.getAppId(s.appInfo.uid));
 
-            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
             ConnectionRecord c = new ConnectionRecord(b, activity,
                     connection, flags, clientLabel, clientIntent,
                     callerApp.uid, callerApp.processName, callingPackage, res.aliasComponent);
@@ -2916,7 +2924,6 @@
             if (activity != null) {
                 activity.addConnection(c);
             }
-            final ProcessServiceRecord clientPsr = b.client.mServices;
             clientPsr.addConnection(c);
             c.startAssociationIfNeeded();
             if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
@@ -3157,8 +3164,20 @@
             return false;
         }
 
+        final int callingPid = Binder.getCallingPid();
         final long origId = Binder.clearCallingIdentity();
         try {
+            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+                String info;
+                if (clist.size() > 0) {
+                    final ConnectionRecord r = clist.get(0);
+                    info = r.binding.service.shortInstanceName + " from " + r.clientProcessName;
+                } else {
+                    info = Integer.toString(callingPid);
+                }
+                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "unbindServiceLocked: " + info);
+            }
+
             while (clist.size() > 0) {
                 ConnectionRecord r = clist.get(0);
                 removeConnectionLocked(r, null, null, true);
@@ -3186,6 +3205,7 @@
             mAm.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
 
         } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
             Binder.restoreCallingIdentity(origId);
         }
 
@@ -4149,6 +4169,22 @@
             boolean whileRestarting, boolean permissionsReviewRequired, boolean packageFrozen,
             boolean enqueueOomAdj)
             throws TransactionTooLargeException {
+        try {
+            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                        "bringUpServiceLocked: " + r.shortInstanceName);
+            }
+            return bringUpServiceInnerLocked(r, intentFlags, execInFg, whileRestarting,
+                    permissionsReviewRequired, packageFrozen, enqueueOomAdj);
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+        }
+    }
+
+    private String bringUpServiceInnerLocked(ServiceRecord r, int intentFlags, boolean execInFg,
+            boolean whileRestarting, boolean permissionsReviewRequired, boolean packageFrozen,
+            boolean enqueueOomAdj)
+            throws TransactionTooLargeException {
         if (r.app != null && r.app.getThread() != null) {
             sendServiceArgsLocked(r, execInFg, false);
             return null;
@@ -4223,6 +4259,10 @@
                 final UidRecord uidRecord = app.getUidRecord();
                 if (thread != null) {
                     try {
+                        if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+                            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                                    "realStartServiceLocked: " + r.shortInstanceName);
+                        }
                         app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode,
                                 mAm.mProcessStats);
                         realStartServiceLocked(r, app, thread, pid, uidRecord, execInFg,
@@ -4232,6 +4272,8 @@
                         throw e;
                     } catch (RemoteException e) {
                         Slog.w(TAG, "Exception when starting service " + r.shortInstanceName, e);
+                    } finally {
+                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     }
 
                     // If a dead object exception was thrown -- fall through to
@@ -5109,8 +5151,16 @@
                     i--;
                     proc.addPackage(sr.appInfo.packageName, sr.appInfo.longVersionCode,
                             mAm.mProcessStats);
-                    realStartServiceLocked(sr, proc, thread, pid, uidRecord, sr.createdFromFg,
-                            true);
+                    try {
+                        if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+                            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                                    "realStartServiceLocked: " + sr.shortInstanceName);
+                        }
+                        realStartServiceLocked(sr, proc, thread, pid, uidRecord, sr.createdFromFg,
+                                true);
+                    } finally {
+                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+                    }
                     didSomething = true;
                     if (!isServiceNeededLocked(sr, false, false)) {
                         // We were waiting for this service to start, but it is actually no
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index c372096..13a13f2 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -196,6 +196,8 @@
     static final long DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME_MS = 60 * 1000;
     static final boolean DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE = true;
 
+    static final int DEFAULT_MAX_SERVICE_CONNECTIONS_PER_PROCESS = 3000;
+
     /**
      * Same as {@link TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED}
      */
@@ -335,6 +337,9 @@
     private static final String KEY_SERVICE_BIND_ALMOST_PERCEPTIBLE_TIMEOUT_MS =
             "service_bind_almost_perceptible_timeout_ms";
 
+    private static final String KEY_MAX_SERVICE_CONNECTIONS_PER_PROCESS =
+            "max_service_connections_per_process";
+
     // Maximum number of cached processes we will allow.
     public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES;
 
@@ -687,6 +692,12 @@
      */
     volatile String mComponentAliasOverrides = DEFAULT_COMPONENT_ALIAS_OVERRIDES;
 
+    /**
+     *  The max number of outgoing ServiceConnection a process is allowed to bind to a service
+     *  (or multiple services).
+     */
+    volatile int mMaxServiceConnectionsPerProcess = DEFAULT_MAX_SERVICE_CONNECTIONS_PER_PROCESS;
+
     private final ActivityManagerService mService;
     private ContentResolver mResolver;
     private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -990,6 +1001,9 @@
                             case KEY_NETWORK_ACCESS_TIMEOUT_MS:
                                 updateNetworkAccessTimeoutMs();
                                 break;
+                            case KEY_MAX_SERVICE_CONNECTIONS_PER_PROCESS:
+                                updateMaxServiceConnectionsPerProcess();
+                                break;
                             default:
                                 break;
                         }
@@ -1633,6 +1647,13 @@
         }
     }
 
+    private void updateMaxServiceConnectionsPerProcess() {
+        mMaxServiceConnectionsPerProcess = DeviceConfig.getInt(
+                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                KEY_MAX_SERVICE_CONNECTIONS_PER_PROCESS,
+                DEFAULT_MAX_SERVICE_CONNECTIONS_PER_PROCESS);
+    }
+
     @NeverCompile // Avoid size overhead of debugging code.
     void dump(PrintWriter pw) {
         pw.println("ACTIVITY MANAGER SETTINGS (dumpsys activity settings) "
@@ -1779,6 +1800,8 @@
         pw.print("="); pw.println(mServiceBindAlmostPerceptibleTimeoutMs);
         pw.print("  "); pw.print(KEY_NETWORK_ACCESS_TIMEOUT_MS);
         pw.print("="); pw.println(mNetworkAccessTimeoutMs);
+        pw.print("  "); pw.print(KEY_MAX_SERVICE_CONNECTIONS_PER_PROCESS);
+        pw.print("="); pw.println(mMaxServiceConnectionsPerProcess);
 
         pw.println();
         if (mOverrideMaxCachedProcesses >= 0) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 60286be..9f0aeec 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -8858,6 +8858,10 @@
 
         // Do the rest in a worker thread to avoid blocking the caller on I/O
         // (After this point, we shouldn't access AMS internal data structures.)
+        //
+        // If process is null, we are being called from some internal code
+        // and may be about to die -- run this synchronously.
+        final boolean runSynchronously = process == null;
         Thread worker = new Thread("Error dump: " + dropboxTag) {
             @Override
             public void run() {
@@ -8885,7 +8889,7 @@
                     sb.append(crashInfo.stackTrace);
                 }
 
-                if (lines > 0) {
+                if (lines > 0 && !runSynchronously) {
                     sb.append("\n");
 
                     InputStreamReader input = null;
@@ -8917,9 +8921,7 @@
             }
         };
 
-        if (process == null) {
-            // If process is null, we are being called from some internal code
-            // and may be about to die -- run this synchronously.
+        if (runSynchronously) {
             final int oldMask = StrictMode.allowThreadDiskWritesMask();
             try {
                 worker.run();
@@ -12513,20 +12515,26 @@
 
         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
                 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
-        synchronized(this) {
-            final int callingPid = Binder.getCallingPid();
-            final int callingUid = Binder.getCallingUid();
-            final long origId = Binder.clearCallingIdentity();
-            ComponentName res;
-            try {
+        final int callingPid = Binder.getCallingPid();
+        final int callingUid = Binder.getCallingUid();
+        final long origId = Binder.clearCallingIdentity();
+        ComponentName res;
+        try {
+            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startService: "
+                        + "intent=" + service + ", caller=" + callingPackage
+                        + ", fgRequired=" + requireForeground);
+            }
+            synchronized (this) {
                 res = mServices.startServiceLocked(caller, service,
                         resolvedType, callingPid, callingUid,
                         requireForeground, callingPackage, callingFeatureId, userId);
-            } finally {
-                Binder.restoreCallingIdentity(origId);
             }
-            return res;
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+            Binder.restoreCallingIdentity(origId);
         }
+        return res;
     }
 
     @Override
@@ -12538,8 +12546,15 @@
             throw new IllegalArgumentException("File descriptors passed in Intent");
         }
 
-        synchronized(this) {
-            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
+        try {
+            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "stopService: " + service);
+            }
+            synchronized (this) {
+                return mServices.stopServiceLocked(caller, service, resolvedType, userId);
+            }
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
         }
     }
 
@@ -12563,8 +12578,17 @@
     @Override
     public boolean stopServiceToken(ComponentName className, IBinder token,
             int startId) {
-        synchronized(this) {
-            return mServices.stopServiceTokenLocked(className, token, startId);
+        try {
+            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "stopServiceToken: "
+                        + (className != null ? className.toShortString()
+                        : ("from " + Binder.getCallingPid())));
+            }
+            synchronized (this) {
+                return mServices.stopServiceTokenLocked(className, token, startId);
+            }
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
         }
     }
 
@@ -12712,8 +12736,15 @@
     }
 
     public boolean unbindService(IServiceConnection connection) {
-        synchronized (this) {
-            return mServices.unbindServiceLocked(connection);
+        try {
+            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "unbindService");
+            }
+            synchronized (this) {
+                return mServices.unbindServiceLocked(connection);
+            }
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
         }
     }
 
@@ -14445,6 +14476,19 @@
             final int callingPid = Binder.getCallingPid();
             final int callingUid = Binder.getCallingUid();
 
+            // Non-system callers can't declare that a broadcast is alarm-related.
+            // The PendingIntent invocation case is handled in PendingIntentRecord.
+            if (bOptions != null && callingUid != SYSTEM_UID) {
+                if (bOptions.containsKey(BroadcastOptions.KEY_ALARM_BROADCAST)) {
+                    if (DEBUG_BROADCAST) {
+                        Slog.w(TAG, "Non-system caller " + callingUid
+                                + " may not flag broadcast as alarm-related");
+                    }
+                    throw new SecurityException(
+                            "Non-system callers may not flag broadcasts as alarm-related");
+                }
+            }
+
             final long origId = Binder.clearCallingIdentity();
             try {
                 return broadcastIntentLocked(callerApp,
@@ -14458,6 +14502,7 @@
         }
     }
 
+    // Not the binder call surface
     int broadcastIntentInPackage(String packageName, @Nullable String featureId, int uid,
             int realCallingUid, int realCallingPid, Intent intent, String resolvedType,
             IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras,
@@ -17026,21 +17071,29 @@
                 int userId, boolean allowBackgroundActivityStarts,
                 @Nullable IBinder backgroundActivityStartsToken)
                 throws TransactionTooLargeException {
-            synchronized(ActivityManagerService.this) {
-                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
+            if (DEBUG_SERVICE) {
+                Slog.v(TAG_SERVICE,
                         "startServiceInPackage: " + service + " type=" + resolvedType);
-                final long origId = Binder.clearCallingIdentity();
-                ComponentName res;
-                try {
+            }
+            final long origId = Binder.clearCallingIdentity();
+            ComponentName res;
+            try {
+                if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startServiceInPackage: "
+                            + "intent=" + service + ", caller=" + callingPackage
+                            + ", fgRequired=" + fgRequired);
+                }
+                synchronized (ActivityManagerService.this) {
                     res = mServices.startServiceLocked(null, service,
                             resolvedType, -1, uid, fgRequired, callingPackage,
                             callingFeatureId, userId, allowBackgroundActivityStarts,
                             backgroundActivityStartsToken);
-                } finally {
-                    Binder.restoreCallingIdentity(origId);
                 }
-                return res;
+            } finally {
+                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+                Binder.restoreCallingIdentity(origId);
             }
+            return res;
         }
 
         // The arguments here are untyped because the base ActivityManagerInternal class
@@ -17834,6 +17887,47 @@
     }
 
     /**
+     * Set an app's background restriction level.
+     * This interface is intended for the shell command to use.
+     */
+    void setBackgroundRestrictionLevel(String packageName, int uid, int userId,
+            @RestrictionLevel int level, int reason, int subReason) {
+        final int callingUid = Binder.getCallingUid();
+        if (callingUid != SYSTEM_UID && callingUid != ROOT_UID && callingUid != SHELL_UID) {
+            throw new SecurityException(
+                    "No permission to change app restriction level");
+        }
+        final long callingId = Binder.clearCallingIdentity();
+        try {
+            final int curBucket = mUsageStatsService.getAppStandbyBucket(packageName, userId,
+                    SystemClock.elapsedRealtime());
+            mAppRestrictionController.applyRestrictionLevel(packageName, uid, level,
+                    null /* trackerInfo */, curBucket, true /* allowUpdateBucket */,
+                    reason, subReason);
+        } finally {
+            Binder.restoreCallingIdentity(callingId);
+        }
+    }
+
+    /**
+     * Get an app's background restriction level.
+     * This interface is intended for the shell command to use.
+     */
+    @RestrictionLevel int getBackgroundRestrictionLevel(String packageName, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        if (callingUid != SYSTEM_UID && callingUid != ROOT_UID && callingUid != SHELL_UID) {
+            throw new SecurityException(
+                    "Don't have permission to query app background restriction level");
+        }
+        final long callingId = Binder.clearCallingIdentity();
+        try {
+            return mInternal.getRestrictionLevel(packageName, userId);
+        } finally {
+            Binder.restoreCallingIdentity(callingId);
+        }
+    }
+
+    /**
      * Force the settings cache to be loaded
      */
     void refreshSettingsCache() {
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index a3ae35e..6609d4a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -23,6 +23,10 @@
 import static android.app.WaitResult.launchStateToString;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED_BY_USER;
+import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_UNDEFINED;
+import static android.content.pm.PackageManager.MATCH_ANY_USER;
+import static android.os.Process.INVALID_UID;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED;
 
@@ -350,6 +354,10 @@
                     return runSetBgAbusiveUids(pw);
                 case "list-bg-exemptions-config":
                     return runListBgExemptionsConfig(pw);
+                case "set-bg-restriction-level":
+                    return runSetBgRestrictionLevel(pw);
+                case "get-bg-restriction-level":
+                    return runGetBgRestrictionLevel(pw);
                 default:
                     return handleDefaultCommands(cmd);
             }
@@ -3374,6 +3382,79 @@
         return 0;
     }
 
+    private @ActivityManager.RestrictionLevel int restrictionNameToLevel(String name) {
+        String lower = name.toLowerCase();
+        switch (lower) {
+            case "unrestricted":
+                return ActivityManager.RESTRICTION_LEVEL_UNRESTRICTED;
+            case "exempted":
+                return ActivityManager.RESTRICTION_LEVEL_EXEMPTED;
+            case "adaptive_bucket":
+                return ActivityManager.RESTRICTION_LEVEL_ADAPTIVE_BUCKET;
+            case "restricted_bucket":
+                return ActivityManager.RESTRICTION_LEVEL_RESTRICTED_BUCKET;
+            case "background_restricted":
+                return ActivityManager.RESTRICTION_LEVEL_BACKGROUND_RESTRICTED;
+            case "hibernation":
+                return ActivityManager.RESTRICTION_LEVEL_HIBERNATION;
+            default:
+                return ActivityManager.RESTRICTION_LEVEL_UNKNOWN;
+        }
+    }
+
+    int runSetBgRestrictionLevel(PrintWriter pw) throws RemoteException {
+        int userId = UserHandle.USER_CURRENT;
+
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            if (opt.equals("--user")) {
+                userId = UserHandle.parseUserArg(getNextArgRequired());
+            } else {
+                getErrPrintWriter().println("Error: Unknown option: " + opt);
+                return -1;
+            }
+        }
+        String packageName = getNextArgRequired();
+        final String value = getNextArgRequired();
+        final int level = restrictionNameToLevel(value);
+        if (level == ActivityManager.RESTRICTION_LEVEL_UNKNOWN) {
+            pw.println("Error: invalid restriction level");
+            return -1;
+        }
+
+        int uid = INVALID_UID;
+        try {
+            final PackageManager pm = mInternal.mContext.getPackageManager();
+            uid = pm.getPackageUidAsUser(packageName,
+                    PackageManager.PackageInfoFlags.of(MATCH_ANY_USER), userId);
+        } catch (PackageManager.NameNotFoundException e) {
+            pw.println("Error: userId:" + userId + " package:" + packageName + " is not found");
+            return -1;
+        }
+        mInternal.setBackgroundRestrictionLevel(packageName, uid, userId, level,
+                REASON_MAIN_FORCED_BY_USER, REASON_SUB_FORCED_SYSTEM_FLAG_UNDEFINED);
+        return 0;
+    }
+
+    int runGetBgRestrictionLevel(PrintWriter pw) throws RemoteException {
+        int userId = UserHandle.USER_CURRENT;
+
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            if (opt.equals("--user")) {
+                userId = UserHandle.parseUserArg(getNextArgRequired());
+            } else {
+                getErrPrintWriter().println("Error: Unknown option: " + opt);
+                return -1;
+            }
+        }
+        final String packageName = getNextArgRequired();
+        final @ActivityManager.RestrictionLevel int level =
+                mInternal.getBackgroundRestrictionLevel(packageName, userId);
+        pw.println(ActivityManager.restrictionLevelToName(level));
+        return 0;
+    }
+
     private Resources getResources(PrintWriter pw) throws RemoteException {
         // system resources does not contain all the device configuration, construct it manually.
         Configuration config = mInterface.getConfiguration();
@@ -3726,6 +3807,10 @@
             pw.println("         Without arguments, it resets to the value defined by platform.");
             pw.println("  set-bg-abusive-uids [uid=percentage][,uid=percentage...]");
             pw.println("         Force setting the battery usage of the given UID.");
+            pw.println("  set-bg-restriction-level [--user <USER_ID>] <PACKAGE> unrestricted|exempted|adaptive_bucket|restricted_bucket|background_restricted|hibernation");
+            pw.println("         Set an app's background restriction level which in turn map to a app standby bucket.");
+            pw.println("  get-bg-restriction-level [--user <USER_ID>] <PACKAGE>");
+            pw.println("         Get an app's background restriction level.");
             pw.println();
             Intent.printIntentArgsHelp(pw, "");
         }
diff --git a/services/core/java/com/android/server/am/AppRestrictionController.java b/services/core/java/com/android/server/am/AppRestrictionController.java
index 6076eb1..e0690bf 100644
--- a/services/core/java/com/android/server/am/AppRestrictionController.java
+++ b/services/core/java/com/android/server/am/AppRestrictionController.java
@@ -2151,7 +2151,7 @@
         return AppBackgroundRestrictionsInfo.SDK_UNKNOWN;
     }
 
-    private void applyRestrictionLevel(String pkgName, int uid,
+    void applyRestrictionLevel(String pkgName, int uid,
             @RestrictionLevel int level, TrackerInfo trackerInfo,
             int curBucket, boolean allowUpdateBucket, int reason, int subReason) {
         int curLevel;
@@ -2790,13 +2790,6 @@
         if (isOnSystemDeviceIdleAllowlist(uid)) {
             return REASON_SYSTEM_ALLOW_LISTED;
         }
-        if (isOnDeviceIdleAllowlist(uid)) {
-            return REASON_ALLOWLISTED_PACKAGE;
-        }
-        final ActivityManagerInternal am = mInjector.getActivityManagerInternal();
-        if (am.isAssociatedCompanionApp(UserHandle.getUserId(uid), uid)) {
-            return REASON_COMPANION_DEVICE_MANAGER;
-        }
         if (UserManager.isDeviceInDemoMode(mContext)) {
             return REASON_DEVICE_DEMO_MODE;
         }
@@ -2805,6 +2798,7 @@
                 .hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL, userId)) {
             return REASON_DISALLOW_APPS_CONTROL;
         }
+        final ActivityManagerInternal am = mInjector.getActivityManagerInternal();
         if (am.isDeviceOwner(uid)) {
             return REASON_DEVICE_OWNER;
         }
@@ -2822,14 +2816,9 @@
             final AppOpsManager appOpsManager = mInjector.getAppOpsManager();
             final PackageManagerInternal pm = mInjector.getPackageManagerInternal();
             final AppStandbyInternal appStandbyInternal = mInjector.getAppStandbyInternal();
+            // Check each packages to see if any of them is in the "fixed" exemption cases.
             for (String pkg : packages) {
-                if (appOpsManager.checkOpNoThrow(AppOpsManager.OP_ACTIVATE_VPN,
-                        uid, pkg) == AppOpsManager.MODE_ALLOWED) {
-                    return REASON_OP_ACTIVATE_VPN;
-                } else if (appOpsManager.checkOpNoThrow(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN,
-                        uid, pkg) == AppOpsManager.MODE_ALLOWED) {
-                    return REASON_OP_ACTIVATE_PLATFORM_VPN;
-                } else if (isSystemModule(pkg)) {
+                if (isSystemModule(pkg)) {
                     return REASON_SYSTEM_MODULE;
                 } else if (isCarrierApp(pkg)) {
                     return REASON_CARRIER_PRIVILEGED_APP;
@@ -2843,6 +2832,16 @@
                     return REASON_ACTIVE_DEVICE_ADMIN;
                 }
             }
+            // Loop the packages again, and check the user-configurable exemptions.
+            for (String pkg : packages) {
+                if (appOpsManager.checkOpNoThrow(AppOpsManager.OP_ACTIVATE_VPN,
+                        uid, pkg) == AppOpsManager.MODE_ALLOWED) {
+                    return REASON_OP_ACTIVATE_VPN;
+                } else if (appOpsManager.checkOpNoThrow(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN,
+                        uid, pkg) == AppOpsManager.MODE_ALLOWED) {
+                    return REASON_OP_ACTIVATE_PLATFORM_VPN;
+                }
+            }
         }
         if (isRoleHeldByUid(RoleManager.ROLE_DIALER, uid)) {
             return REASON_ROLE_DIALER;
@@ -2850,6 +2849,12 @@
         if (isRoleHeldByUid(RoleManager.ROLE_EMERGENCY, uid)) {
             return REASON_ROLE_EMERGENCY;
         }
+        if (isOnDeviceIdleAllowlist(uid)) {
+            return REASON_ALLOWLISTED_PACKAGE;
+        }
+        if (am.isAssociatedCompanionApp(UserHandle.getUserId(uid), uid)) {
+            return REASON_COMPANION_DEVICE_MANAGER;
+        }
         return REASON_DENIED;
     }
 
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 43d0de9..0cd1bfa 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -2125,8 +2125,9 @@
         // app just because it's stopped at a breakpoint.
         final boolean debugging = (r.curApp != null && r.curApp.isDebugging());
 
+        long timeoutDurationMs = now - r.receiverTime;
         Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
-                + ", started " + (now - r.receiverTime) + "ms ago");
+                + ", started " + timeoutDurationMs + "ms ago");
         r.receiverTime = now;
         if (!debugging) {
             r.anrCount++;
@@ -2158,7 +2159,9 @@
         }
 
         if (app != null) {
-            anrMessage = "Broadcast of " + r.intent.toString();
+            anrMessage =
+                    "Broadcast of " + r.intent.toString() + ", waited " + timeoutDurationMs
+                            + "ms";
         }
 
         if (mPendingBroadcast == r) {
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index 19ffc173..ae91d75 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -70,6 +70,7 @@
     final boolean callerInstantApp; // caller is an Instant App?
     final boolean ordered;  // serialize the send to receivers?
     final boolean sticky;   // originated from existing sticky data?
+    final boolean alarm;    // originated from an alarm triggering?
     final boolean initialSticky; // initial broadcast from register to sticky?
     final int userId;       // user id this broadcast was for
     final String resolvedType; // the resolved data type
@@ -305,6 +306,7 @@
         this.allowBackgroundActivityStarts = allowBackgroundActivityStarts;
         mBackgroundActivityStartsToken = backgroundActivityStartsToken;
         this.timeoutExempt = timeoutExempt;
+        alarm = options != null && options.isAlarmBroadcast();
     }
 
     /**
@@ -357,6 +359,7 @@
         allowBackgroundActivityStarts = from.allowBackgroundActivityStarts;
         mBackgroundActivityStartsToken = from.mBackgroundActivityStartsToken;
         timeoutExempt = from.timeoutExempt;
+        alarm = from.alarm;
     }
 
     /**
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index c65e61a..9607e40 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -1482,7 +1482,9 @@
         if (!cycleReEval) {
             // Don't reset this flag when doing cycles re-evaluation.
             state.setNoKillOnBgRestrictedAndIdle(false);
-            app.mOptRecord.setShouldNotFreeze(false);
+            // If this UID is currently allowlisted, it should not be frozen.
+            final UidRecord uidRec = app.getUidRecord();
+            app.mOptRecord.setShouldNotFreeze(uidRec != null && uidRec.isCurAllowListed());
         }
 
         final int appUid = app.info.uid;
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index 4044cce..bda60ff 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -18,6 +18,7 @@
 
 import static android.app.ActivityManager.START_SUCCESS;
 
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
 
@@ -34,6 +35,7 @@
 import android.os.IBinder;
 import android.os.PowerWhitelistManager;
 import android.os.PowerWhitelistManager.ReasonCode;
+import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.TransactionTooLargeException;
@@ -416,6 +418,22 @@
 
         final int callingUid = Binder.getCallingUid();
         final int callingPid = Binder.getCallingPid();
+
+        // Only system senders can declare a broadcast to be alarm-originated.  We check
+        // this here rather than in the general case handling below to fail before the other
+        // invocation side effects such as allowlisting.
+        if (options != null && callingUid != Process.SYSTEM_UID
+                && key.type == ActivityManager.INTENT_SENDER_BROADCAST) {
+            if (options.containsKey(BroadcastOptions.KEY_ALARM_BROADCAST)) {
+                if (DEBUG_BROADCAST_LIGHT) {
+                    Slog.w(TAG, "Non-system caller " + callingUid
+                            + " may not flag broadcast as alarm-related");
+                }
+                throw new SecurityException(
+                        "Non-system callers may not flag broadcasts as alarm-related");
+            }
+        }
+
         final long origId = Binder.clearCallingIdentity();
 
         int res = START_SUCCESS;
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 132309e..42792bf6 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -2269,7 +2269,9 @@
                 final boolean inBgRestricted = ast.isAppBackgroundRestricted(
                         app.info.uid, app.info.packageName);
                 if (inBgRestricted) {
-                    mAppsInBackgroundRestricted.add(app);
+                    synchronized (mService) {
+                        mAppsInBackgroundRestricted.add(app);
+                    }
                 }
                 app.mState.setBackgroundRestricted(inBgRestricted);
             }
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 7ffea26..e4224ed 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -91,6 +91,7 @@
 import android.os.UserManager;
 import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
+import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.ArraySet;
 import android.util.EventLog;
@@ -145,7 +146,7 @@
 
     // Amount of time we wait for observers to handle a user switch before
     // giving up on them and unfreezing the screen.
-    static final int USER_SWITCH_TIMEOUT_MS = 3 * 1000;
+    static final int DEFAULT_USER_SWITCH_TIMEOUT_MS = 3 * 1000;
 
     /**
      * Amount of time we wait for an observer to handle a user switch before we log a warning. This
@@ -182,9 +183,11 @@
     // UI thread message constants
     static final int START_USER_SWITCH_UI_MSG = 1000;
 
-    // If a callback wasn't called within USER_SWITCH_CALLBACKS_TIMEOUT_MS after
-    // USER_SWITCH_TIMEOUT_MS, an error is reported. Usually it indicates a problem in the observer
-    // when it never calls back.
+    /**
+     * If a callback wasn't called within USER_SWITCH_CALLBACKS_TIMEOUT_MS after
+     * {@link #getUserSwitchTimeoutMs}, an error is reported. Usually it indicates a problem in the
+     * observer when it never calls back.
+     */
     private static final int USER_SWITCH_CALLBACKS_TIMEOUT_MS = 5 * 1000;
 
     /**
@@ -348,7 +351,7 @@
     private String mSwitchingToSystemUserMessage;
 
     /**
-     * Callbacks that are still active after {@link #USER_SWITCH_TIMEOUT_MS}
+     * Callbacks that are still active after {@link #getUserSwitchTimeoutMs}
      */
     @GuardedBy("mLock")
     private ArraySet<String> mTimeoutUserSwitchCallbacks;
@@ -1642,7 +1645,7 @@
                 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
                         oldUserId, userId, uss));
                 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
-                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT_MS);
+                        oldUserId, userId, uss), getUserSwitchTimeoutMs());
             }
 
             if (userInfo.preCreated) {
@@ -1955,6 +1958,7 @@
                 mCurWaitingUserSwitchCallbacks = curWaitingUserSwitchCallbacks;
             }
             final AtomicInteger waitingCallbacksCount = new AtomicInteger(observerCount);
+            final long userSwitchTimeoutMs = getUserSwitchTimeoutMs();
             final long dispatchStartedTime = SystemClock.elapsedRealtime();
             for (int i = 0; i < observerCount; i++) {
                 final long dispatchStartedTimeForObserver = SystemClock.elapsedRealtime();
@@ -1978,7 +1982,7 @@
 
                                 long totalDelay = SystemClock.elapsedRealtime()
                                         - dispatchStartedTime;
-                                if (totalDelay > USER_SWITCH_TIMEOUT_MS) {
+                                if (totalDelay > userSwitchTimeoutMs) {
                                     Slogf.e(TAG, "User switch timeout: observer " + name
                                             + "'s result was received " + totalDelay
                                             + " ms after dispatchUserSwitch.");
@@ -3109,6 +3113,19 @@
         return bOptions;
     }
 
+    private static int getUserSwitchTimeoutMs() {
+        final String userSwitchTimeoutMs = SystemProperties.get(
+                "debug.usercontroller.user_switch_timeout_ms");
+        if (!TextUtils.isEmpty(userSwitchTimeoutMs)) {
+            try {
+                return Integer.parseInt(userSwitchTimeoutMs);
+            } catch (NumberFormatException ignored) {
+                // Ignored.
+            }
+        }
+        return DEFAULT_USER_SWITCH_TIMEOUT_MS;
+    }
+
     /**
      * Uptime when any user was being unlocked most recently. 0 if no users have been unlocked
      * yet. To avoid lock contention (since it's used by OomAdjuster), it's volatile internally.
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 03dcc8d..b3aff65 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -1323,7 +1323,8 @@
                     break;
                 case MSG_II_SET_HEARING_AID_VOLUME:
                     synchronized (mDeviceStateLock) {
-                        mBtHelper.setHearingAidVolume(msg.arg1, msg.arg2);
+                        mBtHelper.setHearingAidVolume(msg.arg1, msg.arg2,
+                                mDeviceInventory.isHearingAidConnected());
                     }
                     break;
                 case MSG_II_SET_LE_AUDIO_OUT_VOLUME: {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index dbe4fb8..1312d08 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -1158,6 +1158,22 @@
                 .record();
     }
 
+    /**
+     * Returns whether a device of type DEVICE_OUT_HEARING_AID is connected.
+     * Visibility by APM plays no role
+     * @return true if a DEVICE_OUT_HEARING_AID is connected, false otherwise.
+     */
+    boolean isHearingAidConnected() {
+        synchronized (mDevicesLock) {
+            for (DeviceInfo di : mConnectedDevices.values()) {
+                if (di.mDeviceType == AudioSystem.DEVICE_OUT_HEARING_AID) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
     @GuardedBy("mDevicesLock")
     private void makeLeAudioDeviceAvailable(String address, String name, int streamType, int device,
             String eventSource) {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 42d8778..556fa14 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -550,6 +550,10 @@
                     if (mRecordMonitor != null) {
                         mRecordMonitor.onAudioServerDied();
                     }
+                    // Notify the playback monitor that the audio server has died
+                    if (mPlaybackMonitor != null) {
+                        mPlaybackMonitor.onAudioServerDied();
+                    }
                     sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED,
                             SENDMSG_NOOP, 0, 0, null, 0);
                     sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE,
@@ -1792,11 +1796,11 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /**
      * @see AudioManager#setSupportedSystemUsages(int[])
      */
     public void setSupportedSystemUsages(@NonNull @AttributeSystemUsage int[] systemUsages) {
-        enforceModifyAudioRoutingPermission();
         verifySystemUsages(systemUsages);
 
         synchronized (mSupportedSystemUsagesLock) {
@@ -1805,11 +1809,11 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /**
      * @see AudioManager#getSupportedSystemUsages()
      */
     public @NonNull @AttributeSystemUsage int[] getSupportedSystemUsages() {
-        enforceModifyAudioRoutingPermission();
         synchronized (mSupportedSystemUsagesLock) {
             return Arrays.copyOf(mSupportedSystemUsages, mSupportedSystemUsages.length);
         }
@@ -1823,6 +1827,7 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /**
      * @return the {@link android.media.audiopolicy.AudioProductStrategy} discovered from the
      * platform configuration file.
@@ -1830,10 +1835,10 @@
     @NonNull
     public List<AudioProductStrategy> getAudioProductStrategies() {
         // verify permissions
-        enforceModifyAudioRoutingPermission();
         return AudioProductStrategy.getAudioProductStrategies();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /**
      * @return the List of {@link android.media.audiopolicy.AudioVolumeGroup} discovered from the
      * platform configuration file.
@@ -1841,7 +1846,6 @@
     @NonNull
     public List<AudioVolumeGroup> getAudioVolumeGroups() {
         // verify permissions
-        enforceModifyAudioRoutingPermission();
         return AudioVolumeGroup.getAudioVolumeGroups();
     }
 
@@ -2723,9 +2727,9 @@
         return status;
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /** @see AudioManager#removePreferredDeviceForStrategy(AudioProductStrategy) */
     public int removePreferredDevicesForStrategy(int strategy) {
-        enforceModifyAudioRoutingPermission();
         final String logString =
                 String.format("removePreferredDeviceForStrategy strat:%d", strategy);
         sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG));
@@ -2737,12 +2741,12 @@
         return status;
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /**
      * @see AudioManager#getPreferredDeviceForStrategy(AudioProductStrategy)
      * @see AudioManager#getPreferredDevicesForStrategy(AudioProductStrategy)
      */
     public List<AudioDeviceAttributes> getPreferredDevicesForStrategy(int strategy) {
-        enforceModifyAudioRoutingPermission();
         List<AudioDeviceAttributes> devices = new ArrayList<>();
         final long identity = Binder.clearCallingIdentity();
         final int status = AudioSystem.getDevicesForRoleAndStrategy(
@@ -2810,9 +2814,9 @@
         return status;
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /** @see AudioManager#clearPreferredDevicesForCapturePreset(int) */
     public int clearPreferredDevicesForCapturePreset(int capturePreset) {
-        enforceModifyAudioRoutingPermission();
         final String logString = String.format(
                 "removePreferredDeviceForCapturePreset source:%d", capturePreset);
         sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG));
@@ -2824,11 +2828,11 @@
         return status;
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /**
      * @see AudioManager#getPreferredDevicesForCapturePreset(int)
      */
     public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int capturePreset) {
-        enforceModifyAudioRoutingPermission();
         List<AudioDeviceAttributes> devices = new ArrayList<>();
         final long identity = Binder.clearCallingIdentity();
         final int status = AudioSystem.getDevicesForRoleAndCapturePreset(
@@ -3558,10 +3562,10 @@
     }
 
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /** @see AudioManager#setVolumeIndexForAttributes(attr, int, int) */
     public void setVolumeIndexForAttributes(@NonNull AudioAttributes attr, int index, int flags,
             String callingPackage, String attributionTag) {
-        enforceModifyAudioRoutingPermission();
         Objects.requireNonNull(attr, "attr must not be null");
         final int volumeGroup = getVolumeGroupIdForAttributes(attr);
         if (sVolumeGroupStates.indexOfKey(volumeGroup) < 0) {
@@ -3601,9 +3605,9 @@
         return null;
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /** @see AudioManager#getVolumeIndexForAttributes(attr) */
     public int getVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
-        enforceModifyAudioRoutingPermission();
         Objects.requireNonNull(attr, "attr must not be null");
         final int volumeGroup = getVolumeGroupIdForAttributes(attr);
         if (sVolumeGroupStates.indexOfKey(volumeGroup) < 0) {
@@ -3613,16 +3617,16 @@
         return vgs.getVolumeIndex();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /** @see AudioManager#getMaxVolumeIndexForAttributes(attr) */
     public int getMaxVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
-        enforceModifyAudioRoutingPermission();
         Objects.requireNonNull(attr, "attr must not be null");
         return AudioSystem.getMaxVolumeIndexForAttributes(attr);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /** @see AudioManager#getMinVolumeIndexForAttributes(attr) */
     public int getMinVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
-        enforceModifyAudioRoutingPermission();
         Objects.requireNonNull(attr, "attr must not be null");
         return AudioSystem.getMinVolumeIndexForAttributes(attr);
     }
@@ -3664,9 +3668,9 @@
                 attributionTag, Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission());
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_ULTRASOUND)
     /** @see AudioManager#isUltrasoundSupported() */
     public boolean isUltrasoundSupported() {
-        enforceAccessUltrasoundPermission();
         return AudioSystem.isUltrasoundSupported();
     }
 
@@ -4438,10 +4442,10 @@
         return AudioSystem.getMasterMute();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /** @see AudioManager#setMasterMute(boolean, int) */
     public void setMasterMute(boolean mute, int flags, String callingPackage, int userId,
             String attributionTag) {
-        enforceModifyAudioRoutingPermission();
         setMasterMuteInternal(mute, flags, callingPackage,
                 Binder.getCallingUid(), userId, Binder.getCallingPid(), attributionTag);
     }
@@ -4483,9 +4487,9 @@
         return (mStreamStates[streamType].getMinIndex(isPrivileged) + 5) / 10;
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.QUERY_AUDIO_STATE)
     /** Get last audible volume before stream was muted. */
     public int getLastAudibleStreamVolume(int streamType) {
-        enforceQueryStatePermission();
         ensureValidStreamType(streamType);
         int device = getDeviceForStream(streamType);
         return (mStreamStates[streamType].getIndex(device) + 5) / 10;
@@ -5332,9 +5336,9 @@
         mModeDispatchers.unregister(dispatcher);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION)
     /** @see AudioManager#isPstnCallAudioInterceptable() */
     public boolean isPstnCallAudioInterceptable() {
-        enforceCallAudioInterceptionPermission();
 
         boolean uplinkDeviceFound = false;
         boolean downlinkDeviceFound = false;
@@ -6689,6 +6693,7 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /**
      * @see AudioManager#setDeviceVolumeBehavior(AudioDeviceAttributes, int)
      * @param device the audio device to be affected
@@ -6697,7 +6702,6 @@
     public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
             @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName) {
         // verify permissions
-        enforceModifyAudioRoutingPermission();
         // verify arguments
         Objects.requireNonNull(device);
         AudioManager.enforceValidVolumeBehavior(deviceVolumeBehavior);
@@ -6847,12 +6851,12 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface ConnectionState {}
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /**
      * see AudioManager.setWiredDeviceConnectionState()
      */
     public void setWiredDeviceConnectionState(AudioDeviceAttributes attributes,
             @ConnectionState int state, String caller) {
-        enforceModifyAudioRoutingPermission();
         if (state != CONNECTION_STATE_CONNECTED
                 && state != CONNECTION_STATE_DISCONNECTED) {
             throw new IllegalArgumentException("Invalid state " + state);
@@ -8970,27 +8974,27 @@
         return mSpatializerHelper.isAvailable();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#isAvailableForDevice(AudioDeviceAttributes) */
     public boolean isSpatializerAvailableForDevice(@NonNull AudioDeviceAttributes device)  {
-        enforceModifyDefaultAudioEffectsPermission();
         return mSpatializerHelper.isAvailableForDevice(Objects.requireNonNull(device));
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#hasHeadTracker(AudioDeviceAttributes) */
     public boolean hasHeadTracker(@NonNull AudioDeviceAttributes device) {
-        enforceModifyDefaultAudioEffectsPermission();
         return mSpatializerHelper.hasHeadTracker(Objects.requireNonNull(device));
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#setHeadTrackerEnabled(boolean, AudioDeviceAttributes) */
     public void setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device) {
-        enforceModifyDefaultAudioEffectsPermission();
         mSpatializerHelper.setHeadTrackerEnabled(enabled, Objects.requireNonNull(device));
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#isHeadTrackerEnabled(AudioDeviceAttributes) */
     public boolean isHeadTrackerEnabled(@NonNull AudioDeviceAttributes device) {
-        enforceModifyDefaultAudioEffectsPermission();
         return mSpatializerHelper.isHeadTrackerEnabled(Objects.requireNonNull(device));
     }
 
@@ -8999,9 +9003,9 @@
         return mSpatializerHelper.isHeadTrackerAvailable();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#setSpatializerEnabled(boolean) */
     public void setSpatializerEnabled(boolean enabled) {
-        enforceModifyDefaultAudioEffectsPermission();
         mSpatializerHelper.setFeatureEnabled(enabled);
     }
 
@@ -9027,18 +9031,18 @@
         mSpatializerHelper.unregisterStateCallback(cb);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */
     public void registerSpatializerHeadTrackingCallback(
             @NonNull ISpatializerHeadTrackingModeCallback cb) {
-        enforceModifyDefaultAudioEffectsPermission();
         Objects.requireNonNull(cb);
         mSpatializerHelper.registerHeadTrackingModeCallback(cb);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */
     public void unregisterSpatializerHeadTrackingCallback(
             @NonNull ISpatializerHeadTrackingModeCallback cb) {
-        enforceModifyDefaultAudioEffectsPermission();
         Objects.requireNonNull(cb);
         mSpatializerHelper.unregisterHeadTrackingModeCallback(cb);
     }
@@ -9050,76 +9054,76 @@
         mSpatializerHelper.registerHeadTrackerAvailableCallback(cb, register);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#setOnHeadToSoundstagePoseUpdatedListener */
     public void registerHeadToSoundstagePoseCallback(
             @NonNull ISpatializerHeadToSoundStagePoseCallback cb) {
-        enforceModifyDefaultAudioEffectsPermission();
         Objects.requireNonNull(cb);
         mSpatializerHelper.registerHeadToSoundstagePoseCallback(cb);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#clearOnHeadToSoundstagePoseUpdatedListener */
     public void unregisterHeadToSoundstagePoseCallback(
             @NonNull ISpatializerHeadToSoundStagePoseCallback cb) {
-        enforceModifyDefaultAudioEffectsPermission();
         Objects.requireNonNull(cb);
         mSpatializerHelper.unregisterHeadToSoundstagePoseCallback(cb);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#getSpatializerCompatibleAudioDevices() */
     public @NonNull List<AudioDeviceAttributes> getSpatializerCompatibleAudioDevices() {
-        enforceModifyDefaultAudioEffectsPermission();
         return mSpatializerHelper.getCompatibleAudioDevices();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#addSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */
     public void addSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
-        enforceModifyDefaultAudioEffectsPermission();
         Objects.requireNonNull(ada);
         mSpatializerHelper.addCompatibleAudioDevice(ada);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#removeSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */
     public void removeSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
-        enforceModifyDefaultAudioEffectsPermission();
         Objects.requireNonNull(ada);
         mSpatializerHelper.removeCompatibleAudioDevice(ada);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#getSupportedHeadTrackingModes() */
     public int[] getSupportedHeadTrackingModes() {
-        enforceModifyDefaultAudioEffectsPermission();
         return mSpatializerHelper.getSupportedHeadTrackingModes();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#getHeadTrackingMode() */
     public int getActualHeadTrackingMode() {
-        enforceModifyDefaultAudioEffectsPermission();
         return mSpatializerHelper.getActualHeadTrackingMode();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#getDesiredHeadTrackingMode() */
     public int getDesiredHeadTrackingMode() {
-        enforceModifyDefaultAudioEffectsPermission();
         return mSpatializerHelper.getDesiredHeadTrackingMode();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#setGlobalTransform */
     public void setSpatializerGlobalTransform(@NonNull float[] transform) {
-        enforceModifyDefaultAudioEffectsPermission();
         Objects.requireNonNull(transform);
         mSpatializerHelper.setGlobalTransform(transform);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#recenterHeadTracker() */
     public void recenterHeadTracker() {
-        enforceModifyDefaultAudioEffectsPermission();
         mSpatializerHelper.recenterHeadTracker();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#setDesiredHeadTrackingMode */
     public void setDesiredHeadTrackingMode(@Spatializer.HeadTrackingModeSet int mode) {
-        enforceModifyDefaultAudioEffectsPermission();
         switch(mode) {
             case Spatializer.HEAD_TRACKING_MODE_DISABLED:
             case Spatializer.HEAD_TRACKING_MODE_RELATIVE_WORLD:
@@ -9131,36 +9135,36 @@
         mSpatializerHelper.setDesiredHeadTrackingMode(mode);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#setEffectParameter */
     public void setSpatializerParameter(int key, @NonNull byte[] value) {
-        enforceModifyDefaultAudioEffectsPermission();
         Objects.requireNonNull(value);
         mSpatializerHelper.setEffectParameter(key, value);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#getEffectParameter */
     public void getSpatializerParameter(int key, @NonNull byte[] value) {
-        enforceModifyDefaultAudioEffectsPermission();
         Objects.requireNonNull(value);
         mSpatializerHelper.getEffectParameter(key, value);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#getOutput */
     public int getSpatializerOutput() {
-        enforceModifyDefaultAudioEffectsPermission();
         return mSpatializerHelper.getOutput();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#setOnSpatializerOutputChangedListener */
     public void registerSpatializerOutputCallback(ISpatializerOutputCallback cb) {
-        enforceModifyDefaultAudioEffectsPermission();
         Objects.requireNonNull(cb);
         mSpatializerHelper.registerSpatializerOutputCallback(cb);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
     /** @see Spatializer#clearOnSpatializerOutputChangedListener */
     public void unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb) {
-        enforceModifyDefaultAudioEffectsPermission();
         Objects.requireNonNull(cb);
         mSpatializerHelper.unregisterSpatializerOutputCallback(cb);
     }
@@ -9268,9 +9272,9 @@
             cb.dispatchOnMutedUntilConnection(device, usages); } catch (RemoteException e) { } });
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /** @see AudioManager#getMutingExpectedDevice */
     public @Nullable AudioDeviceAttributes getMutingExpectedDevice() {
-        enforceModifyAudioRoutingPermission();
         synchronized (mMuteAwaitConnectionLock) {
             return mMutingExpectedDevice;
         }
@@ -9308,10 +9312,10 @@
     final RemoteCallbackList<IMuteAwaitConnectionCallback> mMuteAwaitConnectionDispatchers =
             new RemoteCallbackList<IMuteAwaitConnectionCallback>();
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /** @see AudioManager#registerMuteAwaitConnectionCallback */
     public void registerMuteAwaitConnectionDispatcher(@NonNull IMuteAwaitConnectionCallback cb,
             boolean register) {
-        enforceModifyAudioRoutingPermission();
         if (register) {
             mMuteAwaitConnectionDispatchers.register(cb);
         } else {
@@ -10373,6 +10377,11 @@
 
         @Override
         public void setAccessibilityServiceUids(IntArray uids) {
+            // TODO(b/233287010): Fix voice interaction and a11y concurrency in audio policy service
+            if (isPlatformAutomotive()) {
+                return;
+            }
+
             synchronized (mAccessibilityServiceUidsLock) {
                 if (uids.size() == 0) {
                     mAccessibilityServiceUids = null;
@@ -10817,9 +10826,9 @@
         return AudioManager.SUCCESS;
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /** @see AudioPolicy#getFocusStack() */
     public List<AudioFocusInfo> getFocusStack() {
-        enforceModifyAudioRoutingPermission();
         return mMediaFocusControl.getFocusStack();
     }
 
@@ -11023,10 +11032,10 @@
      * Update player event
      * @param piid Player id to update
      * @param event The new player event
-     * @param deviceId The new player device id
+     * @param eventValue The value associated with this event
      */
-    public void playerEvent(int piid, int event, int deviceId) {
-        mPlaybackMonitor.playerEvent(piid, event, deviceId, Binder.getCallingUid());
+    public void playerEvent(int piid, int event, int eventValue) {
+        mPlaybackMonitor.playerEvent(piid, event, eventValue, Binder.getCallingUid());
     }
 
     public void playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio) {
@@ -11582,11 +11591,11 @@
         AudioSystem.setAudioHalPids(pidsArray);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     //======================
     // Multi Audio Focus
     //======================
     public void setMultiAudioFocusEnabled(boolean enabled) {
-        enforceModifyAudioRoutingPermission();
         if (mMediaFocusControl != null) {
             boolean mafEnabled = mMediaFocusControl.getMultiAudioFocusEnabled();
             if (mafEnabled != enabled) {
@@ -11685,10 +11694,10 @@
         return delayMillis;
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /** @see AudioManager#addAssistantServicesUids(int []) */
     @Override
     public void addAssistantServicesUids(int [] assistantUids) {
-        enforceModifyAudioRoutingPermission();
         Objects.requireNonNull(assistantUids);
 
         synchronized (mSettingsLock) {
@@ -11696,20 +11705,20 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /** @see AudioManager#removeAssistantServicesUids(int []) */
     @Override
     public void removeAssistantServicesUids(int [] assistantUids) {
-        enforceModifyAudioRoutingPermission();
         Objects.requireNonNull(assistantUids);
         synchronized (mSettingsLock) {
             removeAssistantServiceUidsLocked(assistantUids);
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /** @see AudioManager#getAssistantServicesUids() */
     @Override
     public int[] getAssistantServicesUids() {
-        enforceModifyAudioRoutingPermission();
         int [] assistantUids;
         synchronized (mSettingsLock) {
             assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray();
@@ -11717,10 +11726,10 @@
         return assistantUids;
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /** @see AudioManager#setActiveAssistantServiceUids(int []) */
     @Override
     public void setActiveAssistantServiceUids(int [] activeAssistantUids) {
-        enforceModifyAudioRoutingPermission();
         Objects.requireNonNull(activeAssistantUids);
         synchronized (mSettingsLock) {
             mActiveAssistantServiceUids = activeAssistantUids;
@@ -11728,10 +11737,10 @@
         updateActiveAssistantServiceUids();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /** @see AudioManager#getActiveAssistantServiceUids() */
     @Override
     public int[] getActiveAssistantServiceUids() {
-        enforceModifyAudioRoutingPermission();
         int [] activeAssistantUids;
         synchronized (mSettingsLock) {
             activeAssistantUids = mActiveAssistantServiceUids.clone();
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 0e38232..d9037fe 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -303,7 +303,7 @@
 
         Log.i(TAG, "receiveBtEvent action: " + action + " mScoAudioState: " + mScoAudioState);
         if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED)) {
-            BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+            BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, android.bluetooth.BluetoothDevice.class);
             setBtScoActiveDevice(btDevice);
         } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
             int btState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
@@ -423,7 +423,8 @@
         mLeAudio.setVolume(volume);
     }
 
-    /*package*/ synchronized void setHearingAidVolume(int index, int streamType) {
+    /*package*/ synchronized void setHearingAidVolume(int index, int streamType,
+            boolean isHeadAidConnected) {
         if (mHearingAid == null) {
             if (AudioService.DEBUG_VOL) {
                 Log.i(TAG, "setHearingAidVolume: null mHearingAid");
@@ -440,8 +441,11 @@
             Log.i(TAG, "setHearingAidVolume: calling mHearingAid.setVolume idx="
                     + index + " gain=" + gainDB);
         }
-        AudioService.sVolumeLogger.log(new AudioServiceEvents.VolumeEvent(
-                AudioServiceEvents.VolumeEvent.VOL_SET_HEARING_AID_VOL, index, gainDB));
+        // do not log when hearing aid is not connected to avoid confusion when reading dumpsys
+        if (isHeadAidConnected) {
+            AudioService.sVolumeLogger.log(new AudioServiceEvents.VolumeEvent(
+                    AudioServiceEvents.VolumeEvent.VOL_SET_HEARING_AID_VOL, index, gainDB));
+        }
         mHearingAid.setVolume(gainDB);
     }
 
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index b3e7e31..02036db 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -34,7 +34,9 @@
 import android.os.IBinder;
 import android.os.Message;
 import android.os.RemoteException;
+import android.text.TextUtils;
 import android.util.Log;
+import android.util.SparseIntArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.ArrayUtils;
@@ -115,6 +117,9 @@
     private final HashMap<Integer, AudioPlaybackConfiguration> mPlayers =
             new HashMap<Integer, AudioPlaybackConfiguration>();
 
+    @GuardedBy("mPlayerLock")
+    private final SparseIntArray mPortIdToPiid = new SparseIntArray();
+
     private final Context mContext;
     private int mSavedAlarmVolume = -1;
     private final int mMaxAlarmVolume;
@@ -290,22 +295,29 @@
      * Update player event
      * @param piid Player id to update
      * @param event The new player event
-     * @param deviceId The new player device id
+     * @param eventValue The value associated with this event
      * @param binderUid Calling binder uid
      */
-    public void playerEvent(int piid, int event, int deviceId, int binderUid) {
+    public void playerEvent(int piid, int event, int eventValue, int binderUid) {
         if (DEBUG) {
-            Log.v(TAG, String.format("playerEvent(piid=%d, deviceId=%d, event=%s)",
-                    piid, deviceId, AudioPlaybackConfiguration.playerStateToString(event)));
+            Log.v(TAG, TextUtils.formatSimple("playerEvent(piid=%d, event=%s, eventValue=%d)",
+                    piid, AudioPlaybackConfiguration.playerStateToString(event), eventValue));
         }
+
         final boolean change;
         synchronized(mPlayerLock) {
             final AudioPlaybackConfiguration apc = mPlayers.get(new Integer(piid));
             if (apc == null) {
                 return;
             }
-            sEventLogger.log(new PlayerEvent(piid, event, deviceId));
-            if (event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
+
+            sEventLogger.log(new PlayerEvent(piid, event, eventValue));
+
+            if (event == AudioPlaybackConfiguration.PLAYER_UPDATE_PORT_ID) {
+                mEventHandler.sendMessage(
+                        mEventHandler.obtainMessage(MSG_L_UPDATE_PORT_EVENT, eventValue, piid));
+                return;
+            } else if (event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
                 for (Integer uidInteger: mBannedUids) {
                     if (checkBanPlayer(apc, uidInteger.intValue())) {
                         // player was banned, do not update its state
@@ -322,7 +334,7 @@
             if (checkConfigurationCaller(piid, apc, binderUid)) {
                 //TODO add generation counter to only update to the latest state
                 checkVolumeForPrivilegedAlarm(apc, event);
-                change = apc.handleStateEvent(event, deviceId);
+                change = apc.handleStateEvent(event, eventValue);
             } else {
                 Log.e(TAG, "Error handling event " + event);
                 change = false;
@@ -357,6 +369,11 @@
                 checkVolumeForPrivilegedAlarm(apc, AudioPlaybackConfiguration.PLAYER_STATE_RELEASED);
                 change = apc.handleStateEvent(AudioPlaybackConfiguration.PLAYER_STATE_RELEASED,
                         AudioPlaybackConfiguration.PLAYER_DEVICEID_INVALID);
+
+                // remove all port ids mapped to the released player
+                mEventHandler.sendMessage(
+                        mEventHandler.obtainMessage(MSG_L_CLEAR_PORTS_FOR_PIID, piid, /*arg2=*/0));
+
             }
         }
         if (change) {
@@ -364,6 +381,18 @@
         }
     }
 
+    /*package*/ void onAudioServerDied() {
+        sEventLogger.log(
+                new AudioEventLogger.StringEvent(
+                        "clear port id to piid map"));
+        synchronized (mPlayerLock) {
+            if (DEBUG) {
+                Log.v(TAG, "clear port id to piid map:\n" + mPortIdToPiid);
+            }
+            mPortIdToPiid.clear();
+        }
+    }
+
     /**
      * A map of uid to capture policy.
      */
@@ -499,9 +528,18 @@
                 pw.print(" " + piid);
             }
             pw.println("\n");
+            // portId to piid mappings:
+            pw.println("\n  current portId to piid map:");
+            for (int i = 0; i < mPortIdToPiid.size(); ++i) {
+                pw.println(
+                        "  portId: " + mPortIdToPiid.keyAt(i) + " piid: " + mPortIdToPiid.valueAt(
+                                i));
+            }
+            pw.println("\n");
             // log
             sEventLogger.dump(pw);
         }
+
         synchronized (mAllowedCapturePolicies) {
             pw.println("\n  allowed capture policies:");
             for (HashMap.Entry<Integer, Integer> entry : mAllowedCapturePolicies.entrySet()) {
@@ -1010,27 +1048,36 @@
 
     //=================================================================
     // For logging
-    private final static class PlayerEvent extends AudioEventLogger.Event {
+    private static final class PlayerEvent extends AudioEventLogger.Event {
         // only keeping the player interface ID as it uniquely identifies the player in the event
         final int mPlayerIId;
-        final int mState;
-        final int mDeviceId;
+        final int mEvent;
+        final int mEventValue;
 
-        PlayerEvent(int piid, int state, int deviceId) {
+        PlayerEvent(int piid, int event, int eventValue) {
             mPlayerIId = piid;
-            mState = state;
-            mDeviceId = deviceId;
+            mEvent = event;
+            mEventValue = eventValue;
         }
 
         @Override
         public String eventToString() {
-            return new StringBuilder("player piid:").append(mPlayerIId).append(" state:")
-                    .append(AudioPlaybackConfiguration.toLogFriendlyPlayerState(mState))
-                    .append(" DeviceId:").append(mDeviceId).toString();
+            if (mEvent == AudioPlaybackConfiguration.PLAYER_UPDATE_PORT_ID) {
+                return AudioPlaybackConfiguration.toLogFriendlyPlayerState(mEvent) + " portId:"
+                        + mEventValue + " mapped to player piid:" + mPlayerIId;
+            }
+
+            StringBuilder builder = new StringBuilder("player piid:").append(mPlayerIId).append(
+                            " state:")
+                    .append(AudioPlaybackConfiguration.toLogFriendlyPlayerState(mEvent));
+            if (mEventValue != 0) {
+                builder.append(" DeviceId:").append(mEventValue);
+            }
+            return builder.toString();
         }
     }
 
-    private final static class PlayerOpPlayAudioEvent extends AudioEventLogger.Event {
+    private static final class PlayerOpPlayAudioEvent extends AudioEventLogger.Event {
         // only keeping the player interface ID as it uniquely identifies the player in the event
         final int mPlayerIId;
         final boolean mHasOp;
@@ -1050,7 +1097,7 @@
         }
     }
 
-    private final static class NewPlayerEvent extends AudioEventLogger.Event {
+    private static final class NewPlayerEvent extends AudioEventLogger.Event {
         private final int mPlayerIId;
         private final int mPlayerType;
         private final int mClientUid;
@@ -1267,6 +1314,21 @@
      */
     private static final int MSG_L_TIMEOUT_MUTE_AWAIT_CONNECTION = 1;
 
+    /**
+     * assign new port id to piid
+     * args:
+     *     msg.arg1: port id
+     *     msg.arg2: piid
+     */
+    private static final int MSG_L_UPDATE_PORT_EVENT = 2;
+
+    /**
+     * clear all ports assigned to a given piid
+     * args:
+     *     msg.arg1: the piid
+     */
+    private static final int MSG_L_CLEAR_PORTS_FOR_PIID = 3;
+
     private void initEventHandler() {
         mEventThread = new HandlerThread(TAG);
         mEventThread.start();
@@ -1282,6 +1344,25 @@
                         }
                         mMuteAwaitConnectionTimeoutCb.accept((AudioDeviceAttributes) msg.obj);
                         break;
+                    case MSG_L_UPDATE_PORT_EVENT:
+                        synchronized (mPlayerLock) {
+                            mPortIdToPiid.put(/*portId*/msg.arg1, /*piid*/msg.arg2);
+                        }
+                        break;
+                    case MSG_L_CLEAR_PORTS_FOR_PIID:
+                        int piid = msg.arg1;
+                        if (piid == AudioPlaybackConfiguration.PLAYER_PIID_INVALID) {
+                            Log.w(TAG, "Received clear ports with invalid piid");
+                            break;
+                        }
+
+                        synchronized (mPlayerLock) {
+                            int portIdx;
+                            while ((portIdx = mPortIdToPiid.indexOfValue(piid)) >= 0) {
+                                mPortIdToPiid.removeAt(portIdx);
+                            }
+                        }
+                        break;
                     default:
                         break;
                 }
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index bc550d3..d2016c47 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -173,10 +173,10 @@
     }
 
     private final class AuthServiceImpl extends IAuthService.Stub {
+        @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
         @Override
         public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
                 @NonNull String opPackageName) throws RemoteException {
-            Utils.checkPermission(getContext(), TEST_BIOMETRIC);
 
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -187,10 +187,10 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
         @Override
         public List<SensorPropertiesInternal> getSensorProperties(String opPackageName)
                 throws RemoteException {
-            Utils.checkPermission(getContext(), TEST_BIOMETRIC);
 
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -202,9 +202,9 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
         @Override
         public String getUiPackage() {
-            Utils.checkPermission(getContext(), TEST_BIOMETRIC);
 
             return getContext().getResources()
                     .getString(R.string.config_biometric_prompt_ui_package);
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 4767969..689ddd2 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -491,10 +491,10 @@
      * sensor arbitration, threading, etc.
      */
     private final class BiometricServiceWrapper extends IBiometricService.Stub {
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
                 @NonNull String opPackageName) throws RemoteException {
-            checkInternalPermission();
 
             for (BiometricSensor sensor : mSensors) {
                 if (sensor.id == sensorId) {
@@ -506,10 +506,10 @@
             return null;
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public List<SensorPropertiesInternal> getSensorProperties(String opPackageName)
                 throws RemoteException {
-            checkInternalPermission();
 
             final List<SensorPropertiesInternal> sensors = new ArrayList<>();
             for (BiometricSensor sensor : mSensors) {
@@ -523,17 +523,17 @@
             return sensors;
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public void onReadyForAuthentication(long requestId, int cookie) {
-            checkInternalPermission();
 
             mHandler.post(() -> handleOnReadyForAuthentication(requestId, cookie));
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public long authenticate(IBinder token, long operationId, int userId,
                 IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo) {
-            checkInternalPermission();
 
             if (token == null || receiver == null || opPackageName == null || promptInfo == null) {
                 Slog.e(TAG, "Unable to authenticate, one or more null arguments");
@@ -561,9 +561,9 @@
             return requestId;
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public void cancelAuthentication(IBinder token, String opPackageName, long requestId) {
-            checkInternalPermission();
 
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = token;
@@ -573,10 +573,10 @@
             mHandler.post(() -> handleCancelAuthentication(requestId));
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public int canAuthenticate(String opPackageName, int userId, int callingUserId,
                 @Authenticators.Types int authenticators) {
-            checkInternalPermission();
 
             Slog.d(TAG, "canAuthenticate: User=" + userId
                     + ", Caller=" + callingUserId
@@ -596,9 +596,9 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override
         public boolean hasEnrolledBiometrics(int userId, String opPackageName) {
-            checkInternalPermission();
 
             try {
                 for (BiometricSensor sensor : mSensors) {
@@ -613,11 +613,11 @@
             return false;
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override
         public synchronized void registerAuthenticator(int id, int modality,
                 @Authenticators.Types int strength,
                 @NonNull IBiometricAuthenticator authenticator) {
-            checkInternalPermission();
 
             Slog.d(TAG, "Registering ID: " + id
                     + " Modality: " + modality
@@ -660,10 +660,10 @@
             mBiometricStrengthController.updateStrengths();
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public void registerEnabledOnKeyguardCallback(
                 IBiometricEnabledOnKeyguardCallback callback, int callingUserId) {
-            checkInternalPermission();
 
             mEnabledOnKeyguardCallbacks.add(new EnabledOnKeyguardCallback(callback));
             try {
@@ -674,17 +674,17 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public void invalidateAuthenticatorIds(int userId, int fromSensorId,
                 IInvalidationCallback callback) {
-            checkInternalPermission();
 
             InvalidationTracker.start(getContext(), mSensors, userId, fromSensorId, callback);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public long[] getAuthenticatorIds(int callingUserId) {
-            checkInternalPermission();
 
             final List<Long> authenticatorIds = new ArrayList<>();
             for (BiometricSensor sensor : mSensors) {
@@ -712,10 +712,10 @@
             return result;
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public void resetLockoutTimeBound(IBinder token, String opPackageName, int fromSensorId,
                 int userId, byte[] hardwareAuthToken) {
-            checkInternalPermission();
 
             // Check originating strength
             if (!Utils.isAtLeastStrength(getSensorForId(fromSensorId).getCurrentStrength(),
@@ -751,9 +751,9 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public int getCurrentStrength(int sensorId) {
-            checkInternalPermission();
 
             for (BiometricSensor sensor : mSensors) {
                 if (sensor.id == sensorId) {
@@ -764,6 +764,7 @@
             return Authenticators.EMPTY_SET;
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public int getCurrentModality(
                 String opPackageName,
@@ -771,7 +772,6 @@
                 int callingUserId,
                 @Authenticators.Types int authenticators) {
 
-            checkInternalPermission();
 
             Slog.d(TAG, "getCurrentModality: User=" + userId
                     + ", Caller=" + callingUserId
@@ -791,9 +791,9 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public int getSupportedModalities(@Authenticators.Types int authenticators) {
-            checkInternalPermission();
 
             Slog.d(TAG, "getSupportedModalities: Authenticators=" + authenticators);
 
diff --git a/services/core/java/com/android/server/biometrics/log/BiometricLogger.java b/services/core/java/com/android/server/biometrics/log/BiometricLogger.java
index ad24cf0..262be08 100644
--- a/services/core/java/com/android/server/biometrics/log/BiometricLogger.java
+++ b/services/core/java/com/android/server/biometrics/log/BiometricLogger.java
@@ -28,8 +28,10 @@
 import android.hardware.biometrics.common.OperationContext;
 import android.hardware.face.FaceManager;
 import android.hardware.fingerprint.FingerprintManager;
+import android.util.Log;
 import android.util.Slog;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.server.biometrics.Utils;
@@ -41,6 +43,10 @@
 
     public static final String TAG = "BiometricLogger";
     public static final boolean DEBUG = false;
+    private static final Object sLock = new Object();
+
+    @GuardedBy("sLock")
+    private static int sAlsCounter;
 
     private final int mStatsModality;
     private final int mStatsAction;
@@ -345,13 +351,33 @@
             if (!mLightSensorEnabled) {
                 mLightSensorEnabled = true;
                 mLastAmbientLux = 0;
-                mSensorManager.registerListener(mLightSensorListener, lightSensor,
-                        SensorManager.SENSOR_DELAY_NORMAL);
+                int localAlsCounter;
+                synchronized (sLock) {
+                    localAlsCounter = sAlsCounter++;
+                }
+
+                if (localAlsCounter == 0) {
+                    mSensorManager.registerListener(mLightSensorListener, lightSensor,
+                            SensorManager.SENSOR_DELAY_NORMAL);
+                } else {
+                    Slog.e(TAG, "Ignoring request to subscribe to ALSProbe due to non-zero ALS"
+                            + " counter: " + localAlsCounter);
+                    Slog.e(TAG, Log.getStackTraceString(new Throwable()));
+                }
             }
         } else {
             mLightSensorEnabled = false;
             mLastAmbientLux = 0;
             mSensorManager.unregisterListener(mLightSensorListener);
+            int localAlsCounter;
+            synchronized (sLock) {
+                localAlsCounter = --sAlsCounter;
+            }
+            if (localAlsCounter != 0) {
+                Slog.e(TAG, "Non-zero ALS counter after unsubscribing from ALSProbe: "
+                        + localAlsCounter);
+                Slog.e(TAG, Log.getStackTraceString(new Throwable()));
+            }
         }
     }
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java b/services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java
index 1b24aa8..0d789f7 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java
@@ -108,6 +108,17 @@
         }
     }
 
+    @Override
+    public void onBiometricAction(@BiometricStateListener.Action int action) {
+        for (IBiometricStateListener listener : mBiometricStateListeners) {
+            try {
+                listener.onBiometricAction(action);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote exception in onBiometricAction", e);
+            }
+        }
+    }
+
     /**
      * This should be invoked when:
      * 1) Enrolled --> None-enrolled
diff --git a/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallback.java b/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallback.java
index 8ea4ee9..4417f92 100644
--- a/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallback.java
+++ b/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallback.java
@@ -31,6 +31,11 @@
     default void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {}
 
     /**
+     * Invoked when a biometric action has occurred.
+     */
+    default void onBiometricAction(int action) {}
+
+    /**
      * Invoked when the ClientMonitor operation is complete. This abstracts away asynchronous
      * (i.e. Authenticate, Enroll, Enumerate, Remove) and synchronous (i.e. generateChallenge,
      * revokeChallenge) so that a scheduler can process ClientMonitors regardless of their
diff --git a/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCompositeCallback.java b/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCompositeCallback.java
index b82f5fa..07041bf8 100644
--- a/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCompositeCallback.java
+++ b/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCompositeCallback.java
@@ -44,6 +44,13 @@
     }
 
     @Override
+    public final void onBiometricAction(int action) {
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            mCallbacks.get(i).onBiometricAction(action);
+        }
+    }
+
+    @Override
     public final void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
             boolean success) {
         for (int i = mCallbacks.size() - 1; i >= 0; i--) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index 75d09f2..79e65cc 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -138,10 +138,10 @@
      * Receives the incoming binder calls from FaceManager.
      */
     private final class FaceServiceWrapper extends IFaceService.Stub {
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override
         public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
                 @NonNull String opPackageName) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
 
@@ -153,9 +153,9 @@
             return provider.createTestSession(sensorId, callback, opPackageName);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override
         public byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ProtoOutputStream proto = new ProtoOutputStream();
             final ServiceProvider provider = getProviderForSensor(sensorId);
@@ -166,18 +166,18 @@
             return proto.getBytes();
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
         @Override // Binder call
         public List<FaceSensorPropertiesInternal> getSensorPropertiesInternal(
                 String opPackageName) {
-            Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
 
             return FaceService.this.getSensorProperties();
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public FaceSensorPropertiesInternal getSensorProperties(int sensorId,
                 @NonNull String opPackageName) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -189,10 +189,10 @@
             return provider.getSensorProperties(sensorId);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
         @Override // Binder call
         public void generateChallenge(IBinder token, int sensorId, int userId,
                 IFaceServiceReceiver receiver, String opPackageName) {
-            Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -203,10 +203,10 @@
             provider.scheduleGenerateChallenge(sensorId, userId, token, receiver, opPackageName);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
         @Override // Binder call
         public void revokeChallenge(IBinder token, int sensorId, int userId, String opPackageName,
                 long challenge) {
-            Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -217,11 +217,11 @@
             provider.scheduleRevokeChallenge(sensorId, userId, token, opPackageName, challenge);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
         @Override // Binder call
         public long enroll(int userId, final IBinder token, final byte[] hardwareAuthToken,
                 final IFaceServiceReceiver receiver, final String opPackageName,
                 final int[] disabledFeatures, Surface previewSurface, boolean debugConsent) {
-            Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
 
             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
             if (provider == null) {
@@ -233,18 +233,18 @@
                     receiver, opPackageName, disabledFeatures, previewSurface, debugConsent);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
         @Override // Binder call
         public long enrollRemotely(int userId, final IBinder token, final byte[] hardwareAuthToken,
                 final IFaceServiceReceiver receiver, final String opPackageName,
                 final int[] disabledFeatures) {
-            Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
             // TODO(b/145027036): Implement this.
             return -1;
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
         @Override // Binder call
         public void cancelEnrollment(final IBinder token, long requestId) {
-            Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
 
             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
             if (provider == null) {
@@ -255,11 +255,11 @@
             provider.second.cancelEnrollment(provider.first, token, requestId);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public long authenticate(final IBinder token, final long operationId, int userId,
                 final IFaceServiceReceiver receiver, final String opPackageName,
                 boolean isKeyguardBypassEnabled) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             // TODO(b/152413782): If the sensor supports face detect and the device is encrypted or
             //  lockdown, something wrong happened. See similar path in FingerprintService.
@@ -285,10 +285,10 @@
                     statsClient, isKeyguard, isKeyguardBypassEnabled);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public long detectFace(final IBinder token, final int userId,
                 final IFaceServiceReceiver receiver, final String opPackageName) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
             if (!Utils.isKeyguard(getContext(), opPackageName)) {
                 Slog.w(TAG, "detectFace called from non-sysui package: " + opPackageName);
                 return -1;
@@ -312,12 +312,12 @@
                     BiometricsProtoEnums.CLIENT_KEYGUARD);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public void prepareForAuthentication(int sensorId, boolean requireConfirmation,
                 IBinder token, long operationId, int userId,
                 IBiometricSensorReceiver sensorReceiver, String opPackageName, long requestId,
                 int cookie, boolean allowBackgroundAuthentication) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -333,9 +333,9 @@
                     allowBackgroundAuthentication, isKeyguardBypassEnabled);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public void startPreparedClient(int sensorId, int cookie) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -346,10 +346,10 @@
             provider.startPreparedClient(sensorId, cookie);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public void cancelAuthentication(final IBinder token, final String opPackageName,
                 final long requestId) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
             if (provider == null) {
@@ -360,10 +360,10 @@
             provider.second.cancelAuthentication(provider.first, token, requestId);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public void cancelFaceDetect(final IBinder token, final String opPackageName,
                 final long requestId) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
             if (!Utils.isKeyguard(getContext(), opPackageName)) {
                 Slog.w(TAG, "cancelFaceDetect called from non-sysui package: "
                         + opPackageName);
@@ -379,10 +379,10 @@
             provider.second.cancelFaceDetect(provider.first, token, requestId);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public void cancelAuthenticationFromService(int sensorId, final IBinder token,
                 final String opPackageName, final long requestId) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -393,10 +393,10 @@
             provider.cancelAuthentication(sensorId, token, requestId);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public void remove(final IBinder token, final int faceId, final int userId,
                 final IFaceServiceReceiver receiver, final String opPackageName) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
             if (provider == null) {
@@ -408,10 +408,10 @@
                     opPackageName);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public void removeAll(final IBinder token, final int userId,
                 final IFaceServiceReceiver receiver, final String opPackageName) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final FaceServiceReceiver internalReceiver = new FaceServiceReceiver() {
                 int sensorsFinishedRemoving = 0;
@@ -441,10 +441,10 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public void addLockoutResetCallback(final IBiometricServiceLockoutResetCallback callback,
                 final String opPackageName) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
             mLockoutResetDispatcher.addCallback(callback, opPackageName);
         }
 
@@ -501,9 +501,9 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public boolean isHardwareDetected(int sensorId, String opPackageName) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final long token = Binder.clearCallingIdentity();
             try {
@@ -518,9 +518,9 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public List<Face> getEnrolledFaces(int sensorId, int userId, String opPackageName) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             if (userId != UserHandle.getCallingUserId()) {
                 Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS);
@@ -535,9 +535,9 @@
             return provider.getEnrolledFaces(sensorId, userId);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public boolean hasEnrolledFaces(int sensorId, int userId, String opPackageName) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             if (userId != UserHandle.getCallingUserId()) {
                 Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS);
@@ -552,9 +552,9 @@
             return provider.getEnrolledFaces(sensorId, userId).size() > 0;
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public @LockoutTracker.LockoutMode int getLockoutModeForUser(int sensorId, int userId) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -565,10 +565,10 @@
             return provider.getLockoutModeForUser(sensorId, userId);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override
         public void invalidateAuthenticatorId(int sensorId, int userId,
                 IInvalidationCallback callback) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -578,9 +578,9 @@
             provider.scheduleInvalidateAuthenticatorId(sensorId, userId, callback);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public long getAuthenticatorId(int sensorId, int userId) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -591,10 +591,10 @@
             return provider.getAuthenticatorId(sensorId, userId);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public void resetLockout(IBinder token, int sensorId, int userId, byte[] hardwareAuthToken,
                 String opPackageName) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -605,11 +605,11 @@
             provider.scheduleResetLockout(sensorId, userId, hardwareAuthToken);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override
         public void setFeature(final IBinder token, int userId, int feature, boolean enabled,
                 final byte[] hardwareAuthToken, IFaceServiceReceiver receiver,
                 final String opPackageName) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
             if (provider == null) {
@@ -621,10 +621,10 @@
                     hardwareAuthToken, receiver, opPackageName);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
         @Override
         public void getFeature(final IBinder token, int userId, int feature,
                 IFaceServiceReceiver receiver, final String opPackageName) {
-            Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
 
             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
             if (provider == null) {
@@ -667,10 +667,10 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public void registerAuthenticators(
                 @NonNull List<FaceSensorPropertiesInternal> hidlSensors) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             // Some HAL might not be started before the system service and will cause the code below
             // to wait, and some of the operations below might take a significant amount of time to
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java
index 9bd7476..73c272f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java
@@ -138,26 +138,26 @@
         mRandom = new Random();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void setTestHalEnabled(boolean enabled) {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mProvider.setTestHalEnabled(enabled);
         mSensor.setTestHalEnabled(enabled);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void startEnroll(int userId) {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mProvider.scheduleEnroll(mSensorId, new Binder(), new byte[69], userId, mReceiver,
                 mContext.getOpPackageName(), new int[0] /* disabledFeatures */,
                 null /* previewSurface */, false /* debugConsent */);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void finishEnroll(int userId) {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         int nextRandomId = mRandom.nextInt();
         while (mEnrollmentIds.contains(nextRandomId)) {
@@ -169,9 +169,9 @@
                 .onEnrollmentProgress(nextRandomId, 0 /* remaining */);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void acceptAuthentication(int userId)  {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         // Fake authentication with any of the existing faces
         List<Face> faces = FaceUtils.getInstance(mSensorId)
@@ -185,17 +185,17 @@
                 HardwareAuthTokenUtils.toHardwareAuthToken(new byte[69]));
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void rejectAuthentication(int userId)  {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mSensor.getSessionForUser(userId).getHalSessionCallback().onAuthenticationFailed();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     // TODO(b/178414967): replace with notifyAuthenticationFrame and notifyEnrollmentFrame.
     @Override
     public void notifyAcquired(int userId, int acquireInfo) {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         BaseFrame data = new BaseFrame();
         data.acquiredInfo = (byte) acquireInfo;
@@ -209,17 +209,17 @@
                 authenticationFrame);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void notifyError(int userId, int errorCode)  {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mSensor.getSessionForUser(userId).getHalSessionCallback().onError((byte) errorCode,
                 0 /* vendorCode */);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void cleanupInternalState(int userId)  {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         Slog.d(TAG, "cleanupInternalState: " + userId);
         mProvider.scheduleInternalCleanup(mSensorId, userId, new ClientMonitorCallback() {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java
index e7483b3..14af216 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java
@@ -127,25 +127,25 @@
         mRandom = new Random();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void setTestHalEnabled(boolean enabled) {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mFace10.setTestHalEnabled(enabled);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void startEnroll(int userId) {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mFace10.scheduleEnroll(mSensorId, new Binder(), new byte[69], userId, mReceiver,
                 mContext.getOpPackageName(), new int[0] /* disabledFeatures */,
                 null /* previewSurface */, false /* debugConsent */);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void finishEnroll(int userId) {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         int nextRandomId = mRandom.nextInt();
         while (mEnrollmentIds.contains(nextRandomId)) {
@@ -157,9 +157,9 @@
                 nextRandomId /* faceId */, userId, 0);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void acceptAuthentication(int userId) {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         // Fake authentication with any of the existing fingers
         List<Face> faces = FaceUtils.getLegacyInstance(mSensorId)
@@ -173,30 +173,30 @@
         mHalResultController.onAuthenticated(0 /* deviceId */, fid, userId, hat);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void rejectAuthentication(int userId) {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mHalResultController.onAuthenticated(0 /* deviceId */, 0 /* faceId */, userId, null);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void notifyAcquired(int userId, int acquireInfo) {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mHalResultController.onAcquired(0 /* deviceId */, userId, acquireInfo, 0 /* vendorCode */);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void notifyError(int userId, int errorCode) {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mHalResultController.onError(0 /* deviceId */, userId, errorCode, 0 /* vendorCode */);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void cleanupInternalState(int userId) {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mFace10.scheduleInternalCleanup(mSensorId, userId, new ClientMonitorCallback() {
             @Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 17b6373..2ba449a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -177,10 +177,10 @@
      * Receives the incoming binder calls from FingerprintManager.
      */
     private final IFingerprintService.Stub mServiceWrapper = new IFingerprintService.Stub() {
+        @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
         @Override
         public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
                 @NonNull String opPackageName) {
-            Utils.checkPermission(getContext(), TEST_BIOMETRIC);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
 
@@ -192,9 +192,9 @@
             return provider.createTestSession(sensorId, callback, opPackageName);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override
         public byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ProtoOutputStream proto = new ProtoOutputStream();
             final ServiceProvider provider = getProviderForSensor(sensorId);
@@ -216,10 +216,10 @@
             return FingerprintService.this.getSensorProperties();
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override
         public FingerprintSensorPropertiesInternal getSensorProperties(int sensorId,
                 @NonNull String opPackageName) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -230,10 +230,10 @@
             return provider.getSensorProperties(sensorId);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
         @Override // Binder call
         public void generateChallenge(IBinder token, int sensorId, int userId,
                 IFingerprintServiceReceiver receiver, String opPackageName) {
-            Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -244,10 +244,10 @@
             provider.scheduleGenerateChallenge(sensorId, userId, token, receiver, opPackageName);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
         @Override // Binder call
         public void revokeChallenge(IBinder token, int sensorId, int userId, String opPackageName,
                 long challenge) {
-            Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -259,11 +259,11 @@
                     challenge);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
         @Override // Binder call
         public long enroll(final IBinder token, @NonNull final byte[] hardwareAuthToken,
                 final int userId, final IFingerprintServiceReceiver receiver,
                 final String opPackageName, @FingerprintManager.EnrollReason int enrollReason) {
-            Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
 
             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
             if (provider == null) {
@@ -275,9 +275,9 @@
                     receiver, opPackageName, enrollReason);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
         @Override // Binder call
         public void cancelEnrollment(final IBinder token, long requestId) {
-            Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
 
             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
             if (provider == null) {
@@ -452,10 +452,10 @@
                     new CancellationSignal(), executor, promptCallback, operationId);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override
         public long detectFingerprint(final IBinder token, final int userId,
                 final IFingerprintServiceReceiver receiver, final String opPackageName) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
             if (!Utils.isKeyguard(getContext(), opPackageName)) {
                 Slog.w(TAG, "detectFingerprint called from non-sysui package: " + opPackageName);
                 return -1;
@@ -479,11 +479,11 @@
                     BiometricsProtoEnums.CLIENT_KEYGUARD);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
         @Override // Binder call
         public void prepareForAuthentication(int sensorId, IBinder token, long operationId,
                 int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
                 long requestId, int cookie, boolean allowBackgroundAuthentication) {
-            Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -498,9 +498,9 @@
                     allowBackgroundAuthentication);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
         @Override // Binder call
         public void startPreparedClient(int sensorId, int cookie) {
-            Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -541,10 +541,10 @@
             provider.second.cancelAuthentication(provider.first, token, requestId);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public void cancelFingerprintDetect(final IBinder token, final String opPackageName,
                 final long requestId) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
             if (!Utils.isKeyguard(getContext(), opPackageName)) {
                 Slog.w(TAG, "cancelFingerprintDetect called from non-sysui package: "
                         + opPackageName);
@@ -562,11 +562,11 @@
             provider.second.cancelAuthentication(provider.first, token, requestId);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
         @Override // Binder call
         public void cancelAuthenticationFromService(final int sensorId, final IBinder token,
                 final String opPackageName, final long requestId) {
 
-            Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
 
             Slog.d(TAG, "cancelAuthenticationFromService, sensorId: " + sensorId);
 
@@ -579,10 +579,10 @@
             provider.cancelAuthentication(sensorId, token, requestId);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
         @Override // Binder call
         public void remove(final IBinder token, final int fingerId, final int userId,
                 final IFingerprintServiceReceiver receiver, final String opPackageName) {
-            Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
 
             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
             if (provider == null) {
@@ -593,10 +593,10 @@
                     opPackageName);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public void removeAll(final IBinder token, final int userId,
                 final IFingerprintServiceReceiver receiver, final String opPackageName) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final FingerprintServiceReceiver internalReceiver = new FingerprintServiceReceiver() {
                 int sensorsFinishedRemoving = 0;
@@ -626,10 +626,10 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public void addLockoutResetCallback(final IBiometricServiceLockoutResetCallback callback,
                 final String opPackageName) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
             mLockoutResetDispatcher.addCallback(callback, opPackageName);
         }
 
@@ -710,9 +710,9 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public boolean isHardwareDetected(int sensorId, String opPackageName) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -723,9 +723,9 @@
             return provider.isHardwareDetected(sensorId);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
         @Override // Binder call
         public void rename(final int fingerId, final int userId, final String name) {
-            Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
             if (!Utils.isCurrentUserOrProfile(getContext(), userId)) {
                 return;
             }
@@ -779,8 +779,8 @@
                     .isEmpty();
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         public boolean hasEnrolledFingerprints(int sensorId, int userId, String opPackageName) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -791,9 +791,9 @@
             return provider.getEnrolledFingerprints(sensorId, userId).size() > 0;
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public @LockoutTracker.LockoutMode int getLockoutModeForUser(int sensorId, int userId) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -803,10 +803,10 @@
             return provider.getLockoutModeForUser(sensorId, userId);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override
         public void invalidateAuthenticatorId(int sensorId, int userId,
                 IInvalidationCallback callback) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -816,9 +816,9 @@
             provider.scheduleInvalidateAuthenticatorId(sensorId, userId, callback);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public long getAuthenticatorId(int sensorId, int userId) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -828,10 +828,10 @@
             return provider.getAuthenticatorId(sensorId, userId);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.RESET_FINGERPRINT_LOCKOUT)
         @Override // Binder call
         public void resetLockout(IBinder token, int sensorId, int userId,
                 @Nullable byte[] hardwareAuthToken, String opPackageName) {
-            Utils.checkPermission(getContext(), RESET_FINGERPRINT_LOCKOUT);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -842,28 +842,28 @@
             provider.scheduleResetLockout(sensorId, userId, hardwareAuthToken);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
         @Override
         public boolean isClientActive() {
-            Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
             return mGestureAvailabilityDispatcher.isAnySensorActive();
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
         @Override
         public void addClientActiveCallback(IFingerprintClientActiveCallback callback) {
-            Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
             mGestureAvailabilityDispatcher.registerCallback(callback);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
         @Override
         public void removeClientActiveCallback(IFingerprintClientActiveCallback callback) {
-            Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
             mGestureAvailabilityDispatcher.removeCallback(callback);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public void registerAuthenticators(
                 @NonNull List<FingerprintSensorPropertiesInternal> hidlSensors) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             // Some HAL might not be started before the system service and will cause the code below
             // to wait, and some of the operations below might take a significant amount of time to
@@ -885,10 +885,10 @@
             thread.quitSafely();
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override
         public void addAuthenticatorsRegisteredCallback(
                 IFingerprintAuthenticatorsRegisteredCallback callback) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
             if (callback == null) {
                 Slog.e(TAG, "addAuthenticatorsRegisteredCallback, callback is null");
                 return;
@@ -907,10 +907,10 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override
         public void onPointerDown(long requestId, int sensorId, int x, int y,
                 float minor, float major) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -920,9 +920,9 @@
             provider.onPointerDown(requestId, sensorId, x, y, minor, major);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override
         public void onPointerUp(long requestId, int sensorId) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -932,9 +932,9 @@
             provider.onPointerUp(requestId, sensorId);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override
         public void onUiReady(long requestId, int sensorId) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
@@ -944,18 +944,18 @@
             provider.onUiReady(requestId, sensorId);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override
         public void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             for (ServiceProvider provider : mServiceProviders) {
                 provider.setUdfpsOverlayController(controller);
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override
         public void setSidefpsController(@NonNull ISidefpsController controller) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             for (ServiceProvider provider : mServiceProviders) {
                 provider.setSidefpsController(controller);
@@ -964,8 +964,17 @@
 
         @Override
         public void registerBiometricStateListener(@NonNull IBiometricStateListener listener) {
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
             FingerprintService.this.registerBiometricStateListener(listener);
         }
+
+        @Override
+        public void onPowerPressed() {
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            for (ServiceProvider provider : mServiceProviders) {
+                provider.onPowerPressed();
+            }
+        }
     };
 
     public FingerprintService(Context context) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/PowerPressHandler.java
similarity index 60%
copy from packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java
copy to services/core/java/com/android/server/biometrics/sensors/fingerprint/PowerPressHandler.java
index 2aaf6a5..288c372 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/PowerPressHandler.java
@@ -14,17 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone;
+package com.android.server.biometrics.sensors.fingerprint;
 
-import com.android.systemui.dagger.SysUISingleton;
-
-import dagger.Binds;
-import dagger.Module;
-
-/** Provides a {@link NotifPanelEvents} in {@link SysUISingleton} scope. */
-@Module
-public abstract class NotifPanelEventsModule {
-    @Binds
-    abstract NotifPanelEvents bindPanelEvents(
-            NotificationPanelViewController.PanelEventsEmitter impl);
+/**
+ * Interface for handling power presses.
+ */
+public interface PowerPressHandler {
+    /**
+     * Indicates a power press has occurred.
+     */
+    void onPowerPressed();
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
index 4dfc738..275d7e4 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
@@ -153,6 +153,8 @@
 
     void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller);
 
+    void onPowerPressed();
+
     /**
      * Sets side-fps controller
      * @param controller side-fps controller
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
index ba7202f..4181b99 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
@@ -131,25 +131,25 @@
         mRandom = new Random();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void setTestHalEnabled(boolean enabled) {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mProvider.setTestHalEnabled(enabled);
         mSensor.setTestHalEnabled(enabled);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void startEnroll(int userId) {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mProvider.scheduleEnroll(mSensorId, new Binder(), new byte[69], userId, mReceiver,
                 mContext.getOpPackageName(), FingerprintManager.ENROLL_ENROLL);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void finishEnroll(int userId) {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         int nextRandomId = mRandom.nextInt();
         while (mEnrollmentIds.contains(nextRandomId)) {
@@ -161,9 +161,9 @@
                 .onEnrollmentProgress(nextRandomId, 0 /* remaining */);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void acceptAuthentication(int userId)  {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         // Fake authentication with any of the existing fingers
         List<Fingerprint> fingerprints = FingerprintUtils.getInstance(mSensorId)
@@ -177,32 +177,32 @@
                 HardwareAuthTokenUtils.toHardwareAuthToken(new byte[69]));
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void rejectAuthentication(int userId)  {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mSensor.getSessionForUser(userId).getHalSessionCallback().onAuthenticationFailed();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void notifyAcquired(int userId, int acquireInfo)  {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mSensor.getSessionForUser(userId).getHalSessionCallback()
                 .onAcquired((byte) acquireInfo, 0 /* vendorCode */);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void notifyError(int userId, int errorCode)  {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mSensor.getSessionForUser(userId).getHalSessionCallback().onError((byte) errorCode,
                 0 /* vendorCode */);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void cleanupInternalState(int userId)  {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         Slog.d(TAG, "cleanupInternalState: " + userId);
         mProvider.scheduleInternalCleanup(mSensorId, userId, new ClientMonitorCallback() {
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
index 79e3bf5..e1626f0 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
@@ -21,6 +21,7 @@
 import android.app.TaskStackListener;
 import android.content.Context;
 import android.hardware.biometrics.BiometricAuthenticator;
+import android.hardware.biometrics.BiometricConstants;
 import android.hardware.biometrics.BiometricFingerprintConstants;
 import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcquired;
 import android.hardware.biometrics.common.ICancellationSignal;
@@ -29,10 +30,15 @@
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
 import android.hardware.fingerprint.ISidefpsController;
 import android.hardware.fingerprint.IUdfpsOverlayController;
+import android.os.Build;
+import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
+import android.provider.Settings;
 import android.util.Slog;
 
+import com.android.internal.R;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
 import com.android.server.biometrics.log.CallbackWithProbe;
@@ -46,17 +52,18 @@
 import com.android.server.biometrics.sensors.LockoutConsumer;
 import com.android.server.biometrics.sensors.LockoutTracker;
 import com.android.server.biometrics.sensors.SensorOverlays;
+import com.android.server.biometrics.sensors.fingerprint.PowerPressHandler;
 import com.android.server.biometrics.sensors.fingerprint.Udfps;
 
 import java.util.ArrayList;
 import java.util.function.Supplier;
 
 /**
- * Fingerprint-specific authentication client supporting the
- * {@link android.hardware.biometrics.fingerprint.IFingerprint} AIDL interface.
+ * Fingerprint-specific authentication client supporting the {@link
+ * android.hardware.biometrics.fingerprint.IFingerprint} AIDL interface.
  */
-class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession> implements
-        Udfps, LockoutConsumer {
+class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
+        implements Udfps, LockoutConsumer, PowerPressHandler {
     private static final String TAG = "FingerprintAuthenticationClient";
 
     @NonNull private final LockoutCache mLockoutCache;
@@ -64,33 +71,88 @@
     @NonNull private final FingerprintSensorPropertiesInternal mSensorProps;
     @NonNull private final CallbackWithProbe<Probe> mALSProbeCallback;
 
-    @Nullable private ICancellationSignal mCancellationSignal;
+    @Nullable
+    private ICancellationSignal mCancellationSignal;
     private boolean mIsPointerDown;
+    private final Handler mHandler;
 
-    FingerprintAuthenticationClient(@NonNull Context context,
+    private static final int MESSAGE_IGNORE_AUTH = 1;
+    private static final int MESSAGE_AUTH_SUCCESS = 2;
+    private long mWaitForAuthKeyguard;
+    private long mWaitForAuthBp;
+    private long mIgnoreAuthFor;
+
+    FingerprintAuthenticationClient(
+            @NonNull Context context,
             @NonNull Supplier<AidlSession> lazyDaemon,
-            @NonNull IBinder token, long requestId,
-            @NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId,
-            boolean restricted, @NonNull String owner, int cookie, boolean requireConfirmation,
+            @NonNull IBinder token,
+            long requestId,
+            @NonNull ClientMonitorCallbackConverter listener,
+            int targetUserId,
+            long operationId,
+            boolean restricted,
+            @NonNull String owner,
+            int cookie,
+            boolean requireConfirmation,
             int sensorId,
-            @NonNull BiometricLogger biometricLogger, @NonNull BiometricContext biometricContext,
+            @NonNull BiometricLogger biometricLogger,
+            @NonNull BiometricContext biometricContext,
             boolean isStrongBiometric,
-            @Nullable TaskStackListener taskStackListener, @NonNull LockoutCache lockoutCache,
+            @Nullable TaskStackListener taskStackListener,
+            @NonNull LockoutCache lockoutCache,
             @Nullable IUdfpsOverlayController udfpsOverlayController,
             @Nullable ISidefpsController sidefpsController,
             boolean allowBackgroundAuthentication,
-            @NonNull FingerprintSensorPropertiesInternal sensorProps) {
-        super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted, owner,
-                cookie, requireConfirmation, sensorId,
-                biometricLogger, biometricContext,
-                isStrongBiometric, taskStackListener,
-                lockoutCache, allowBackgroundAuthentication, true /* shouldVibrate */,
+            @NonNull FingerprintSensorPropertiesInternal sensorProps,
+            @NonNull Handler handler) {
+        super(
+                context,
+                lazyDaemon,
+                token,
+                listener,
+                targetUserId,
+                operationId,
+                restricted,
+                owner,
+                cookie,
+                requireConfirmation,
+                sensorId,
+                biometricLogger,
+                biometricContext,
+                isStrongBiometric,
+                taskStackListener,
+                lockoutCache,
+                allowBackgroundAuthentication,
+                true /* shouldVibrate */,
                 false /* isKeyguardBypassEnabled */);
         setRequestId(requestId);
         mLockoutCache = lockoutCache;
         mSensorOverlays = new SensorOverlays(udfpsOverlayController, sidefpsController);
         mSensorProps = sensorProps;
         mALSProbeCallback = getLogger().createALSCallback(false /* startWithClient */);
+        mHandler = handler;
+
+        mWaitForAuthKeyguard =
+                context.getResources()
+                        .getInteger(R.integer.config_sidefpsKeyguardPowerPressWindow);
+        mWaitForAuthBp =
+                context.getResources().getInteger(R.integer.config_sidefpsBpPowerPressWindow);
+        mIgnoreAuthFor =
+                context.getResources().getInteger(R.integer.config_sidefpsPostAuthDowntime);
+
+        if (mSensorProps.isAnySidefpsType()) {
+            if (Build.isDebuggable()) {
+                mWaitForAuthKeyguard = Settings.Secure.getIntForUser(context.getContentResolver(),
+                        Settings.Secure.FINGERPRINT_SIDE_FPS_KG_POWER_WINDOW,
+                        (int) mWaitForAuthKeyguard, UserHandle.USER_CURRENT);
+                mWaitForAuthBp = Settings.Secure.getIntForUser(context.getContentResolver(),
+                        Settings.Secure.FINGERPRINT_SIDE_FPS_BP_POWER_WINDOW, (int) mWaitForAuthBp,
+                        UserHandle.USER_CURRENT);
+                mIgnoreAuthFor = Settings.Secure.getIntForUser(context.getContentResolver(),
+                        Settings.Secure.FINGERPRINT_SIDE_FPS_AUTH_DOWNTIME, (int) mIgnoreAuthFor,
+                        UserHandle.USER_CURRENT);
+            }
+        }
     }
 
     @Override
@@ -108,8 +170,8 @@
     @NonNull
     @Override
     protected ClientMonitorCallback wrapCallbackForStart(@NonNull ClientMonitorCallback callback) {
-        return new ClientMonitorCompositeCallback(mALSProbeCallback,
-                getBiometricContextUnsubscriber(), callback);
+        return new ClientMonitorCompositeCallback(
+                mALSProbeCallback, getBiometricContextUnsubscriber(), callback);
     }
 
     @Override
@@ -126,16 +188,37 @@
     }
 
     @Override
-    public void onAuthenticated(BiometricAuthenticator.Identifier identifier,
-            boolean authenticated, ArrayList<Byte> token) {
-        super.onAuthenticated(identifier, authenticated, token);
+    public void onAuthenticated(
+            BiometricAuthenticator.Identifier identifier,
+            boolean authenticated,
+            ArrayList<Byte> token) {
 
-        if (authenticated) {
-            mState = STATE_STOPPED;
-            mSensorOverlays.hide(getSensorId());
-        } else {
-            mState = STATE_STARTED_PAUSED_ATTEMPTED;
+        long delay = 0;
+        if (authenticated && mSensorProps.isAnySidefpsType()) {
+            if (mHandler.hasMessages(MESSAGE_IGNORE_AUTH)) {
+                Slog.i(TAG, "(sideFPS) Ignoring auth due to recent power press");
+                onErrorInternal(BiometricConstants.BIOMETRIC_ERROR_POWER_PRESSED, 0, true);
+                return;
+            }
+            delay = isKeyguard() ? mWaitForAuthKeyguard : mWaitForAuthBp;
+            Slog.i(TAG, "(sideFPS) Auth succeeded, sideFps waiting for power until: " + delay);
         }
+
+        mHandler.postDelayed(
+                () -> {
+                    if (authenticated && mSensorProps.isAnySidefpsType()) {
+                        Slog.i(TAG, "(sideFPS): No power press detected, sending auth");
+                    }
+                    super.onAuthenticated(identifier, authenticated, token);
+                    if (authenticated) {
+                        mState = STATE_STOPPED;
+                        mSensorOverlays.hide(getSensorId());
+                    } else {
+                        mState = STATE_STARTED_PAUSED_ATTEMPTED;
+                    }
+                },
+                MESSAGE_AUTH_SUCCESS,
+                delay);
     }
 
     @Override
@@ -165,7 +248,8 @@
             mCancellationSignal = doAuthenticate();
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception", e);
-            onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
+            onError(
+                    BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
                     0 /* vendorCode */);
             mSensorOverlays.hide(getSensorId());
             mCallback.onClientFinished(this, false /* success */);
@@ -177,15 +261,18 @@
 
         if (session.hasContextMethods()) {
             final OperationContext opContext = getOperationContext();
-            final ICancellationSignal cancel =  session.getSession().authenticateWithContext(
-                    mOperationId, opContext);
-            getBiometricContext().subscribe(opContext, ctx -> {
-                try {
-                    session.getSession().onContextChanged(ctx);
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Unable to notify context changed", e);
-                }
-            });
+            final ICancellationSignal cancel =
+                    session.getSession().authenticateWithContext(mOperationId, opContext);
+            getBiometricContext()
+                    .subscribe(
+                            opContext,
+                            ctx -> {
+                                try {
+                                    session.getSession().onContextChanged(ctx);
+                                } catch (RemoteException e) {
+                                    Slog.e(TAG, "Unable to notify context changed", e);
+                                }
+                            });
             return cancel;
         } else {
             return session.getSession().authenticate(mOperationId);
@@ -202,7 +289,8 @@
                 mCancellationSignal.cancel();
             } catch (RemoteException e) {
                 Slog.e(TAG, "Remote exception", e);
-                onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
+                onError(
+                        BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
                         0 /* vendorCode */);
                 mCallback.onClientFinished(this, false /* success */);
             }
@@ -284,8 +372,13 @@
         mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_TIMED);
         // Lockout metrics are logged as an error code.
         final int error = BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT;
-        getLogger().logOnError(getContext(), getOperationContext(),
-                error, 0 /* vendorCode */, getTargetUserId());
+        getLogger()
+                .logOnError(
+                        getContext(),
+                        getOperationContext(),
+                        error,
+                        0 /* vendorCode */,
+                        getTargetUserId());
 
         try {
             getListener().onError(getSensorId(), getCookie(), error, 0 /* vendorCode */);
@@ -303,8 +396,13 @@
         mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_PERMANENT);
         // Lockout metrics are logged as an error code.
         final int error = BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT_PERMANENT;
-        getLogger().logOnError(getContext(), getOperationContext(),
-                error, 0 /* vendorCode */, getTargetUserId());
+        getLogger()
+                .logOnError(
+                        getContext(),
+                        getOperationContext(),
+                        error,
+                        0 /* vendorCode */,
+                        getTargetUserId());
 
         try {
             getListener().onError(getSensorId(), getCookie(), error, 0 /* vendorCode */);
@@ -315,4 +413,19 @@
         mSensorOverlays.hide(getSensorId());
         mCallback.onClientFinished(this, false /* success */);
     }
+
+    @Override
+    public void onPowerPressed() {
+        if (mSensorProps.isAnySidefpsType()) {
+            Slog.i(TAG, "(sideFPS): onPowerPressed");
+            if (mHandler.hasMessages(MESSAGE_AUTH_SUCCESS)) {
+                Slog.i(TAG, "(sideFPS): Ignoring auth in queue");
+                mHandler.removeMessages(MESSAGE_AUTH_SUCCESS);
+                // Do not call onError() as that will send an additional callback to coex.
+                onErrorInternal(BiometricConstants.BIOMETRIC_ERROR_POWER_PRESSED, 0, true);
+            }
+            mHandler.removeMessages(MESSAGE_IGNORE_AUTH);
+            mHandler.postDelayed(() -> {}, MESSAGE_IGNORE_AUTH, mIgnoreAuthFor);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
index f23659c..f4f0a19 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
@@ -22,6 +22,7 @@
 import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricFingerprintConstants;
 import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcquired;
+import android.hardware.biometrics.BiometricStateListener;
 import android.hardware.biometrics.common.ICancellationSignal;
 import android.hardware.biometrics.common.OperationContext;
 import android.hardware.biometrics.fingerprint.PointerContext;
@@ -139,7 +140,7 @@
                 controller.onEnrollmentHelp(getSensorId());
             }
         });
-
+        mCallback.onBiometricAction(BiometricStateListener.ACTION_SENSOR_TOUCH);
         super.onAcquired(acquiredInfo, vendorCode);
     }
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index 668f4c4..2dc00520 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -67,6 +67,7 @@
 import com.android.server.biometrics.sensors.PerformanceTracker;
 import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
 import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
+import com.android.server.biometrics.sensors.fingerprint.PowerPressHandler;
 import com.android.server.biometrics.sensors.fingerprint.ServiceProvider;
 import com.android.server.biometrics.sensors.fingerprint.Udfps;
 
@@ -388,6 +389,11 @@
                 }
 
                 @Override
+                public void onBiometricAction(int action) {
+                    mBiometricStateCallback.onBiometricAction(action);
+                }
+
+                @Override
                 public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
                         boolean success) {
                     mBiometricStateCallback.onClientFinished(clientMonitor, success);
@@ -441,7 +447,7 @@
                     mBiometricContext, isStrongBiometric,
                     mTaskStackListener, mSensors.get(sensorId).getLockoutCache(),
                     mUdfpsOverlayController, mSidefpsController, allowBackgroundAuthentication,
-                    mSensors.get(sensorId).getSensorProperties());
+                    mSensors.get(sensorId).getSensorProperties(), mHandler);
             scheduleForSensor(sensorId, client, mBiometricStateCallback);
         });
     }
@@ -623,6 +629,21 @@
     }
 
     @Override
+    public void onPowerPressed() {
+        for (int i = 0; i < mSensors.size(); i++) {
+            final Sensor sensor = mSensors.valueAt(i);
+            BaseClientMonitor client = sensor.getScheduler().getCurrentClient();
+            if (client == null) {
+                return;
+            }
+            if (!(client instanceof PowerPressHandler)) {
+                continue;
+            }
+            ((PowerPressHandler) client).onPowerPressed();
+        }
+    }
+
+    @Override
     public void setSidefpsController(@NonNull ISidefpsController controller) {
         mSidefpsController = controller;
     }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java
index a58bb89..682c005 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java
@@ -132,24 +132,24 @@
         mRandom = new Random();
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void setTestHalEnabled(boolean enabled) {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mFingerprint21.setTestHalEnabled(enabled);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void startEnroll(int userId) {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mFingerprint21.scheduleEnroll(mSensorId, new Binder(), new byte[69], userId, mReceiver,
                 mContext.getOpPackageName(), FingerprintManager.ENROLL_ENROLL);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void finishEnroll(int userId) {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         int nextRandomId = mRandom.nextInt();
         while (mEnrollmentIds.contains(nextRandomId)) {
@@ -161,9 +161,9 @@
                 nextRandomId /* fingerId */, userId, 0);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void acceptAuthentication(int userId)  {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         // Fake authentication with any of the existing fingers
         List<Fingerprint> fingerprints = FingerprintUtils.getLegacyInstance(mSensorId)
@@ -177,30 +177,30 @@
         mHalResultController.onAuthenticated(0 /* deviceId */, fid, userId, hat);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void rejectAuthentication(int userId)  {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mHalResultController.onAuthenticated(0 /* deviceId */, 0 /* fingerId */, userId, null);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void notifyAcquired(int userId, int acquireInfo)  {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mHalResultController.onAcquired(0 /* deviceId */, acquireInfo, 0 /* vendorCode */);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void notifyError(int userId, int errorCode)  {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mHalResultController.onError(0 /* deviceId */, errorCode, 0 /* vendorCode */);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
     @Override
     public void cleanupInternalState(int userId)  {
-        Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         mFingerprint21.scheduleInternalCleanup(mSensorId, userId, new ClientMonitorCallback() {
             @Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
index 0c7bcc7..ed482f0 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
@@ -603,6 +603,11 @@
                 }
 
                 @Override
+                public void onBiometricAction(int action) {
+                    mBiometricStateCallback.onBiometricAction(action);
+                }
+
+                @Override
                 public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
                         boolean success) {
                     mBiometricStateCallback.onClientFinished(clientMonitor, success);
@@ -828,6 +833,11 @@
     }
 
     @Override
+    public void onPowerPressed() {
+        Slog.e(TAG, "onPowerPressed not supported for HIDL clients");
+    }
+
+    @Override
     public void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller) {
         mUdfpsOverlayController = controller;
     }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java
index 1d478e5..2a59c8c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricFingerprintConstants;
+import android.hardware.biometrics.BiometricStateListener;
 import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
 import android.hardware.fingerprint.Fingerprint;
 import android.hardware.fingerprint.FingerprintManager;
@@ -151,6 +152,8 @@
                 controller.onEnrollmentHelp(getSensorId());
             }
         });
+
+        mCallback.onBiometricAction(BiometricStateListener.ACTION_SENSOR_TOUCH);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java b/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java
index d684bb8..ff1e762 100644
--- a/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java
@@ -55,9 +55,9 @@
      * Receives the incoming binder calls from IrisManager.
      */
     private final class IrisServiceWrapper extends IIrisService.Stub {
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override // Binder call
         public void registerAuthenticators(@NonNull List<SensorPropertiesInternal> hidlSensors) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             // Some HAL might not be started before the system service and will cause the code below
             // to wait, and some of the operations below might take a significant amount of time to
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index b425420..66ef5e7 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -355,7 +355,7 @@
                 case UsbManager.ACTION_USB_DEVICE_ATTACHED:
                 case UsbManager.ACTION_USB_DEVICE_DETACHED:
                     synchronized (mLock) {
-                        UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
+                        UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE, android.hardware.usb.UsbDevice.class);
                         if (device != null) {
                             notifyUsbDeviceHotplugLocked(device,
                                     action.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED));
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index 61350bb..076ac2b 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -215,9 +215,12 @@
     private class ListenerInfo {
         final int mUid;
         final String mPackageName;
-        ListenerInfo(int uid, String packageName) {
+        final String mAttributionTag;
+
+        ListenerInfo(int uid, String packageName, String attributionTag) {
             mUid = uid;
             mPackageName = packageName;
+            mAttributionTag = attributionTag;
         }
     }
 
@@ -355,27 +358,43 @@
         }
 
         @Override
-        public void setPrimaryClip(ClipData clip, String callingPackage, @UserIdInt int userId) {
-            checkAndSetPrimaryClip(clip, callingPackage, userId, callingPackage);
+        public void setPrimaryClip(
+                ClipData clip,
+                String callingPackage,
+                String attributionTag,
+                @UserIdInt int userId) {
+            checkAndSetPrimaryClip(clip, callingPackage, attributionTag, userId, callingPackage);
         }
 
         @Override
         public void setPrimaryClipAsPackage(
-                ClipData clip, String callingPackage, @UserIdInt int userId, String sourcePackage) {
+                ClipData clip,
+                String callingPackage,
+                String attributionTag,
+                @UserIdInt int userId,
+                String sourcePackage) {
             getContext().enforceCallingOrSelfPermission(Manifest.permission.SET_CLIP_SOURCE,
                     "Requires SET_CLIP_SOURCE permission");
-            checkAndSetPrimaryClip(clip, callingPackage, userId, sourcePackage);
+            checkAndSetPrimaryClip(clip, callingPackage, attributionTag, userId, sourcePackage);
         }
 
         private void checkAndSetPrimaryClip(
-                ClipData clip, String callingPackage, @UserIdInt int userId, String sourcePackage) {
+                ClipData clip,
+                String callingPackage,
+                String attributionTag,
+                @UserIdInt int userId,
+                String sourcePackage) {
             if (clip == null || clip.getItemCount() <= 0) {
                 throw new IllegalArgumentException("No items");
             }
             final int intendingUid = getIntendingUid(callingPackage, userId);
             final int intendingUserId = UserHandle.getUserId(intendingUid);
-            if (!clipboardAccessAllowed(AppOpsManager.OP_WRITE_CLIPBOARD, callingPackage,
-                    intendingUid, intendingUserId)) {
+            if (!clipboardAccessAllowed(
+                    AppOpsManager.OP_WRITE_CLIPBOARD,
+                    callingPackage,
+                    attributionTag,
+                    intendingUid,
+                    intendingUserId)) {
                 return;
             }
             checkDataOwner(clip, intendingUid);
@@ -392,8 +411,13 @@
                         PROPERTY_AUTO_CLEAR_ENABLED, true)) {
                     mClipboardClearHandler.removeEqualMessages(ClipboardClearHandler.MSG_CLEAR,
                             userId);
-                    Message clearMessage = Message.obtain(mClipboardClearHandler,
-                            ClipboardClearHandler.MSG_CLEAR, userId, intendingUid, userId);
+                    Message clearMessage =
+                            Message.obtain(
+                                    mClipboardClearHandler,
+                                    ClipboardClearHandler.MSG_CLEAR,
+                                    userId,
+                                    intendingUid,
+                                    userId);
                     mClipboardClearHandler.sendMessageDelayed(clearMessage,
                             getTimeoutForAutoClear());
                 }
@@ -409,11 +433,16 @@
         }
 
         @Override
-        public void clearPrimaryClip(String callingPackage, @UserIdInt int userId) {
+        public void clearPrimaryClip(
+                String callingPackage, String attributionTag, @UserIdInt int userId) {
             final int intendingUid = getIntendingUid(callingPackage, userId);
             final int intendingUserId = UserHandle.getUserId(intendingUid);
-            if (!clipboardAccessAllowed(AppOpsManager.OP_WRITE_CLIPBOARD, callingPackage,
-                    intendingUid, intendingUserId)) {
+            if (!clipboardAccessAllowed(
+                    AppOpsManager.OP_WRITE_CLIPBOARD,
+                    callingPackage,
+                    attributionTag,
+                    intendingUid,
+                    intendingUserId)) {
                 return;
             }
             synchronized (mLock) {
@@ -424,11 +453,15 @@
         }
 
         @Override
-        public ClipData getPrimaryClip(String pkg, @UserIdInt int userId) {
+        public ClipData getPrimaryClip(String pkg, String attributionTag, @UserIdInt int userId) {
             final int intendingUid = getIntendingUid(pkg, userId);
             final int intendingUserId = UserHandle.getUserId(intendingUid);
-            if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, pkg,
-                    intendingUid, intendingUserId)
+            if (!clipboardAccessAllowed(
+                            AppOpsManager.OP_READ_CLIPBOARD,
+                            pkg,
+                            attributionTag,
+                            intendingUid,
+                            intendingUserId)
                     || isDeviceLocked(intendingUserId)) {
                 return null;
             }
@@ -453,12 +486,17 @@
         }
 
         @Override
-        public ClipDescription getPrimaryClipDescription(String callingPackage,
-                @UserIdInt int userId) {
+        public ClipDescription getPrimaryClipDescription(
+                String callingPackage, String attributionTag, @UserIdInt int userId) {
             final int intendingUid = getIntendingUid(callingPackage, userId);
             final int intendingUserId = UserHandle.getUserId(intendingUid);
-            if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
-                    intendingUid, intendingUserId, false)
+            if (!clipboardAccessAllowed(
+                            AppOpsManager.OP_READ_CLIPBOARD,
+                            callingPackage,
+                            attributionTag,
+                            intendingUid,
+                            intendingUserId,
+                            false)
                     || isDeviceLocked(intendingUserId)) {
                 return null;
             }
@@ -470,11 +508,17 @@
         }
 
         @Override
-        public boolean hasPrimaryClip(String callingPackage, @UserIdInt int userId) {
+        public boolean hasPrimaryClip(
+                String callingPackage, String attributionTag, @UserIdInt int userId) {
             final int intendingUid = getIntendingUid(callingPackage, userId);
             final int intendingUserId = UserHandle.getUserId(intendingUid);
-            if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
-                    intendingUid, intendingUserId, false)
+            if (!clipboardAccessAllowed(
+                            AppOpsManager.OP_READ_CLIPBOARD,
+                            callingPackage,
+                            attributionTag,
+                            intendingUid,
+                            intendingUserId,
+                            false)
                     || isDeviceLocked(intendingUserId)) {
                 return false;
             }
@@ -484,19 +528,28 @@
         }
 
         @Override
-        public void addPrimaryClipChangedListener(IOnPrimaryClipChangedListener listener,
-                String callingPackage, @UserIdInt int userId) {
+        public void addPrimaryClipChangedListener(
+                IOnPrimaryClipChangedListener listener,
+                String callingPackage,
+                String attributionTag,
+                @UserIdInt int userId) {
             final int intendingUid = getIntendingUid(callingPackage, userId);
             final int intendingUserId = UserHandle.getUserId(intendingUid);
             synchronized (mLock) {
-                getClipboardLocked(intendingUserId).primaryClipListeners.register(listener,
-                        new ListenerInfo(intendingUid, callingPackage));
+                getClipboardLocked(intendingUserId)
+                        .primaryClipListeners
+                        .register(
+                                listener,
+                                new ListenerInfo(intendingUid, callingPackage, attributionTag));
             }
         }
 
         @Override
-        public void removePrimaryClipChangedListener(IOnPrimaryClipChangedListener listener,
-                String callingPackage, @UserIdInt int userId) {
+        public void removePrimaryClipChangedListener(
+                IOnPrimaryClipChangedListener listener,
+                String callingPackage,
+                String attributionTag,
+                @UserIdInt int userId) {
             final int intendingUserId = getIntendingUserId(callingPackage, userId);
             synchronized (mLock) {
                 getClipboardLocked(intendingUserId).primaryClipListeners.unregister(listener);
@@ -504,11 +557,16 @@
         }
 
         @Override
-        public boolean hasClipboardText(String callingPackage, int userId) {
+        public boolean hasClipboardText(String callingPackage, String attributionTag, int userId) {
             final int intendingUid = getIntendingUid(callingPackage, userId);
             final int intendingUserId = UserHandle.getUserId(intendingUid);
-            if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
-                    intendingUid, intendingUserId, false)
+            if (!clipboardAccessAllowed(
+                            AppOpsManager.OP_READ_CLIPBOARD,
+                            callingPackage,
+                            attributionTag,
+                            intendingUid,
+                            intendingUserId,
+                            false)
                     || isDeviceLocked(intendingUserId)) {
                 return false;
             }
@@ -523,13 +581,19 @@
         }
 
         @Override
-        public String getPrimaryClipSource(String callingPackage, int userId) {
+        public String getPrimaryClipSource(
+                String callingPackage, String attributionTag, int userId) {
             getContext().enforceCallingOrSelfPermission(Manifest.permission.SET_CLIP_SOURCE,
                     "Requires SET_CLIP_SOURCE permission");
             final int intendingUid = getIntendingUid(callingPackage, userId);
             final int intendingUserId = UserHandle.getUserId(intendingUid);
-            if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
-                    intendingUid, intendingUserId, false)
+            if (!clipboardAccessAllowed(
+                            AppOpsManager.OP_READ_CLIPBOARD,
+                            callingPackage,
+                            attributionTag,
+                            intendingUid,
+                            intendingUserId,
+                            false)
                     || isDeviceLocked(intendingUserId)) {
                 return null;
             }
@@ -718,8 +782,12 @@
                     ListenerInfo li = (ListenerInfo)
                             clipboard.primaryClipListeners.getBroadcastCookie(i);
 
-                    if (clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, li.mPackageName,
-                            li.mUid, UserHandle.getUserId(li.mUid))) {
+                    if (clipboardAccessAllowed(
+                            AppOpsManager.OP_READ_CLIPBOARD,
+                            li.mPackageName,
+                            li.mAttributionTag,
+                            li.mUid,
+                            UserHandle.getUserId(li.mUid))) {
                         clipboard.primaryClipListeners.getBroadcastItem(i)
                                 .dispatchPrimaryClipChanged();
                     }
@@ -965,13 +1033,18 @@
         }
     }
 
-    private boolean clipboardAccessAllowed(int op, String callingPackage, int uid,
-            @UserIdInt int userId) {
-        return clipboardAccessAllowed(op, callingPackage, uid, userId, true);
+    private boolean clipboardAccessAllowed(
+            int op, String callingPackage, String attributionTag, int uid, @UserIdInt int userId) {
+        return clipboardAccessAllowed(op, callingPackage, attributionTag, uid, userId, true);
     }
 
-    private boolean clipboardAccessAllowed(int op, String callingPackage, int uid,
-            @UserIdInt int userId, boolean shouldNoteOp) {
+    private boolean clipboardAccessAllowed(
+            int op,
+            String callingPackage,
+            String attributionTag,
+            int uid,
+            @UserIdInt int userId,
+            boolean shouldNoteOp) {
 
         boolean allowed;
 
@@ -1040,7 +1113,7 @@
         // Finally, check the app op.
         int appOpsResult;
         if (shouldNoteOp) {
-            appOpsResult = mAppOps.noteOp(op, uid, callingPackage);
+            appOpsResult = mAppOps.noteOp(op, uid, callingPackage, attributionTag, null);
         } else {
             appOpsResult = mAppOps.checkOp(op, uid, callingPackage);
         }
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 4e5ce8a..baeaa50 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -186,7 +186,7 @@
     private static final boolean LOGD = true;
     private static final String ANDROID_KEYSTORE_PROVIDER = "AndroidKeyStore";
     /** Key containing prefix of vpn app excluded list */
-    @VisibleForTesting static final String VPN_APP_EXCLUDED = "VPN_APP_EXCLUDED_";
+    @VisibleForTesting static final String VPN_APP_EXCLUDED = "VPNAPPEXCLUDED_";
 
     // Length of time (in milliseconds) that an app hosting an always-on VPN is placed on
     // the device idle allowlist during service launch and VPN bootstrap.
@@ -1095,7 +1095,7 @@
         // Except for Settings and VpnDialogs, the caller should be matched one of oldPackage or
         // newPackage. Otherwise, non VPN owner might get the VPN always-on status of the VPN owner.
         // See b/191382886.
-        if (mContext.checkCallingOrSelfPermission(CONTROL_VPN) != PERMISSION_GRANTED) {
+        if (!hasControlVpnPermission()) {
             if (oldPackage != null) {
                 verifyCallingUidAndPackage(oldPackage);
             }
@@ -1182,20 +1182,9 @@
                 cleanupVpnStateLocked();
             } else if (mVpnRunner != null) {
                 if (!VpnConfig.LEGACY_VPN.equals(mPackage)) {
-                    mAppOpsManager.finishOp(
-                            AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER, mOwnerUID, mPackage, null);
-                    // The underlying network, NetworkCapabilities and LinkProperties are not
-                    // necessary to send to VPN app since the purpose of this event is to notify
-                    // VPN app that VPN is deactivated by the user.
-                    // TODO(b/230548427): Remove SDK check once VPN related stuff are decoupled from
-                    //  ConnectivityServiceTest.
-                    if (SdkLevel.isAtLeastT()) {
-                        sendEventToVpnManagerApp(VpnManager.CATEGORY_EVENT_DEACTIVATED_BY_USER,
-                                -1 /* errorClass */, -1 /* errorCode*/, mPackage,
-                                getSessionKeyLocked(), makeVpnProfileStateLocked(),
-                                null /* underlyingNetwork */, null /* nc */, null /* lp */);
-                    }
+                    notifyVpnManagerVpnStopped(mPackage, mOwnerUID);
                 }
+
                 // cleanupVpnStateLocked() is called from mVpnRunner.exit()
                 mVpnRunner.exit();
             }
@@ -2056,6 +2045,10 @@
                 "Unauthorized Caller");
     }
 
+    private boolean hasControlVpnPermission() {
+        return mContext.checkCallingOrSelfPermission(CONTROL_VPN) == PERMISSION_GRANTED;
+    }
+
     private class Connection implements ServiceConnection {
         private IBinder mService;
 
@@ -3857,8 +3850,10 @@
             Binder.restoreCallingIdentity(token);
         }
 
-        // TODO: if package has CONTROL_VPN, grant the ACTIVATE_PLATFORM_VPN appop.
-        // This mirrors the prepareAndAuthorize that is used by VpnService.
+        // If package has CONTROL_VPN, grant the ACTIVATE_PLATFORM_VPN appop.
+        if (hasControlVpnPermission()) {
+            setPackageAuthorization(packageName, VpnManager.TYPE_VPN_PLATFORM);
+        }
 
         // Return whether the app is already pre-consented
         return isVpnProfilePreConsented(mContext, packageName);
@@ -4043,7 +4038,25 @@
         // To stop the VPN profile, the caller must be the current prepared package and must be
         // running an Ikev2VpnProfile.
         if (isCurrentIkev2VpnLocked(packageName)) {
-            prepareInternal(VpnConfig.LEGACY_VPN);
+            notifyVpnManagerVpnStopped(packageName, mOwnerUID);
+
+            mVpnRunner.exit();
+        }
+    }
+
+    private synchronized void notifyVpnManagerVpnStopped(String packageName, int ownerUID) {
+        mAppOpsManager.finishOp(
+                AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER, ownerUID, packageName, null);
+        // The underlying network, NetworkCapabilities and LinkProperties are not
+        // necessary to send to VPN app since the purpose of this event is to notify
+        // VPN app that VPN is deactivated by the user.
+        // TODO(b/230548427): Remove SDK check once VPN related stuff are decoupled from
+        //  ConnectivityServiceTest.
+        if (SdkLevel.isAtLeastT()) {
+            sendEventToVpnManagerApp(VpnManager.CATEGORY_EVENT_DEACTIVATED_BY_USER,
+                    -1 /* errorClass */, -1 /* errorCode*/, packageName,
+                    getSessionKeyLocked(), makeVpnProfileStateLocked(),
+                    null /* underlyingNetwork */, null /* nc */, null /* lp */);
         }
     }
 
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 75b4eb4..781920c 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -119,6 +119,13 @@
     @EnabledAfter(targetSdkVersion = android.os.Build.VERSION_CODES.S_V2)
     public static final long ACCOUNT_ACCESS_CHECK_CHANGE_ID = 201794303L;
 
+    /**
+     * Enables checking for authority access for the calling uid on all sync-related APIs.
+     */
+    @ChangeId
+    @EnabledAfter(targetSdkVersion = android.os.Build.VERSION_CODES.TIRAMISU)
+    public static final long AUTHORITY_ACCESS_CHECK_CHANGE_ID = 207133734L;
+
     public static class Lifecycle extends SystemService {
         private ContentService mService;
 
@@ -608,6 +615,9 @@
         if (!hasAccountAccess(true, account, callingUid)) {
             return;
         }
+        if (!hasAuthorityAccess(authority, callingUid, userId)) {
+            return;
+        }
 
         validateExtras(callingUid, extras);
         final int syncExemption = getSyncExemptionAndCleanUpExtrasForCaller(callingUid, extras);
@@ -661,6 +671,9 @@
         if (!hasAccountAccess(true, request.getAccount(), callingUid)) {
             return;
         }
+        if (!hasAuthorityAccess(request.getProvider(), callingUid, userId)) {
+            return;
+        }
 
         final Bundle extras = request.getBundle();
         validateExtras(callingUid, extras);
@@ -863,7 +876,12 @@
                 "no permission to read the sync settings for user " + userId);
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
                 "no permission to read the sync settings");
-        if (!hasAccountAccess(true, account, Binder.getCallingUid())) {
+
+        final int callingUid = Binder.getCallingUid();
+        if (!hasAccountAccess(true, account, callingUid)) {
+            return false;
+        }
+        if (!hasAuthorityAccess(providerName, callingUid, userId)) {
             return false;
         }
 
@@ -897,6 +915,9 @@
         if (!hasAccountAccess(true, account, callingUid)) {
             return;
         }
+        if (!hasAuthorityAccess(providerName, callingUid, userId)) {
+            return;
+        }
 
         final int syncExemptionFlag = getSyncExemptionForCaller(callingUid);
 
@@ -924,16 +945,19 @@
                 "no permission to write the sync settings");
 
         final int callingUid = Binder.getCallingUid();
+        final int userId = UserHandle.getCallingUserId();
         if (!hasAccountAccess(true, account, callingUid)) {
             return;
         }
+        if (!hasAuthorityAccess(authority, callingUid, userId)) {
+            return;
+        }
 
         validateExtras(callingUid, extras);
 
         pollFrequency = clampPeriod(pollFrequency);
         long defaultFlex = SyncStorageEngine.calculateDefaultFlexTime(pollFrequency);
 
-        int userId = UserHandle.getCallingUserId();
         final long identityToken = clearCallingIdentity();
         try {
             SyncStorageEngine.EndPoint info =
@@ -958,13 +982,16 @@
                 "no permission to write the sync settings");
 
         final int callingUid = Binder.getCallingUid();
+        final int userId = UserHandle.getCallingUserId();
         if (!hasAccountAccess(true, account, callingUid)) {
             return;
         }
+        if (!hasAuthorityAccess(authority, callingUid, userId)) {
+            return;
+        }
 
         validateExtras(callingUid, extras);
 
-        int userId = UserHandle.getCallingUserId();
         final long identityToken = clearCallingIdentity();
         try {
             getSyncManager().removePeriodicSync(
@@ -986,11 +1013,16 @@
         }
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
                 "no permission to read the sync settings");
-        if (!hasAccountAccess(true, account, Binder.getCallingUid())) {
+
+        final int callingUid = Binder.getCallingUid();
+        final int userId = UserHandle.getCallingUserId();
+        if (!hasAccountAccess(true, account, callingUid)) {
             return new ArrayList<>(); // return a new empty list for consistent behavior
         }
+        if (!hasAuthorityAccess(providerName, callingUid, userId)) {
+            return new ArrayList<>();
+        }
 
-        int userId = UserHandle.getCallingUserId();
         final long identityToken = clearCallingIdentity();
         try {
             return getSyncManager().getPeriodicSyncs(
@@ -1015,9 +1047,14 @@
                 "no permission to read the sync settings for user " + userId);
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
                 "no permission to read the sync settings");
-        if (!hasAccountAccess(true, account, Binder.getCallingUid())) {
+
+        final int callingUid = Binder.getCallingUid();
+        if (!hasAccountAccess(true, account, callingUid)) {
             return SyncStorageEngine.AuthorityInfo.NOT_SYNCABLE; // to keep behavior consistent
         }
+        if (!hasAuthorityAccess(providerName, callingUid, userId)) {
+            return SyncStorageEngine.AuthorityInfo.NOT_SYNCABLE;
+        }
 
         final long identityToken = clearCallingIdentity();
         try {
@@ -1052,6 +1089,9 @@
         if (!hasAccountAccess(true, account, callingUid)) {
             return;
         }
+        if (!hasAuthorityAccess(providerName, callingUid, userId)) {
+            return;
+        }
 
         final long identityToken = clearCallingIdentity();
         try {
@@ -1114,11 +1154,16 @@
     public boolean isSyncActive(Account account, String authority, ComponentName cname) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
                 "no permission to read the sync stats");
-        if (!hasAccountAccess(true, account, Binder.getCallingUid())) {
+
+        final int callingUid = Binder.getCallingUid();
+        final int userId = UserHandle.getCallingUserId();
+        if (!hasAccountAccess(true, account, callingUid)) {
+            return false;
+        }
+        if (!hasAuthorityAccess(authority, callingUid, userId)) {
             return false;
         }
 
-        int userId = UserHandle.getCallingUserId();
         final long identityToken = clearCallingIdentity();
         try {
             return getSyncManager().getSyncStorageEngine().isSyncActive(
@@ -1147,13 +1192,17 @@
         final boolean canAccessAccounts =
             mContext.checkCallingOrSelfPermission(Manifest.permission.GET_ACCOUNTS)
                 == PackageManager.PERMISSION_GRANTED;
+        final List<SyncInfo> results;
+        final int callingUid = Binder.getCallingUid();
         final long identityToken = clearCallingIdentity();
         try {
-            return getSyncManager().getSyncStorageEngine()
+            results = getSyncManager().getSyncStorageEngine()
                     .getCurrentSyncsCopy(userId, canAccessAccounts);
         } finally {
             restoreCallingIdentity(identityToken);
         }
+        results.removeIf(i -> !hasAuthorityAccess(i.authority, callingUid, userId));
+        return results;
     }
 
     @Override
@@ -1177,7 +1226,12 @@
                 "no permission to read the sync stats for user " + userId);
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
                 "no permission to read the sync stats");
-        if (!hasAccountAccess(true, account, Binder.getCallingUid())) {
+
+        final int callingUid = Binder.getCallingUid();
+        if (!hasAccountAccess(true, account, callingUid)) {
+            return null;
+        }
+        if (!hasAuthorityAccess(authority, callingUid, userId)) {
             return null;
         }
 
@@ -1207,7 +1261,12 @@
                 "no permission to read the sync stats");
         enforceCrossUserPermission(userId,
                 "no permission to retrieve the sync settings for user " + userId);
-        if (!hasAccountAccess(true, account, Binder.getCallingUid())) {
+
+        final int callingUid = Binder.getCallingUid();
+        if (!hasAccountAccess(true, account, callingUid)) {
+            return false;
+        }
+        if (!hasAuthorityAccess(authority, callingUid, userId)) {
             return false;
         }
 
@@ -1441,6 +1500,30 @@
         }
     }
 
+    /**
+     * Checks to see if the given authority is accessible by the caller.
+     *
+     * @param authority the authority to be accessed
+     * @param uid the uid trying to access the authority
+     * @param userId the user id for which to access the authority
+     * @return {@code true} if the authority is accessible by the caller, {@code false} otherwise
+     */
+    private boolean hasAuthorityAccess(@Nullable String authority, int uid, @UserIdInt int userId) {
+        if (TextUtils.isEmpty(authority)) {
+            return true;
+        }
+        if (!CompatChanges.isChangeEnabled(AUTHORITY_ACCESS_CHECK_CHANGE_ID, uid)) {
+            return true;
+        }
+        // Since #getSyncAdapterPackagesForAuthorityAsUser would filter out the packages
+        // that aren't visible to the callers, using this to check if the given authority
+        // is accessible by the callers.
+        final String[] syncAdapterPackages =
+                getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
+        return !ArrayUtils.isEmpty(syncAdapterPackages);
+    }
+
+
     private static int normalizeSyncable(int syncable) {
         if (syncable > 0) {
             return SyncStorageEngine.AuthorityInfo.SYNCABLE;
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 05341e0..dedc56a 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -523,10 +523,12 @@
         // Set the layer stack.
         device.setLayerStackLocked(t, isBlanked ? BLANK_LAYER_STACK : mLayerStack);
         // Also inform whether the device is the same one sent to inputflinger for its layerstack.
+        // Prevent displays that are disabled from receiving input.
         // TODO(b/188914255): Remove once input can dispatch against device vs layerstack.
         device.setDisplayFlagsLocked(t,
-                device.getDisplayDeviceInfoLocked().touch != TOUCH_NONE
-                        ? SurfaceControl.DISPLAY_RECEIVES_INPUT : 0);
+                (isEnabled() && device.getDisplayDeviceInfoLocked().touch != TOUCH_NONE)
+                        ? SurfaceControl.DISPLAY_RECEIVES_INPUT
+                        : 0);
 
         // Set the color mode and allowed display mode.
         if (device == mPrimaryDisplayDevice) {
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index fcb2eb4..9f44765 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -203,7 +203,7 @@
     }
 
     private void handleMediaProjectionStoppedLocked(IBinder appToken) {
-        VirtualDisplayDevice device = mVirtualDisplayDevices.remove(appToken);
+        VirtualDisplayDevice device = mVirtualDisplayDevices.get(appToken);
         if (device != null) {
             Slog.i(TAG, "Virtual display device released because media projection stopped: "
                     + device.mName);
diff --git a/services/core/java/com/android/server/display/WifiDisplayController.java b/services/core/java/com/android/server/display/WifiDisplayController.java
index a7e1a28..5b204ad 100644
--- a/services/core/java/com/android/server/display/WifiDisplayController.java
+++ b/services/core/java/com/android/server/display/WifiDisplayController.java
@@ -1090,7 +1090,7 @@
                 handlePeersChanged();
             } else if (action.equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) {
                 NetworkInfo networkInfo = (NetworkInfo)intent.getParcelableExtra(
-                        WifiP2pManager.EXTRA_NETWORK_INFO);
+                        WifiP2pManager.EXTRA_NETWORK_INFO, android.net.NetworkInfo.class);
                 if (DEBUG) {
                     Slog.d(TAG, "Received WIFI_P2P_CONNECTION_CHANGED_ACTION: networkInfo="
                             + networkInfo);
@@ -1099,7 +1099,7 @@
                 handleConnectionChanged(networkInfo);
             } else if (action.equals(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION)) {
                 mThisDevice = (WifiP2pDevice) intent.getParcelableExtra(
-                        WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);
+                        WifiP2pManager.EXTRA_WIFI_P2P_DEVICE, android.net.wifi.p2p.WifiP2pDevice.class);
                 if (DEBUG) {
                     Slog.d(TAG, "Received WIFI_P2P_THIS_DEVICE_CHANGED_ACTION: mThisDevice= "
                             + mThisDevice);
diff --git a/services/core/java/com/android/server/display/color/ColorDisplayService.java b/services/core/java/com/android/server/display/color/ColorDisplayService.java
index 223b8c1..6e30416 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -1666,11 +1666,9 @@
             return true;
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
         @Override
         public boolean isSaturationActivated() {
-            getContext().enforceCallingPermission(
-                    Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
-                    "Permission required to get display saturation level");
             final long token = Binder.clearCallingIdentity();
             try {
                 return !mGlobalSaturationTintController.isActivatedStateNotSet()
@@ -1680,11 +1678,9 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
         @Override
         public boolean setAppSaturationLevel(String packageName, int level) {
-            getContext().enforceCallingPermission(
-                    Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
-                    "Permission required to set display saturation level");
             final String callingPackageName = LocalServices.getService(PackageManagerInternal.class)
                     .getNameForUid(Binder.getCallingUid());
             final long token = Binder.clearCallingIdentity();
@@ -1695,10 +1691,8 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
         public int getTransformCapabilities() {
-            getContext().enforceCallingPermission(
-                    Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
-                    "Permission required to query transform capabilities");
             final long token = Binder.clearCallingIdentity();
             try {
                 return getTransformCapabilitiesInternal();
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index 63c5456..7b60345 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -23,6 +23,7 @@
 
 import static com.android.server.wm.ActivityInterceptorCallback.DREAM_MANAGER_ORDERED_ID;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.TaskInfo;
@@ -45,6 +46,9 @@
 import android.os.Looper;
 import android.os.PowerManager;
 import android.os.PowerManagerInternal;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
@@ -221,6 +225,10 @@
         }
     }
 
+    protected void requestStartDreamFromShell() {
+        requestDreamInternal();
+    }
+
     private void requestDreamInternal() {
         // Ask the power manager to nap.  It will eventually call back into
         // startDream() if/when it is appropriate to start dreaming.
@@ -275,6 +283,10 @@
         }
     }
 
+    protected void requestStopDreamFromShell() {
+        stopDreamInternal(true, "stopping dream from shell");
+    }
+
     private void stopDreamInternal(boolean immediate, String reason) {
         synchronized (mLock) {
             stopDreamLocked(immediate, reason);
@@ -593,6 +605,14 @@
             }
         }
 
+        public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
+                @Nullable FileDescriptor err,
+                @NonNull String[] args, @Nullable ShellCallback callback,
+                @NonNull ResultReceiver resultReceiver) throws RemoteException {
+            new DreamShellCommand(DreamManagerService.this, mPowerManager)
+                    .exec(this, in, out, err, args, callback, resultReceiver);
+        }
+
         @Override // Binder call
         public ComponentName[] getDreamComponents() {
             return getDreamComponentsForUser(UserHandle.getCallingUserId());
diff --git a/services/core/java/com/android/server/dreams/DreamShellCommand.java b/services/core/java/com/android/server/dreams/DreamShellCommand.java
new file mode 100644
index 0000000..eae7e80
--- /dev/null
+++ b/services/core/java/com/android/server/dreams/DreamShellCommand.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.dreams;
+
+import android.annotation.NonNull;
+import android.os.Binder;
+import android.os.PowerManager;
+import android.os.Process;
+import android.os.ShellCommand;
+import android.os.SystemClock;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import java.io.PrintWriter;
+
+/**
+ * {@link DreamShellCommand} allows accessing dream functionality, including toggling dream state.
+ */
+public class DreamShellCommand extends ShellCommand {
+    private static final boolean DEBUG = true;
+    private static final String TAG = "DreamShellCommand";
+    private final @NonNull DreamManagerService mService;
+    private final @NonNull PowerManager mPowerManager;
+
+    DreamShellCommand(@NonNull DreamManagerService service, @NonNull PowerManager powerManager) {
+        mService = service;
+        mPowerManager = powerManager;
+    }
+
+    @Override
+    public int onCommand(String cmd) {
+        final int callingUid = Binder.getCallingUid();
+        if (callingUid != Process.ROOT_UID) {
+            Slog.e(TAG, "Must be root before calling Dream shell commands");
+            return -1;
+        }
+
+        if (TextUtils.isEmpty(cmd)) {
+            return super.handleDefaultCommands(cmd);
+        }
+        if (DEBUG) {
+            Slog.d(TAG, "onCommand:" + cmd);
+        }
+
+        switch (cmd) {
+            case "start-dreaming":
+                return startDreaming();
+            case "stop-dreaming":
+                return stopDreaming();
+            default:
+                return super.handleDefaultCommands(cmd);
+        }
+    }
+
+    private int startDreaming() {
+        mPowerManager.wakeUp(SystemClock.uptimeMillis(),
+                PowerManager.WAKE_REASON_PLUGGED_IN, "shell:cmd:android.service.dreams:DREAM");
+        mService.requestStartDreamFromShell();
+        return 0;
+    }
+
+    private int stopDreaming() {
+        mService.requestStopDreamFromShell();
+        return 0;
+    }
+
+    @Override
+    public void onHelp() {
+        PrintWriter pw = getOutPrintWriter();
+        pw.println("Dream manager (dreams) commands:");
+        pw.println("  help");
+        pw.println("      Print this help text.");
+        pw.println("  start-dreaming");
+        pw.println("      Start the currently configured dream.");
+        pw.println("  stop-dreaming");
+        pw.println("      Stops any active dream");
+    }
+}
diff --git a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
index ae9c64b4..326d720 100644
--- a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
+++ b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
@@ -64,11 +64,10 @@
     private static final String FONT_FILES_DIR = "/data/fonts/files";
     private static final String CONFIG_XML_FILE = "/data/fonts/config/config.xml";
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.UPDATE_FONTS)
     @RequiresPermission(Manifest.permission.UPDATE_FONTS)
     @Override
     public FontConfig getFontConfig() {
-        getContext().enforceCallingPermission(Manifest.permission.UPDATE_FONTS,
-                "UPDATE_FONTS permission required.");
         return getSystemFontConfig();
     }
 
diff --git a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
index e222c64..d238dae 100644
--- a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
+++ b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
@@ -27,8 +27,6 @@
 import android.view.SurfaceControl;
 import android.view.WindowManager;
 
-import com.android.server.policy.WindowManagerPolicy;
-
 /**
  * An internal implementation of an {@link InputMonitor} that uses a spy window.
  *
@@ -69,9 +67,7 @@
 
         final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
         t.setInputWindowInfo(mInputSurface, mWindowHandle);
-        // Gesture monitor should be above handwriting event surface, hence setting it to
-        // WindowManagerPolicy.INPUT_DISPLAY_OVERLAY_LAYER + 1
-        t.setLayer(mInputSurface, WindowManagerPolicy.INPUT_DISPLAY_OVERLAY_LAYER + 1);
+        t.setLayer(mInputSurface, Integer.MAX_VALUE);
         t.setPosition(mInputSurface, 0, 0);
         t.setCrop(mInputSurface, null /* crop to parent surface */);
         t.show(mInputSurface);
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 0f0579c..44aefcc 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -396,7 +396,7 @@
         }
 
         NativeInputManagerService getNativeService(InputManagerService service) {
-            return new NativeInputManagerService.NativeImpl(service, mContext, mLooper.getQueue());
+            return new NativeInputManagerService.NativeImpl(service, mLooper.getQueue());
         }
 
         void registerLocalService(InputManagerInternal localService) {
@@ -843,14 +843,17 @@
      * When input dispatches focus to the apps, the touch mode state
      * will be sent together with the focus change (but each one in its own event).
      *
-     * @param inTouchMode true if the device is in touch mode
-     * @param pid the pid of the process that requested to switch touch mode state
-     * @param uid the uid of the process that requested to switch touch mode state
+     * @param inTouchMode   true if the device is in touch mode
+     * @param pid           the pid of the process that requested to switch touch mode state
+     * @param uid           the uid of the process that requested to switch touch mode state
      * @param hasPermission if set to {@code true} then no further authorization will be performed
+     * @param displayId     the target display (ignored if device is configured with per display
+     *                      touch mode enabled)
      * @return {@code true} if the touch mode was successfully changed, {@code false} otherwise
      */
-    public boolean setInTouchMode(boolean inTouchMode, int pid, int uid, boolean hasPermission) {
-        return mNative.setInTouchMode(inTouchMode, pid, uid, hasPermission);
+    public boolean setInTouchMode(boolean inTouchMode, int pid, int uid, boolean hasPermission,
+            int displayId) {
+        return mNative.setInTouchMode(inTouchMode, pid, uid, hasPermission, displayId);
     }
 
     @Override // Binder call
@@ -3031,6 +3034,13 @@
         return names.toArray(new String[0]);
     }
 
+    // Native callback.
+    @SuppressWarnings("unused")
+    private boolean isPerDisplayTouchModeEnabled() {
+        return mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_perDisplayFocusEnabled);
+    }
+
     /**
      * Flatten a map into a string list, with value positioned directly next to the
      * key.
diff --git a/services/core/java/com/android/server/input/NativeInputManagerService.java b/services/core/java/com/android/server/input/NativeInputManagerService.java
index 3d1e441..325c308 100644
--- a/services/core/java/com/android/server/input/NativeInputManagerService.java
+++ b/services/core/java/com/android/server/input/NativeInputManagerService.java
@@ -16,7 +16,6 @@
 
 package com.android.server.input;
 
-import android.content.Context;
 import android.hardware.display.DisplayViewport;
 import android.hardware.input.InputSensorInfo;
 import android.hardware.lights.Light;
@@ -64,7 +63,19 @@
 
     void setInputFilterEnabled(boolean enable);
 
-    boolean setInTouchMode(boolean inTouchMode, int pid, int uid, boolean hasPermission);
+    /**
+     * Set the touch mode state for the display passed as argument.
+     *
+     * @param inTouchMode   true if the device is in touch mode
+     * @param pid           the pid of the process that requested to switch touch mode state
+     * @param uid           the uid of the process that requested to switch touch mode state
+     * @param hasPermission if set to {@code true} then no further authorization will be performed
+     * @param displayId     the target display (ignored if device is configured with per display
+     *                      touch mode enabled)
+     * @return {@code true} if the touch mode was successfully changed, {@code false} otherwise
+     */
+    boolean setInTouchMode(boolean inTouchMode, int pid, int uid, boolean hasPermission,
+            int displayId);
 
     void setMaximumObscuringOpacityForTouch(float opacity);
 
@@ -194,12 +205,11 @@
         @SuppressWarnings({"unused", "FieldCanBeLocal"})
         private final long mPtr;
 
-        NativeImpl(InputManagerService service, Context context, MessageQueue messageQueue) {
-            mPtr = init(service, context, messageQueue);
+        NativeImpl(InputManagerService service, MessageQueue messageQueue) {
+            mPtr = init(service, messageQueue);
         }
 
-        private native long init(InputManagerService service, Context context,
-                MessageQueue messageQueue);
+        private native long init(InputManagerService service, MessageQueue messageQueue);
 
         @Override
         public native void start();
@@ -240,7 +250,7 @@
 
         @Override
         public native boolean setInTouchMode(boolean inTouchMode, int pid, int uid,
-                boolean hasPermission);
+                boolean hasPermission, int displayId);
 
         @Override
         public native void setMaximumObscuringOpacityForTouch(float opacity);
diff --git a/services/core/java/com/android/server/inputmethod/AdditionalSubtypeUtils.java b/services/core/java/com/android/server/inputmethod/AdditionalSubtypeUtils.java
index 24b8e34..816d08a 100644
--- a/services/core/java/com/android/server/inputmethod/AdditionalSubtypeUtils.java
+++ b/services/core/java/com/android/server/inputmethod/AdditionalSubtypeUtils.java
@@ -31,6 +31,8 @@
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodSubtype;
 
+import libcore.io.IoUtils;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -102,11 +104,11 @@
      *
      * @param allSubtypes {@link ArrayMap} from IME ID to additional subtype list. Passing an empty
      *                    map deletes the file.
-     * @param methodMap {@link ArrayMap} from IME ID to {@link InputMethodInfo}.
-     * @param userId The user ID to be associated with.
+     * @param methodMap   {@link ArrayMap} from IME ID to {@link InputMethodInfo}.
+     * @param userId      The user ID to be associated with.
      */
     static void save(ArrayMap<String, List<InputMethodSubtype>> allSubtypes,
-             ArrayMap<String, InputMethodInfo> methodMap, @UserIdInt int userId) {
+            ArrayMap<String, InputMethodInfo> methodMap, @UserIdInt int userId) {
         final File inputMethodDir = getInputMethodDir(userId);
 
         if (allSubtypes.isEmpty()) {
@@ -172,11 +174,13 @@
             out.endTag(null, NODE_SUBTYPES);
             out.endDocument();
             subtypesFile.finishWrite(fos);
-        } catch (java.io.IOException e) {
+        } catch (IOException e) {
             Slog.w(TAG, "Error writing subtypes", e);
             if (fos != null) {
                 subtypesFile.failWrite(fos);
             }
+        } finally {
+            IoUtils.closeQuietly(fos);
         }
     }
 
@@ -189,7 +193,7 @@
      *
      * @param allSubtypes {@link ArrayMap} from IME ID to additional subtype list. This parameter
      *                    will be used to return the result.
-     * @param userId The user ID to be associated with.
+     * @param userId      The user ID to be associated with.
      */
     static void load(@NonNull ArrayMap<String, List<InputMethodSubtype>> allSubtypes,
             @UserIdInt int userId) {
diff --git a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
index 5438faa..8180e66 100644
--- a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
+++ b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
@@ -27,8 +27,6 @@
 import android.view.SurfaceControl;
 import android.view.WindowManager;
 
-import com.android.server.policy.WindowManagerPolicy;
-
 final class HandwritingEventReceiverSurface {
 
     public static final String TAG = HandwritingEventReceiverSurface.class.getSimpleName();
@@ -38,8 +36,7 @@
     // is above gesture monitors, then edge-back and swipe-up gestures won't work when this surface
     // is intercepting.
     // TODO(b/217538817): Specify the ordering in WM by usage.
-    private static final int HANDWRITING_SURFACE_LAYER =
-            WindowManagerPolicy.INPUT_DISPLAY_OVERLAY_LAYER;
+    private static final int HANDWRITING_SURFACE_LAYER = Integer.MAX_VALUE - 1;
 
     private final InputWindowHandle mWindowHandle;
     private final InputChannel mClientChannel;
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodInfoUtils.java b/services/core/java/com/android/server/inputmethod/InputMethodInfoUtils.java
index 68753ab..2957935 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodInfoUtils.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodInfoUtils.java
@@ -22,7 +22,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
-import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Slog;
@@ -199,7 +198,8 @@
      * @param methodMap Map from the IME ID to {@link InputMethodInfo}.
      * @param systemSpeechRecognizerPackageName System speech recognizer configured by the system
      *                                          config.
-     * @param currentDefaultVoiceImeId IME ID currently set to
+     * @param currentDefaultVoiceImeId the default voice IME id, which may be {@code null} or
+     *                                 the value assigned for
      *                                 {@link Settings.Secure#DEFAULT_VOICE_INPUT_METHOD}
      * @return {@link InputMethodInfo} that is found in {@code methodMap} and most suitable for
      *                                 the system voice IME.
@@ -294,7 +294,7 @@
             for (int i = 0; i < imis.size(); ++i) {
                 if (isSystemImeThatHasSubtypeOf(imis.get(i), context,
                         true /* checkDefaultAttribute */, fallbackLocale,
-                        true /* checkCountry */, SubtypeUtils.SUBTYPE_MODE_KEYBOARD)) {
+                        true /* checkCountry */, SUBTYPE_MODE_KEYBOARD)) {
                     return fallbackLocale;
                 }
             }
@@ -305,7 +305,7 @@
             for (int i = 0; i < imis.size(); ++i) {
                 if (isSystemImeThatHasSubtypeOf(imis.get(i), context,
                         false /* checkDefaultAttribute */, fallbackLocale,
-                        true /* checkCountry */, SubtypeUtils.SUBTYPE_MODE_KEYBOARD)) {
+                        true /* checkCountry */, SUBTYPE_MODE_KEYBOARD)) {
                     return fallbackLocale;
                 }
             }
@@ -323,10 +323,7 @@
         if (checkDefaultAttribute && !imi.isDefault(context)) {
             return false;
         }
-        if (!SubtypeUtils.containsSubtypeOf(imi, requiredLocale, checkCountry,
-                requiredSubtypeMode)) {
-            return false;
-        }
-        return true;
+        return SubtypeUtils.containsSubtypeOf(imi, requiredLocale, checkCountry,
+                requiredSubtypeMode);
     }
 }
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 3c0cc6d..794c06f 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -1,16 +1,17 @@
 /*
+ * Copyright (C) 2022 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
+ * 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
+ *      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.
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 package com.android.server.inputmethod;
@@ -59,6 +60,7 @@
 import android.annotation.BinderThread;
 import android.annotation.ColorInt;
 import android.annotation.DrawableRes;
+import android.annotation.EnforcePermission;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -90,6 +92,7 @@
 import android.database.ContentObserver;
 import android.graphics.Matrix;
 import android.hardware.display.DisplayManagerInternal;
+import android.hardware.input.InputManager;
 import android.hardware.input.InputManagerInternal;
 import android.inputmethodservice.InputMethodService;
 import android.media.AudioManagerInternal;
@@ -118,6 +121,7 @@
 import android.util.ArraySet;
 import android.util.EventLog;
 import android.util.IndentingPrintWriter;
+import android.util.IntArray;
 import android.util.Pair;
 import android.util.PrintWriterPrinter;
 import android.util.Printer;
@@ -128,6 +132,7 @@
 import android.view.DisplayInfo;
 import android.view.IWindowManager;
 import android.view.InputChannel;
+import android.view.InputDevice;
 import android.view.View;
 import android.view.WindowManager;
 import android.view.WindowManager.DisplayImePolicy;
@@ -173,7 +178,6 @@
 import com.android.internal.inputmethod.UnbindReason;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.internal.notification.SystemNotificationChannels;
-import com.android.internal.os.SomeArgs;
 import com.android.internal.os.TransferPipe;
 import com.android.internal.util.ConcurrentUtils;
 import com.android.internal.util.DumpUtils;
@@ -219,6 +223,8 @@
  */
 public final class InputMethodManagerService extends IInputMethodManager.Stub
         implements Handler.Callback {
+    // Virtual device id for test.
+    private static final Integer VIRTUAL_STYLUS_ID_FOR_TEST = 999999;
     static final boolean DEBUG = false;
     static final String TAG = "InputMethodManagerService";
     public static final String PROTO_ARG = "--proto";
@@ -290,6 +296,8 @@
     final IWindowManager mIWindowManager;
     private final SparseBooleanArray mLoggedDeniedGetInputMethodWindowVisibleHeightForUid =
             new SparseBooleanArray(0);
+    private final SparseBooleanArray mLoggedDeniedIsInputMethodPickerShownForTestForUid =
+            new SparseBooleanArray(0);
     final WindowManagerInternal mWindowManagerInternal;
     final PackageManagerInternal mPackageManagerInternal;
     final InputManagerInternal mInputManagerInternal;
@@ -349,6 +357,8 @@
     private boolean mNotificationShown;
     @GuardedBy("ImfLock.class")
     private final HandwritingModeController mHwController;
+    @GuardedBy("ImfLock.class")
+    private IntArray mStylusIds;
 
     @GuardedBy("ImfLock.class")
     @Nullable
@@ -358,29 +368,29 @@
     Future<?> mImeDrawsImeNavBarResLazyInitFuture;
 
     static class SessionState {
-        final ClientState client;
-        final IInputMethodInvoker method;
+        final ClientState mClient;
+        final IInputMethodInvoker mMethod;
 
-        IInputMethodSession session;
-        InputChannel channel;
+        IInputMethodSession mSession;
+        InputChannel mChannel;
 
         @Override
         public String toString() {
-            return "SessionState{uid " + client.uid + " pid " + client.pid
+            return "SessionState{uid " + mClient.mUid + " pid " + mClient.mPid
                     + " method " + Integer.toHexString(
-                            IInputMethodInvoker.getBinderIdentityHashCode(method))
+                    IInputMethodInvoker.getBinderIdentityHashCode(mMethod))
                     + " session " + Integer.toHexString(
-                            System.identityHashCode(session))
-                    + " channel " + channel
+                    System.identityHashCode(mSession))
+                    + " channel " + mChannel
                     + "}";
         }
 
-        SessionState(ClientState _client, IInputMethodInvoker _method,
-                IInputMethodSession _session, InputChannel _channel) {
-            client = _client;
-            method = _method;
-            session = _session;
-            channel = _channel;
+        SessionState(ClientState client, IInputMethodInvoker method,
+                IInputMethodSession session, InputChannel channel) {
+            mClient = client;
+            mMethod = method;
+            mSession = session;
+            mChannel = channel;
         }
     }
 
@@ -396,7 +406,7 @@
 
         @Override
         public String toString() {
-            return "AccessibilitySessionState{uid " + mClient.uid + " pid " + mClient.pid
+            return "AccessibilitySessionState{uid " + mClient.mUid + " pid " + mClient.mPid
                     + " id " + Integer.toHexString(mId)
                     + " session " + Integer.toHexString(
                     System.identityHashCode(mSession))
@@ -427,37 +437,37 @@
     }
 
     static final class ClientState {
-        final IInputMethodClientInvoker client;
-        final IRemoteInputConnection fallbackInputConnection;
-        final int uid;
-        final int pid;
-        final int selfReportedDisplayId;
-        final InputBinding binding;
-        final ClientDeathRecipient clientDeathRecipient;
+        final IInputMethodClientInvoker mClient;
+        final IRemoteInputConnection mFallbackInputConnection;
+        final int mUid;
+        final int mPid;
+        final int mSelfReportedDisplayId;
+        final InputBinding mBinding;
+        final ClientDeathRecipient mClientDeathRecipient;
 
-        boolean sessionRequested;
+        boolean mSessionRequested;
         boolean mSessionRequestedForAccessibility;
-        SessionState curSession;
+        SessionState mCurSession;
         SparseArray<AccessibilitySessionState> mAccessibilitySessions = new SparseArray<>();
 
         @Override
         public String toString() {
             return "ClientState{" + Integer.toHexString(
-                    System.identityHashCode(this)) + " uid=" + uid
-                    + " pid=" + pid + " displayId=" + selfReportedDisplayId + "}";
+                    System.identityHashCode(this)) + " mUid=" + mUid
+                    + " mPid=" + mPid + " mSelfReportedDisplayId=" + mSelfReportedDisplayId + "}";
         }
 
-        ClientState(IInputMethodClientInvoker _client,
-                IRemoteInputConnection _fallbackInputConnection,
-                int _uid, int _pid, int _selfReportedDisplayId,
-                ClientDeathRecipient _clientDeathRecipient) {
-            client = _client;
-            fallbackInputConnection = _fallbackInputConnection;
-            uid = _uid;
-            pid = _pid;
-            selfReportedDisplayId = _selfReportedDisplayId;
-            binding = new InputBinding(null, fallbackInputConnection.asBinder(), uid, pid);
-            clientDeathRecipient = _clientDeathRecipient;
+        ClientState(IInputMethodClientInvoker client,
+                IRemoteInputConnection fallbackInputConnection,
+                int uid, int pid, int selfReportedDisplayId,
+                ClientDeathRecipient clientDeathRecipient) {
+            mClient = client;
+            mFallbackInputConnection = fallbackInputConnection;
+            mUid = uid;
+            mPid = pid;
+            mSelfReportedDisplayId = selfReportedDisplayId;
+            mBinding = new InputBinding(null, mFallbackInputConnection.asBinder(), mUid, mPid);
+            mClientDeathRecipient = clientDeathRecipient;
         }
     }
 
@@ -755,7 +765,7 @@
      */
     boolean mBoundToAccessibility;
 
-     /**
+    /**
      * Currently enabled session.
      */
     @GuardedBy("ImfLock.class")
@@ -1000,7 +1010,7 @@
          * <p>TODO: Consider to follow what other system services have been doing to manage
          * constants (e.g. {@link android.provider.Settings.Global#ACTIVITY_MANAGER_CONSTANTS}).</p>
          */
-        private final static int ENTRY_SIZE_FOR_HIGH_RAM_DEVICE = 32;
+        private static final int ENTRY_SIZE_FOR_HIGH_RAM_DEVICE = 32;
 
         /**
          * Entry size for non low-RAM devices.
@@ -1008,7 +1018,7 @@
          * <p>TODO: Consider to follow what other system services have been doing to manage
          * constants (e.g. {@link android.provider.Settings.Global#ACTIVITY_MANAGER_CONSTANTS}).</p>
          */
-        private final static int ENTRY_SIZE_FOR_LOW_RAM_DEVICE = 5;
+        private static final int ENTRY_SIZE_FOR_LOW_RAM_DEVICE = 5;
 
         private static int getEntrySize() {
             if (ActivityManager.isLowRamDeviceStatic()) {
@@ -1131,7 +1141,7 @@
 
                 pw.print(prefix);
                 pw.println(" softInputMode=" + InputMethodDebug.softInputModeToString(
-                                entry.mTargetWindowSoftInputMode));
+                        entry.mTargetWindowSoftInputMode));
 
                 pw.print(prefix);
                 pw.println(" inputType=0x" + Integer.toHexString(entry.mEditorInfo.inputType)
@@ -1327,7 +1337,7 @@
          * rescanning.</p>
          */
         @GuardedBy("ImfLock.class")
-        final private ArraySet<String> mKnownImePackageNames = new ArraySet<>();
+        private final ArraySet<String> mKnownImePackageNames = new ArraySet<>();
 
         /**
          * Packages that are appeared, disappeared, or modified for whatever reason.
@@ -1355,7 +1365,7 @@
         }
 
         @GuardedBy("ImfLock.class")
-        final void addKnownImePackageNameLocked(@NonNull String packageName) {
+        void addKnownImePackageNameLocked(@NonNull String packageName) {
             mKnownImePackageNames.add(packageName);
         }
 
@@ -1378,9 +1388,9 @@
                     return false;
                 }
                 String curInputMethodId = mSettings.getSelectedInputMethod();
-                final int N = mMethodList.size();
+                final int numImes = mMethodList.size();
                 if (curInputMethodId != null) {
-                    for (int i=0; i<N; i++) {
+                    for (int i = 0; i < numImes; i++) {
                         InputMethodInfo imi = mMethodList.get(i);
                         if (imi.getId().equals(curInputMethodId)) {
                             for (String pkg : packages) {
@@ -1459,6 +1469,7 @@
         public void onUidRemoved(int uid) {
             synchronized (ImfLock.class) {
                 mLoggedDeniedGetInputMethodWindowVisibleHeightForUid.delete(uid);
+                mLoggedDeniedIsInputMethodPickerShownForTestForUid.delete(uid);
             }
         }
 
@@ -1481,8 +1492,8 @@
             // Otherwise, check if mKnownImePackageNames and mChangedPackages have any intersection.
             // TODO: Consider to create a utility method to do the following test. List.retainAll()
             // is an option, but it may still do some extra operations that we do not need here.
-            final int N = mChangedPackages.size();
-            for (int i = 0; i < N; ++i) {
+            final int numPackages = mChangedPackages.size();
+            for (int i = 0; i < numPackages; ++i) {
                 final String packageName = mChangedPackages.get(i);
                 if (mKnownImePackageNames.contains(packageName)) {
                     return true;
@@ -1502,9 +1513,9 @@
 
                 InputMethodInfo curIm = null;
                 String curInputMethodId = mSettings.getSelectedInputMethod();
-                final int N = mMethodList.size();
+                final int numImes = mMethodList.size();
                 if (curInputMethodId != null) {
-                    for (int i=0; i<N; i++) {
+                    for (int i = 0; i < numImes; i++) {
                         InputMethodInfo imi = mMethodList.get(i);
                         final String imiId = imi.getId();
                         if (imiId.equals(curInputMethodId)) {
@@ -1610,6 +1621,10 @@
     @GuardedBy("ImfLock.class")
     private UserSwitchHandlerTask mUserSwitchHandlerTask;
 
+    /**
+     * {@link SystemService} used to publish and manage the lifecycle of
+     * {@link InputMethodManagerService}.
+     */
     public static final class Lifecycle extends SystemService {
         private final InputMethodManagerService mService;
 
@@ -1767,6 +1782,7 @@
                 com.android.internal.R.array.config_nonPreemptibleInputMethods));
         mHwController = new HandwritingModeController(thread.getLooper(),
                 new InkWindowInitializer());
+        registerDeviceListenerAndCheckStylusSupport();
     }
 
     private final class InkWindowInitializer implements Runnable {
@@ -1842,8 +1858,10 @@
     @GuardedBy("ImfLock.class")
     private void switchUserOnHandlerLocked(@UserIdInt int newUserId,
             IInputMethodClientInvoker clientToBeReset) {
-        if (DEBUG) Slog.d(TAG, "Switching user stage 1/3. newUserId=" + newUserId
-                + " currentUserId=" + mSettings.getCurrentUserId());
+        if (DEBUG) {
+            Slog.d(TAG, "Switching user stage 1/3. newUserId=" + newUserId
+                    + " currentUserId=" + mSettings.getCurrentUserId());
+        }
 
         maybeInitImeNavbarConfigLocked(newUserId);
 
@@ -1860,8 +1878,10 @@
         AdditionalSubtypeUtils.load(mAdditionalSubtypeMap, newUserId);
         final String defaultImiId = mSettings.getSelectedInputMethod();
 
-        if (DEBUG) Slog.d(TAG, "Switching user stage 2/3. newUserId=" + newUserId
-                + " defaultImiId=" + defaultImiId);
+        if (DEBUG) {
+            Slog.d(TAG, "Switching user stage 2/3. newUserId=" + newUserId
+                    + " defaultImiId=" + defaultImiId);
+        }
 
         // For secondary users, the list of enabled IMEs may not have been updated since the
         // callbacks to PackageMonitor are ignored for the secondary user. Here, defaultImiId may
@@ -1888,8 +1908,10 @@
                     mSettings.getEnabledInputMethodListLocked());
         }
 
-        if (DEBUG) Slog.d(TAG, "Switching user stage 3/3. newUserId=" + newUserId
-                + " selectedIme=" + mSettings.getSelectedInputMethod());
+        if (DEBUG) {
+            Slog.d(TAG, "Switching user stage 3/3. newUserId=" + newUserId
+                    + " selectedIme=" + mSettings.getSelectedInputMethod());
+        }
 
         mLastSwitchUserId = newUserId;
 
@@ -1899,7 +1921,7 @@
                 // The client is already gone.
                 return;
             }
-            cs.client.scheduleStartInputIfNecessary(mInFullscreenMode);
+            cs.mClient.scheduleStartInputIfNecessary(mInFullscreenMode);
         }
     }
 
@@ -1923,6 +1945,9 @@
         }
     }
 
+    /**
+     * TODO(b/32343335): The entire systemRunning() method needs to be revisited.
+     */
     public void systemRunning(StatusBarManagerService statusBar) {
         synchronized (ImfLock.class) {
             if (DEBUG) {
@@ -2022,7 +2047,7 @@
         // by a token.
         if (mContext.checkCallingOrSelfPermission(
                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
-                        == PackageManager.PERMISSION_GRANTED) {
+                == PackageManager.PERMISSION_GRANTED) {
             if (DEBUG) {
                 Slog.d(TAG, "--- Access granted because the calling process has "
                         + "the INTERACT_ACROSS_USERS_FULL permission");
@@ -2054,7 +2079,10 @@
         return true;
     }
 
-    private List<InputMethodInfo> getInputMethodListInternal(@UserIdInt int userId,
+    @BinderThread
+    @NonNull
+    @Override
+    public List<InputMethodInfo> getInputMethodList(@UserIdInt int userId,
             @DirectBootAwareness int directBootAwareness) {
         if (UserHandle.getCallingUserId() != userId) {
             mContext.enforceCallingPermission(
@@ -2076,17 +2104,6 @@
     }
 
     @Override
-    public List<InputMethodInfo> getInputMethodList(@UserIdInt int userId) {
-        return getInputMethodListInternal(userId, DirectBootAwareness.AUTO);
-    }
-
-    @Override
-    public List<InputMethodInfo> getAwareLockedInputMethodList(@UserIdInt int userId,
-            @DirectBootAwareness int directBootAwareness) {
-        return getInputMethodListInternal(userId, directBootAwareness);
-    }
-
-    @Override
     public List<InputMethodInfo> getEnabledInputMethodList(@UserIdInt int userId) {
         if (UserHandle.getCallingUserId() != userId) {
             mContext.enforceCallingPermission(
@@ -2267,8 +2284,8 @@
             final int numClients = mClients.size();
             for (int i = 0; i < numClients; ++i) {
                 final ClientState state = mClients.valueAt(i);
-                if (state.uid == callerUid && state.pid == callerPid
-                        && state.selfReportedDisplayId == selfReportedDisplayId) {
+                if (state.mUid == callerUid && state.mPid == callerPid
+                        && state.mSelfReportedDisplayId == selfReportedDisplayId) {
                     throw new SecurityException("uid=" + callerUid + "/pid=" + callerPid
                             + "/displayId=" + selfReportedDisplayId + " is already registered.");
                 }
@@ -2300,7 +2317,7 @@
         synchronized (ImfLock.class) {
             ClientState cs = mClients.remove(client.asBinder());
             if (cs != null) {
-                client.asBinder().unlinkToDeath(cs.clientDeathRecipient, 0);
+                client.asBinder().unlinkToDeath(cs.mClientDeathRecipient, 0);
                 clearClientSessionLocked(cs);
                 clearClientSessionForAccessibilityLocked(cs);
 
@@ -2339,8 +2356,10 @@
     @GuardedBy("ImfLock.class")
     void unbindCurrentClientLocked(@UnbindReason int unbindClientReason) {
         if (mCurClient != null) {
-            if (DEBUG) Slog.v(TAG, "unbindCurrentInputLocked: client="
-                    + mCurClient.client.asBinder());
+            if (DEBUG) {
+                Slog.v(TAG, "unbindCurrentInputLocked: client="
+                        + mCurClient.mClient.asBinder());
+            }
             if (mBoundToMethod) {
                 mBoundToMethod = false;
                 IInputMethodInvoker curMethod = getCurMethodLocked();
@@ -2353,10 +2372,10 @@
             // Since we set active false to current client and set mCurClient to null, let's unbind
             // all accessibility too. That means, when input method get disconnected (including
             // switching ime), we also unbind accessibility
-            mCurClient.client.setActive(false /* active */, false /* fullscreen */,
+            mCurClient.mClient.setActive(false /* active */, false /* fullscreen */,
                     false /* reportToImeController */);
-            mCurClient.client.onUnbindMethod(getSequenceNumberLocked(), unbindClientReason);
-            mCurClient.sessionRequested = false;
+            mCurClient.mClient.onUnbindMethod(getSequenceNumberLocked(), unbindClientReason);
+            mCurClient.mSessionRequested = false;
             mCurClient.mSessionRequestedForAccessibility = false;
             mCurClient = null;
             mCurVirtualDisplayToScreenMatrix = null;
@@ -2398,7 +2417,7 @@
     @NonNull
     InputBindResult attachNewInputLocked(@StartInputReason int startInputReason, boolean initial) {
         if (!mBoundToMethod) {
-            getCurMethodLocked().bindInput(mCurClient.binding);
+            getCurMethodLocked().bindInput(mCurClient.mBinding);
             mBoundToMethod = true;
         }
 
@@ -2407,7 +2426,7 @@
         final StartInputInfo info = new StartInputInfo(mSettings.getCurrentUserId(),
                 getCurTokenLocked(),
                 mCurTokenDisplayId, getCurIdLocked(), startInputReason, restarting,
-                UserHandle.getUserId(mCurClient.uid), mCurClient.selfReportedDisplayId,
+                UserHandle.getUserId(mCurClient.mUid), mCurClient.mSelfReportedDisplayId,
                 mCurFocusedWindow, mCurEditorInfo, mCurFocusedWindowSoftInputMode,
                 getSequenceNumberLocked());
         mImeTargetWindowMap.put(startInputToken, mCurFocusedWindow);
@@ -2418,17 +2437,17 @@
         // same-user scenarios.
         // That said ignoring cross-user scenario will never affect IMEs that do not have
         // INTERACT_ACROSS_USERS(_FULL) permissions, which is actually almost always the case.
-        if (mSettings.getCurrentUserId() == UserHandle.getUserId(mCurClient.uid)) {
+        if (mSettings.getCurrentUserId() == UserHandle.getUserId(mCurClient.mUid)) {
             mPackageManagerInternal.grantImplicitAccess(mSettings.getCurrentUserId(),
-                    null /* intent */, UserHandle.getAppId(getCurMethodUidLocked()), mCurClient.uid,
-                    true /* direct */);
+                    null /* intent */, UserHandle.getAppId(getCurMethodUidLocked()),
+                    mCurClient.mUid, true /* direct */);
         }
 
         @InputMethodNavButtonFlags
         final int navButtonFlags = getInputMethodNavButtonFlagsLocked();
-        final SessionState session = mCurClient.curSession;
+        final SessionState session = mCurClient.mCurSession;
         setEnabledSessionLocked(session);
-        session.method.startInput(startInputToken, mCurInputConnection, mCurEditorInfo, restarting,
+        session.mMethod.startInput(startInputToken, mCurInputConnection, mCurEditorInfo, restarting,
                 navButtonFlags, mCurImeDispatcher);
         if (mShowRequested) {
             if (DEBUG) Slog.v(TAG, "Attach new input asks to show input");
@@ -2443,8 +2462,8 @@
         final SparseArray<IAccessibilityInputMethodSession> accessibilityInputMethodSessions =
                 createAccessibilityInputMethodSessions(mCurClient.mAccessibilitySessions);
         return new InputBindResult(InputBindResult.ResultCode.SUCCESS_WITH_IME_SESSION,
-                session.session, accessibilityInputMethodSessions,
-                (session.channel != null ? session.channel.dup() : null),
+                session.mSession, accessibilityInputMethodSessions,
+                (session.mChannel != null ? session.mChannel.dup() : null),
                 curId, getSequenceNumberLocked(), mCurVirtualDisplayToScreenMatrix,
                 suppressesSpellChecker);
     }
@@ -2467,10 +2486,10 @@
             } else {
                 matrix.postConcat(info.mMatrix);
             }
-            if (info.mParentClient.selfReportedDisplayId == imeDisplayId) {
+            if (info.mParentClient.mSelfReportedDisplayId == imeDisplayId) {
                 return matrix;
             }
-            displayId = info.mParentClient.selfReportedDisplayId;
+            displayId = info.mParentClient.mSelfReportedDisplayId;
         }
     }
 
@@ -2538,16 +2557,16 @@
                     null, null, null, selectedMethodId, getSequenceNumberLocked(), null, false);
         }
 
-        if (!InputMethodUtils.checkIfPackageBelongsToUid(mAppOpsManager, cs.uid,
+        if (!InputMethodUtils.checkIfPackageBelongsToUid(mAppOpsManager, cs.mUid,
                 editorInfo.packageName)) {
             Slog.e(TAG, "Rejecting this client as it reported an invalid package name."
-                    + " uid=" + cs.uid + " package=" + editorInfo.packageName);
+                    + " uid=" + cs.mUid + " package=" + editorInfo.packageName);
             return InputBindResult.INVALID_PACKAGE_NAME;
         }
 
         // Compute the final shown display ID with validated cs.selfReportedDisplayId for this
         // session & other conditions.
-        mDisplayIdToShowIme = computeImeDisplayIdForTarget(cs.selfReportedDisplayId,
+        mDisplayIdToShowIme = computeImeDisplayIdForTarget(cs.mSelfReportedDisplayId,
                 mImeDisplayValidator);
 
         if (mDisplayIdToShowIme == INVALID_DISPLAY) {
@@ -2569,7 +2588,7 @@
         mCurRemoteAccessibilityInputConnection = remoteAccessibilityInputConnection;
         mCurImeDispatcher = imeDispatcher;
         mCurVirtualDisplayToScreenMatrix =
-                getVirtualDisplayToScreenMatrixLocked(cs.selfReportedDisplayId,
+                getVirtualDisplayToScreenMatrixLocked(cs.mSelfReportedDisplayId,
                         mDisplayIdToShowIme);
         mCurEditorInfo = editorInfo;
 
@@ -2588,7 +2607,7 @@
         // We expect the caller has already verified that the client is allowed to access this
         // display ID.
         if (isSelectedMethodBoundLocked()) {
-            if (cs.curSession != null) {
+            if (cs.mCurSession != null) {
                 // Fast case: if we are already connected to the input method,
                 // then just return it.
                 // This doesn't mean a11y sessions are there. When a11y service is
@@ -2664,7 +2683,7 @@
         unbindCurrentClientLocked(UnbindReason.SWITCH_CLIENT);
         // If the screen is on, inform the new client it is active
         if (mIsInteractive) {
-            cs.client.setActive(true /* active */, false /* fullscreen */,
+            cs.mClient.setActive(true /* active */, false /* fullscreen */,
                     false /* reportToImeController */);
         }
     }
@@ -2776,13 +2795,13 @@
                         && curMethod.asBinder() == method.asBinder()) {
                     if (mCurClient != null) {
                         clearClientSessionLocked(mCurClient);
-                        mCurClient.curSession = new SessionState(mCurClient,
+                        mCurClient.mCurSession = new SessionState(mCurClient,
                                 method, session, channel);
                         InputBindResult res = attachNewInputLocked(
                                 StartInputReason.SESSION_CREATED_BY_IME, true);
                         attachNewAccessibilityLocked(StartInputReason.SESSION_CREATED_BY_IME, true);
                         if (res.method != null) {
-                            mCurClient.client.onBindMethod(res);
+                            mCurClient.mClient.onBindMethod(res);
                         }
                         return;
                     }
@@ -2825,7 +2844,7 @@
 
     @GuardedBy("ImfLock.class")
     void requestClientSessionLocked(ClientState cs) {
-        if (!cs.sessionRequested) {
+        if (!cs.mSessionRequested) {
             if (DEBUG) Slog.v(TAG, "Creating new session for client " + cs);
             final InputChannel serverChannel;
             final InputChannel clientChannel;
@@ -2835,7 +2854,7 @@
                 clientChannel = channels[1];
             }
 
-            cs.sessionRequested = true;
+            cs.mSessionRequested = true;
 
             final IInputMethodInvoker curMethod = getCurMethodLocked();
             final IInputMethodSessionCallback.Stub callback =
@@ -2878,9 +2897,9 @@
 
     @GuardedBy("ImfLock.class")
     void clearClientSessionLocked(ClientState cs) {
-        finishSessionLocked(cs.curSession);
-        cs.curSession = null;
-        cs.sessionRequested = false;
+        finishSessionLocked(cs.mCurSession);
+        cs.mCurSession = null;
+        cs.mSessionRequested = false;
     }
 
     @GuardedBy("ImfLock.class")
@@ -2904,18 +2923,18 @@
     @GuardedBy("ImfLock.class")
     private void finishSessionLocked(SessionState sessionState) {
         if (sessionState != null) {
-            if (sessionState.session != null) {
+            if (sessionState.mSession != null) {
                 try {
-                    sessionState.session.finishSession();
+                    sessionState.mSession.finishSession();
                 } catch (RemoteException e) {
                     Slog.w(TAG, "Session failed to close due to remote exception", e);
                     updateSystemUiLocked(0 /* vis */, mBackDisposition);
                 }
-                sessionState.session = null;
+                sessionState.mSession = null;
             }
-            if (sessionState.channel != null) {
-                sessionState.channel.dispose();
-                sessionState.channel = null;
+            if (sessionState.mChannel != null) {
+                sessionState.mChannel.dispose();
+                sessionState.mChannel = null;
             }
         }
     }
@@ -3014,7 +3033,7 @@
                 InputMethodService.IME_ACTIVE | InputMethodService.IME_VISIBLE);
         return (canImeDrawsImeNavBar ? InputMethodNavButtonFlags.IME_DRAWS_IME_NAV_BAR : 0)
                 | (shouldShowImeSwitcherWhenImeIsShown
-                        ? InputMethodNavButtonFlags.SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN : 0);
+                ? InputMethodNavButtonFlags.SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN : 0);
     }
 
     @GuardedBy("ImfLock.class")
@@ -3037,17 +3056,17 @@
             return false;
         }
 
-        List<InputMethodInfo> imis = mSettings.getEnabledInputMethodListWithFilterLocked(
+        List<InputMethodInfo> imes = mSettings.getEnabledInputMethodListWithFilterLocked(
                 InputMethodInfo::shouldShowInInputMethodPicker);
-        final int N = imis.size();
-        if (N > 2) return true;
-        if (N < 1) return false;
+        final int numImes = imes.size();
+        if (numImes > 2) return true;
+        if (numImes < 1) return false;
         int nonAuxCount = 0;
         int auxCount = 0;
         InputMethodSubtype nonAuxSubtype = null;
         InputMethodSubtype auxSubtype = null;
-        for(int i = 0; i < N; ++i) {
-            final InputMethodInfo imi = imis.get(i);
+        for (int i = 0; i < numImes; ++i) {
+            final InputMethodInfo imi = imes.get(i);
             final List<InputMethodSubtype> subtypes =
                     mSettings.getEnabledInputMethodSubtypeListLocked(mContext, imi, true);
             final int subtypeCount = subtypes.size();
@@ -3071,8 +3090,8 @@
         } else if (nonAuxCount == 1 && auxCount == 1) {
             if (nonAuxSubtype != null && auxSubtype != null
                     && (nonAuxSubtype.getLocale().equals(auxSubtype.getLocale())
-                            || auxSubtype.overridesImplicitlyEnabledSubtype()
-                            || nonAuxSubtype.overridesImplicitlyEnabledSubtype())
+                    || auxSubtype.overridesImplicitlyEnabledSubtype()
+                    || nonAuxSubtype.overridesImplicitlyEnabledSubtype())
                     && nonAuxSubtype.containsExtraValueKey(TAG_TRY_SUPPRESSING_IME_SWITCHER)) {
                 return false;
             }
@@ -3162,7 +3181,7 @@
         }
 
         // TODO: Move this clearing calling identity block to setImeWindowStatus after making sure
-        // all updateSystemUi happens on system previlege.
+        // all updateSystemUi happens on system privilege.
         final long ident = Binder.clearCallingIdentity();
         try {
             if (!mCurPerceptible) {
@@ -3228,7 +3247,7 @@
     void updateInputMethodsFromSettingsLocked(boolean enabledMayChange) {
         if (enabledMayChange) {
             List<InputMethodInfo> enabled = mSettings.getEnabledInputMethodListLocked();
-            for (int i=0; i<enabled.size(); i++) {
+            for (int i = 0; i < enabled.size(); i++) {
                 // We allow the user to select "disabled until used" apps, so if they
                 // are enabling one of those here we now need to make it enabled.
                 InputMethodInfo imm = enabled.get(i);
@@ -3349,14 +3368,11 @@
         ImeTracing.getInstance().triggerManagerServiceDump(
                 "InputMethodManagerService#showSoftInput");
         synchronized (ImfLock.class) {
-            if (!calledFromValidUserLocked()) {
+            if (!canInteractWithImeLocked(uid, client, "showSoftInput")) {
                 return false;
             }
             final long ident = Binder.clearCallingIdentity();
             try {
-                if (!canInteractWithImeLocked(uid, client, "showSoftInput")) {
-                    return false;
-                }
                 if (DEBUG) Slog.v(TAG, "Client requesting input be shown");
                 return showCurrentInputLocked(windowToken, flags, resultReceiver, reason);
             } finally {
@@ -3370,41 +3386,48 @@
     @Override
     public void startStylusHandwriting(IInputMethodClient client) {
         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.startStylusHandwriting");
-        ImeTracing.getInstance().triggerManagerServiceDump(
-                "InputMethodManagerService#startStylusHandwriting");
-        int uid = Binder.getCallingUid();
-        synchronized (ImfLock.class) {
-            if (!calledFromValidUserLocked()) {
-                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-                return;
-            }
-            final long ident = Binder.clearCallingIdentity();
-            try {
+        try {
+            ImeTracing.getInstance().triggerManagerServiceDump(
+                    "InputMethodManagerService#startStylusHandwriting");
+            int uid = Binder.getCallingUid();
+            synchronized (ImfLock.class) {
                 if (!canInteractWithImeLocked(uid, client, "startStylusHandwriting")) {
                     return;
                 }
-                if (!mBindingController.supportsStylusHandwriting()) {
-                    Slog.w(TAG, "Stylus HW unsupported by IME. Ignoring startStylusHandwriting()");
+                if (!hasSupportedStylusLocked()) {
+                    Slog.w(TAG, "No supported Stylus hardware found on device. Ignoring"
+                            + " startStylusHandwriting()");
                     return;
                 }
-                final OptionalInt requestId = mHwController.getCurrentRequestId();
-                if (!requestId.isPresent()) {
-                    Slog.e(TAG, "Stylus handwriting was not initialized.");
-                    return;
+                final long ident = Binder.clearCallingIdentity();
+                try {
+                    if (!mBindingController.supportsStylusHandwriting()) {
+                        Slog.w(TAG,
+                                "Stylus HW unsupported by IME. Ignoring startStylusHandwriting()");
+                        return;
+                    }
+
+                    final OptionalInt requestId = mHwController.getCurrentRequestId();
+                    if (!requestId.isPresent()) {
+                        Slog.e(TAG, "Stylus handwriting was not initialized.");
+                        return;
+                    }
+                    if (!mHwController.isStylusGestureOngoing()) {
+                        Slog.e(TAG,
+                                "There is no ongoing stylus gesture to start stylus handwriting.");
+                        return;
+                    }
+                    if (DEBUG) Slog.v(TAG, "Client requesting Stylus Handwriting to be started");
+                    final IInputMethodInvoker curMethod = getCurMethodLocked();
+                    if (curMethod != null) {
+                        curMethod.canStartStylusHandwriting(requestId.getAsInt());
+                    }
+                } finally {
+                    Binder.restoreCallingIdentity(ident);
                 }
-                if (!mHwController.isStylusGestureOngoing()) {
-                    Slog.e(TAG, "There is no ongoing stylus gesture to start stylus handwriting.");
-                    return;
-                }
-                if (DEBUG) Slog.v(TAG, "Client requesting Stylus Handwriting to be started");
-                final IInputMethodInvoker curMethod = getCurMethodLocked();
-                if (curMethod != null) {
-                    curMethod.canStartStylusHandwriting(requestId.getAsInt());
-                }
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
             }
+        } finally {
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
     }
 
@@ -3412,21 +3435,13 @@
     @Override
     public void reportPerceptibleAsync(IBinder windowToken, boolean perceptible) {
         Objects.requireNonNull(windowToken, "windowToken must not be null");
-        int uid = Binder.getCallingUid();
         synchronized (ImfLock.class) {
-            if (!calledFromValidUserLocked()) {
+            if (mCurFocusedWindow != windowToken || mCurPerceptible == perceptible) {
                 return;
             }
-            final long ident = Binder.clearCallingIdentity();
-            try {
-                if (mCurFocusedWindow == windowToken
-                        && mCurPerceptible != perceptible) {
-                    mCurPerceptible = perceptible;
-                    updateSystemUiLocked(mImeWindowVis, mBackDisposition);
-                }
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
+            mCurPerceptible = perceptible;
+            Binder.withCleanCallingIdentity(() ->
+                    updateSystemUiLocked(mImeWindowVis, mBackDisposition));
         }
     }
 
@@ -3438,10 +3453,10 @@
             return false;
         }
 
-        if ((flags&InputMethodManager.SHOW_FORCED) != 0) {
+        if ((flags & InputMethodManager.SHOW_FORCED) != 0) {
             mShowExplicitlyRequested = true;
             mShowForced = true;
-        } else if ((flags&InputMethodManager.SHOW_IMPLICIT) == 0) {
+        } else if ((flags & InputMethodManager.SHOW_IMPLICIT) == 0) {
             mShowExplicitlyRequested = true;
         }
 
@@ -3478,29 +3493,12 @@
         ImeTracing.getInstance().triggerManagerServiceDump(
                 "InputMethodManagerService#hideSoftInput");
         synchronized (ImfLock.class) {
-            if (!InputMethodManagerService.this.calledFromValidUserLocked()) {
+            if (!canInteractWithImeLocked(uid, client, "hideSoftInput")) {
                 return false;
             }
             final long ident = Binder.clearCallingIdentity();
             try {
                 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.hideSoftInput");
-                if (mCurClient == null || client == null
-                        || mCurClient.client.asBinder() != client.asBinder()) {
-                    // We need to check if this is the current client with
-                    // focus in the window manager, to allow this call to
-                    // be made before input is started in it.
-                    final ClientState cs = mClients.get(client.asBinder());
-                    if (cs == null) {
-                        throw new IllegalArgumentException("unknown client " + client.asBinder());
-                    }
-                    if (!isImeClientFocused(windowToken, cs)) {
-                        if (DEBUG) {
-                            Slog.w(TAG, "Ignoring hideSoftInput of uid " + uid + ": " + client);
-                        }
-                        return false;
-                    }
-                }
-
                 if (DEBUG) Slog.v(TAG, "Client requesting input be hidden");
                 return InputMethodManagerService.this.hideCurrentInputLocked(windowToken,
                         flags, resultReceiver, reason);
@@ -3514,12 +3512,12 @@
     @GuardedBy("ImfLock.class")
     boolean hideCurrentInputLocked(IBinder windowToken, int flags, ResultReceiver resultReceiver,
             @SoftInputShowHideReason int reason) {
-        if ((flags&InputMethodManager.HIDE_IMPLICIT_ONLY) != 0
+        if ((flags & InputMethodManager.HIDE_IMPLICIT_ONLY) != 0
                 && (mShowExplicitlyRequested || mShowForced)) {
             if (DEBUG) Slog.v(TAG, "Not hiding: explicit show not cancelled by non-explicit hide");
             return false;
         }
-        if (mShowForced && (flags&InputMethodManager.HIDE_NOT_ALWAYS) != 0) {
+        if (mShowForced && (flags & InputMethodManager.HIDE_NOT_ALWAYS) != 0) {
             if (DEBUG) Slog.v(TAG, "Not hiding: forced show not cancelled by not-always hide");
             return false;
         }
@@ -3566,7 +3564,7 @@
 
     private boolean isImeClientFocused(IBinder windowToken, ClientState cs) {
         final int imeClientFocus = mWindowManagerInternal.hasInputMethodClientFocus(
-                windowToken, cs.uid, cs.pid, cs.selfReportedDisplayId);
+                windowToken, cs.mUid, cs.mPid, cs.mSelfReportedDisplayId);
         return imeClientFocus == WindowManagerInternal.ImeClientFocusResult.HAS_IME_FOCUS;
     }
 
@@ -3681,7 +3679,7 @@
         }
 
         final int imeClientFocus = mWindowManagerInternal.hasInputMethodClientFocus(
-                windowToken, cs.uid, cs.pid, cs.selfReportedDisplayId);
+                windowToken, cs.mUid, cs.mPid, cs.mSelfReportedDisplayId);
         switch (imeClientFocus) {
             case WindowManagerInternal.ImeClientFocusResult.DISPLAY_ID_MISMATCH:
                 Slog.e(TAG, "startInputOrWindowGainedFocusInternal: display ID mismatch.");
@@ -3693,8 +3691,8 @@
                 // next client receiving focus that has any interest in input will
                 // be calling through here after that change happens.
                 if (DEBUG) {
-                    Slog.w(TAG, "Focus gain on non-focused client " + cs.client
-                            + " (uid=" + cs.uid + " pid=" + cs.pid + ")");
+                    Slog.w(TAG, "Focus gain on non-focused client " + cs.mClient
+                            + " (uid=" + cs.mUid + " pid=" + cs.mPid + ")");
                 }
                 return InputBindResult.NOT_IME_TARGET_WINDOW;
             case WindowManagerInternal.ImeClientFocusResult.INVALID_DISPLAY_ID:
@@ -3705,19 +3703,19 @@
             // There is already an on-going pending user switch task.
             final int nextUserId = mUserSwitchHandlerTask.mToUserId;
             if (userId == nextUserId) {
-                scheduleSwitchUserTaskLocked(userId, cs.client);
+                scheduleSwitchUserTaskLocked(userId, cs.mClient);
                 return InputBindResult.USER_SWITCHING;
             }
             for (int profileId : mUserManager.getProfileIdsWithDisabled(nextUserId)) {
                 if (profileId == userId) {
-                    scheduleSwitchUserTaskLocked(userId, cs.client);
+                    scheduleSwitchUserTaskLocked(userId, cs.mClient);
                     return InputBindResult.USER_SWITCHING;
                 }
             }
             return InputBindResult.INVALID_USER;
         }
 
-        final boolean shouldClearFlag = mImePlatformCompatUtils.shouldClearShowForcedFlag(cs.uid);
+        final boolean shouldClearFlag = mImePlatformCompatUtils.shouldClearShowForcedFlag(cs.mUid);
         // In case mShowForced flag affects the next client to keep IME visible, when the current
         // client is leaving due to the next focused client, we clear mShowForced flag when the
         // next client's targetSdkVersion is T or higher.
@@ -3737,7 +3735,7 @@
         }
 
         if (userId != mSettings.getCurrentUserId()) {
-            scheduleSwitchUserTaskLocked(userId, cs.client);
+            scheduleSwitchUserTaskLocked(userId, cs.mClient);
             return InputBindResult.USER_SWITCHING;
         }
 
@@ -3778,7 +3776,7 @@
         final boolean doAutoShow =
                 (softInputMode & LayoutParams.SOFT_INPUT_MASK_ADJUST)
                         == LayoutParams.SOFT_INPUT_ADJUST_RESIZE
-                || mRes.getConfiguration().isLayoutSizeAtLeast(
+                        || mRes.getConfiguration().isLayoutSizeAtLeast(
                         Configuration.SCREENLAYOUT_SIZE_LARGE);
 
         // We want to start input before showing the IME, but after closing
@@ -3821,7 +3819,7 @@
                         // window token removed.
                         // Note that we can trust client's display ID as long as it matches
                         // to the display ID obtained from the window.
-                        if (cs.selfReportedDisplayId != mCurTokenDisplayId) {
+                        if (cs.mSelfReportedDisplayId != mCurTokenDisplayId) {
                             mBindingController.unbindCurrentMethod();
                         }
                     }
@@ -3936,7 +3934,7 @@
     private boolean canInteractWithImeLocked(
             int uid, IInputMethodClient client, String methodName) {
         if (mCurClient == null || client == null
-                || mCurClient.client.asBinder() != client.asBinder()) {
+                || mCurClient.mClient.asBinder() != client.asBinder()) {
             // We need to check if this is the current client with
             // focus in the window manager, to allow this call to
             // be made before input is started in it.
@@ -3967,12 +3965,15 @@
 
     @GuardedBy("ImfLock.class")
     private boolean canShowInputMethodPickerLocked(IInputMethodClient client) {
-        // TODO(yukawa): multi-display support.
         final int uid = Binder.getCallingUid();
         if (mCurFocusedWindowClient != null && client != null
-                && mCurFocusedWindowClient.client.asBinder() == client.asBinder()) {
+                && mCurFocusedWindowClient.mClient.asBinder() == client.asBinder()) {
             return true;
-        } else if (getCurIntentLocked() != null && InputMethodUtils.checkIfPackageBelongsToUid(
+        }
+        if (mSettings.getCurrentUserId() != UserHandle.getUserId(uid)) {
+            return false;
+        }
+        if (getCurIntentLocked() != null && InputMethodUtils.checkIfPackageBelongsToUid(
                 mAppOpsManager,
                 uid,
                 getCurIntentLocked().getComponent().getPackageName())) {
@@ -3985,9 +3986,6 @@
     public void showInputMethodPickerFromClient(IInputMethodClient client,
             int auxiliarySubtypeMode) {
         synchronized (ImfLock.class) {
-            if (!calledFromValidUserLocked()) {
-                return;
-            }
             if (!canShowInputMethodPickerLocked(client)) {
                 Slog.w(TAG, "Ignoring showInputMethodPickerFromClient of uid "
                         + Binder.getCallingUid() + ": " + client);
@@ -3997,21 +3995,16 @@
             // Always call subtype picker, because subtype picker is a superset of input method
             // picker.
             final int displayId =
-                    (mCurClient != null) ? mCurClient.selfReportedDisplayId : DEFAULT_DISPLAY;
+                    (mCurClient != null) ? mCurClient.mSelfReportedDisplayId : DEFAULT_DISPLAY;
             mHandler.obtainMessage(MSG_SHOW_IM_SUBTYPE_PICKER, auxiliarySubtypeMode, displayId)
                     .sendToTarget();
         }
     }
 
+    @EnforcePermission(Manifest.permission.WRITE_SECURE_SETTINGS)
     @Override
     public void showInputMethodPickerFromSystem(IInputMethodClient client, int auxiliarySubtypeMode,
             int displayId) {
-        if (mContext.checkCallingPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-                != PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException(
-                    "showInputMethodPickerFromSystem requires WRITE_SECURE_SETTINGS "
-                            + "permission");
-        }
         // Always call subtype picker, because subtype picker is a superset of input method
         // picker.
         mHandler.obtainMessage(MSG_SHOW_IM_SUBTYPE_PICKER, auxiliarySubtypeMode, displayId)
@@ -4022,6 +4015,18 @@
      * A test API for CTS to make sure that the input method menu is showing.
      */
     public boolean isInputMethodPickerShownForTest() {
+        if (mContext.checkCallingPermission(android.Manifest.permission.TEST_INPUT_METHOD)
+                != PackageManager.PERMISSION_GRANTED) {
+            final int callingUid = Binder.getCallingUid();
+            synchronized (ImfLock.class) {
+                if (!mLoggedDeniedIsInputMethodPickerShownForTestForUid.get(callingUid)) {
+                    EventLog.writeEvent(0x534e4554, "237317525", callingUid, "");
+                    mLoggedDeniedIsInputMethodPickerShownForTestForUid.put(callingUid, true);
+                }
+            }
+            throw new SecurityException(
+                    "isInputMethodPickerShownForTest requires TEST_INPUT_METHOD permission");
+        }
         synchronized (ImfLock.class) {
             return mMenuController.isisInputMethodPickerShownForTestLocked();
         }
@@ -4054,18 +4059,6 @@
         }
     }
 
-    @Override
-    public void showInputMethodAndSubtypeEnablerFromClient(
-            IInputMethodClient client, String inputMethodId) {
-        synchronized (ImfLock.class) {
-            // TODO(yukawa): Should we verify the display ID?
-            if (!calledFromValidUserLocked()) {
-                return;
-            }
-            showInputMethodAndSubtypeEnabler(inputMethodId);
-        }
-    }
-
     @BinderThread
     private boolean switchToPreviousInputMethod(@NonNull IBinder token) {
         synchronized (ImfLock.class) {
@@ -4101,11 +4094,11 @@
                 // the most applicable enabled keyboard subtype of the system imes.
                 final List<InputMethodInfo> enabled = mSettings.getEnabledInputMethodListLocked();
                 if (enabled != null) {
-                    final int N = enabled.size();
+                    final int enabledCount = enabled.size();
                     final String locale = mCurrentSubtype == null
                             ? mRes.getConfiguration().locale.toString()
                             : mCurrentSubtype.getLocale();
-                    for (int i = 0; i < N; ++i) {
+                    for (int i = 0; i < enabledCount; ++i) {
                         final InputMethodInfo imi = enabled.get(i);
                         if (imi.getSubtypeCount() > 0 && imi.isSystem()) {
                             InputMethodSubtype keyboardSubtype =
@@ -4116,7 +4109,7 @@
                                 targetLastImiId = imi.getId();
                                 subtypeId = SubtypeUtils.getSubtypeIdFromHashCode(imi,
                                         keyboardSubtype.hashCode());
-                                if(keyboardSubtype.getLocale().equals(locale)) {
+                                if (keyboardSubtype.getLocale().equals(locale)) {
                                     break;
                                 }
                             }
@@ -4164,10 +4157,7 @@
             final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethodLocked(
                     false /* onlyCurrentIme */, mMethodMap.get(getSelectedMethodIdLocked()),
                     mCurrentSubtype);
-            if (nextSubtype == null) {
-                return false;
-            }
-            return true;
+            return nextSubtype != null;
         }
     }
 
@@ -4256,8 +4246,9 @@
      * {@link InputMethodManager#getInputMethodWindowVisibleHeight()} and a dependency in
      * {@link InputMethodService#onCreate()}.
      *
-     * <p>TODO(Bug 113914148): Check if we can remove this.</p>
      * @return {@link WindowManagerInternal#getInputMethodWindowVisibleHeight(int)}
+     *
+     * @deprecated TODO(b/113914148): Check if we can remove this
      */
     @Override
     @Deprecated
@@ -4282,9 +4273,9 @@
         });
     }
 
+    @EnforcePermission(Manifest.permission.INTERNAL_SYSTEM_WINDOW)
     @Override
     public void removeImeSurface() {
-        mContext.enforceCallingPermission(Manifest.permission.INTERNAL_SYSTEM_WINDOW, null);
         mHandler.obtainMessage(MSG_REMOVE_IME_SURFACE).sendToTarget();
     }
 
@@ -4331,7 +4322,7 @@
                             + " is already registered by " + info.mParentClient);
                 }
                 if (info == null) {
-                    if (!mWindowManagerInternal.isUidAllowedOnDisplay(childDisplayId, cs.uid)) {
+                    if (!mWindowManagerInternal.isUidAllowedOnDisplay(childDisplayId, cs.mUid)) {
                         throw new SecurityException(cs + " cannot access to display #"
                                 + childDisplayId);
                     }
@@ -4340,12 +4331,12 @@
                 }
                 info.mMatrix.setValues(matrixValues);
 
-                if (mCurClient == null || mCurClient.curSession == null) {
+                if (mCurClient == null || mCurClient.mCurSession == null) {
                     return;
                 }
 
                 Matrix matrix = null;
-                int displayId = mCurClient.selfReportedDisplayId;
+                int displayId = mCurClient.mSelfReportedDisplayId;
                 boolean needToNotify = false;
                 while (true) {
                     needToNotify |= (displayId == childDisplayId);
@@ -4358,16 +4349,16 @@
                     } else {
                         matrix.postConcat(next.mMatrix);
                     }
-                    if (next.mParentClient.selfReportedDisplayId == mCurTokenDisplayId) {
+                    if (next.mParentClient.mSelfReportedDisplayId == mCurTokenDisplayId) {
                         if (needToNotify) {
                             final float[] values = new float[9];
                             matrix.getValues(values);
-                            mCurClient.client.updateVirtualDisplayToScreenMatrix(
+                            mCurClient.mClient.updateVirtualDisplayToScreenMatrix(
                                     getSequenceNumberLocked(), values);
                         }
                         break;
                     }
-                    displayId = info.mParentClient.selfReportedDisplayId;
+                    displayId = info.mParentClient.mSelfReportedDisplayId;
                 }
             }
         } catch (Throwable t) {
@@ -4384,10 +4375,142 @@
         mHandler.obtainMessage(MSG_REMOVE_IME_SURFACE_FROM_WINDOW, windowToken).sendToTarget();
     }
 
+    private void registerDeviceListenerAndCheckStylusSupport() {
+        final InputManager im = mContext.getSystemService(InputManager.class);
+        final IntArray stylusIds = getStylusInputDeviceIds(im);
+        if (stylusIds.size() > 0) {
+            synchronized (ImfLock.class) {
+                mStylusIds = new IntArray();
+                mStylusIds.addAll(stylusIds);
+            }
+        }
+        im.registerInputDeviceListener(new InputManager.InputDeviceListener() {
+            @Override
+            public void onInputDeviceAdded(int deviceId) {
+                if (isStylusDevice(im.getInputDevice(deviceId))) {
+                    add(deviceId);
+                }
+            }
+
+            @Override
+            public void onInputDeviceRemoved(int deviceId) {
+                remove(deviceId);
+            }
+
+            @Override
+            public void onInputDeviceChanged(int deviceId) {
+                if (isStylusDevice(im.getInputDevice(deviceId))) {
+                    add(deviceId);
+                } else {
+                    remove(deviceId);
+                }
+            }
+
+            private void add(int deviceId) {
+                synchronized (ImfLock.class) {
+                    if (mStylusIds == null) {
+                        mStylusIds = new IntArray();
+                    } else if (mStylusIds.indexOf(deviceId) != -1) {
+                        return;
+                    }
+                    Slog.d(TAG, "New Stylus device " + deviceId + " added.");
+                    mStylusIds.add(deviceId);
+                    // a new Stylus is detected. If IME supports handwriting and we don't have
+                    // handwriting initialized, lets do it now.
+                    if (!mHwController.getCurrentRequestId().isPresent()
+                            && mMethodMap.get(getSelectedMethodIdLocked())
+                            .supportsStylusHandwriting()) {
+                        scheduleResetStylusHandwriting();
+                    }
+                }
+            }
+
+            private void remove(int deviceId) {
+                synchronized (ImfLock.class) {
+                    if (mStylusIds == null || mStylusIds.size() == 0) {
+                        return;
+                    }
+                    if (mStylusIds.indexOf(deviceId) != -1) {
+                        mStylusIds.remove(deviceId);
+                        Slog.d(TAG, "Stylus device " + deviceId + " removed.");
+                    }
+                    if (mStylusIds.size() == 0) {
+                        mHwController.reset();
+                    }
+                }
+            }
+        }, mHandler);
+    }
+
+    private static boolean isStylusDevice(InputDevice inputDevice) {
+        return inputDevice.supportsSource(InputDevice.SOURCE_STYLUS)
+                || inputDevice.supportsSource(InputDevice.SOURCE_BLUETOOTH_STYLUS);
+    }
+
+    @GuardedBy("ImfLock.class")
+    private boolean hasSupportedStylusLocked() {
+        return mStylusIds != null && mStylusIds.size() != 0;
+    }
+
+    /**
+     * Helper method that adds a virtual stylus id for next handwriting session test if
+     * a stylus deviceId is not already registered on device.
+     */
+    @BinderThread
+    @EnforcePermission(Manifest.permission.INJECT_EVENTS)
+    @Override
+    public void addVirtualStylusIdForTestSession(IInputMethodClient client) {
+        int uid = Binder.getCallingUid();
+        synchronized (ImfLock.class) {
+            if (!canInteractWithImeLocked(uid, client, "addVirtualStylusIdForTestSession")) {
+                return;
+            }
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                if (!mBindingController.supportsStylusHandwriting()) {
+                    Slog.w(TAG, "Stylus HW unsupported by IME. Ignoring addVirtualStylusId()");
+                    return;
+                }
+
+                if (DEBUG) Slog.v(TAG, "Adding virtual stylus id for session");
+                if (mStylusIds == null) {
+                    mStylusIds = new IntArray();
+                }
+                mStylusIds.add(VIRTUAL_STYLUS_ID_FOR_TEST);
+                scheduleResetStylusHandwriting();
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+    }
+
+    @GuardedBy("ImfLock.class")
+    private void removeVirtualStylusIdForTestSessionLocked() {
+        int index;
+        if ((index = mStylusIds.indexOf(VIRTUAL_STYLUS_ID_FOR_TEST)) != -1) {
+            mStylusIds.remove(index);
+        }
+    }
+
+    private static IntArray getStylusInputDeviceIds(InputManager im) {
+        IntArray stylusIds = new IntArray();
+        for (int id : im.getInputDeviceIds()) {
+            if (!im.isInputDeviceEnabled(id)) {
+                continue;
+            }
+            InputDevice inputDevice = im.getInputDevice(id);
+            if (isStylusDevice(inputDevice)) {
+                stylusIds.add(id);
+            }
+        }
+
+        return stylusIds;
+    }
+
     /**
      * Starting point for dumping the IME tracing information in proto format.
      *
-     * @param clientProtoDump dump information from the IME client side
+     * @param protoDump dump information from the IME client side
      */
     @BinderThread
     @Override
@@ -4452,7 +4575,7 @@
         }
         for (ClientState state : clients.values()) {
             if (state != null) {
-                state.client.setImeTraceEnabled(true /* enabled */);
+                state.mClient.setImeTraceEnabled(true /* enabled */);
             }
         }
     }
@@ -4467,7 +4590,7 @@
         }
         for (ClientState state : clients.values()) {
             if (state != null) {
-                state.client.setImeTraceEnabled(false /* enabled */);
+                state.mClient.setImeTraceEnabled(false /* enabled */);
             }
         }
     }
@@ -4546,7 +4669,7 @@
                     // actual IME target.
                     mWindowManagerInternal.hideIme(
                             mHideRequestWindowMap.get(windowToken),
-                            mCurClient.selfReportedDisplayId);
+                            mCurClient.mSelfReportedDisplayId);
                 }
             } else {
                 // Send to window manager to show IME after IME layout finishes.
@@ -4564,6 +4687,7 @@
                 Slog.w(TAG, "IME requested to finish handwriting with a mismatched requestId: "
                         + requestId);
             }
+            removeVirtualStylusIdForTestSessionLocked();
             scheduleResetStylusHandwriting();
         }
     }
@@ -4576,7 +4700,7 @@
                     != PackageManager.PERMISSION_GRANTED) {
                 throw new SecurityException(
                         "Using null token requires permission "
-                        + android.Manifest.permission.WRITE_SECURE_SETTINGS);
+                                + android.Manifest.permission.WRITE_SECURE_SETTINGS);
             }
         } else if (getCurTokenLocked() != token) {
             Slog.w(TAG, "Ignoring setInputMethod of uid " + Binder.getCallingUid()
@@ -4644,14 +4768,14 @@
     @GuardedBy("ImfLock.class")
     void setEnabledSessionLocked(SessionState session) {
         if (mEnabledSession != session) {
-            if (mEnabledSession != null && mEnabledSession.session != null) {
+            if (mEnabledSession != null && mEnabledSession.mSession != null) {
                 if (DEBUG) Slog.v(TAG, "Disabling: " + mEnabledSession);
-                mEnabledSession.method.setSessionEnabled(mEnabledSession.session, false);
+                mEnabledSession.mMethod.setSessionEnabled(mEnabledSession.mSession, false);
             }
             mEnabledSession = session;
-            if (mEnabledSession != null && mEnabledSession.session != null) {
+            if (mEnabledSession != null && mEnabledSession.mSession != null) {
                 if (DEBUG) Slog.v(TAG, "Enabling: " + mEnabledSession);
-                mEnabledSession.method.setSessionEnabled(mEnabledSession.session, true);
+                mEnabledSession.mMethod.setSessionEnabled(mEnabledSession.mSession, true);
             }
         }
     }
@@ -4694,7 +4818,6 @@
     @UiThread
     @Override
     public boolean handleMessage(Message msg) {
-        SomeArgs args;
         switch (msg.what) {
             case MSG_SHOW_IM_SUBTYPE_PICKER:
                 final boolean showAuxSubtypes;
@@ -4731,9 +4854,9 @@
             case MSG_REMOVE_IME_SURFACE: {
                 synchronized (ImfLock.class) {
                     try {
-                        if (mEnabledSession != null && mEnabledSession.session != null
+                        if (mEnabledSession != null && mEnabledSession.mSession != null
                                 && !mShowRequested) {
-                            mEnabledSession.session.removeImeSurface();
+                            mEnabledSession.mSession.removeImeSurface();
                         }
                     } catch (RemoteException e) {
                     }
@@ -4745,8 +4868,8 @@
                 synchronized (ImfLock.class) {
                     try {
                         if (windowToken == mCurFocusedWindow
-                                && mEnabledSession != null && mEnabledSession.session != null) {
-                            mEnabledSession.session.removeImeSurface();
+                                && mEnabledSession != null && mEnabledSession.mSession != null) {
+                            mEnabledSession.mSession.removeImeSurface();
                         }
                     } catch (RemoteException e) {
                     }
@@ -4798,7 +4921,8 @@
             case MSG_RESET_HANDWRITING: {
                 synchronized (ImfLock.class) {
                     if (mBindingController.supportsStylusHandwriting()
-                            && getCurMethodLocked() != null) {
+                            && getCurMethodLocked() != null && hasSupportedStylusLocked()) {
+                        Slog.d(TAG, "Initializing Handwriting Spy");
                         mHwController.initializeHandwritingSpy(mCurTokenDisplayId);
                     } else {
                         mHwController.reset();
@@ -4855,8 +4979,8 @@
             updateSystemUiLocked(interactive ? mImeWindowVis : 0, mBackDisposition);
 
             // Inform the current client of the change in active status
-            if (mCurClient != null && mCurClient.client != null) {
-                mCurClient.client.setActive(mIsInteractive, mInFullscreenMode,
+            if (mCurClient != null && mCurClient.mClient != null) {
+                mCurClient.mClient.setActive(mIsInteractive, mInFullscreenMode,
                         mImePlatformCompatUtils.shouldFinishInputWithReportToIme(
                                 getCurMethodUidLocked()));
             }
@@ -4966,8 +5090,8 @@
                     mContext.getPackageManager().queryIntentServicesAsUser(
                             new Intent(InputMethod.SERVICE_INTERFACE),
                             PackageManager.MATCH_DISABLED_COMPONENTS, mSettings.getCurrentUserId());
-            final int N = allInputMethodServices.size();
-            for (int i = 0; i < N; ++i) {
+            final int numImes = allInputMethodServices.size();
+            for (int i = 0; i < numImes; ++i) {
                 final ServiceInfo si = allInputMethodServices.get(i).serviceInfo;
                 if (android.Manifest.permission.BIND_INPUT_METHOD.equals(si.permission)) {
                     mMyPackageMonitor.addKnownImePackageNameLocked(si.packageName);
@@ -4981,8 +5105,8 @@
             boolean enabledImeFound = false;
             boolean enabledNonAuxImeFound = false;
             final List<InputMethodInfo> enabledImes = mSettings.getEnabledInputMethodListLocked();
-            final int N = enabledImes.size();
-            for (int i = 0; i < N; ++i) {
+            final int numImes = enabledImes.size();
+            for (int i = 0; i < numImes; ++i) {
                 final InputMethodInfo imi = enabledImes.get(i);
                 if (mMethodList.contains(imi)) {
                     enabledImeFound = true;
@@ -5010,8 +5134,8 @@
             final ArrayList<InputMethodInfo> defaultEnabledIme =
                     InputMethodInfoUtils.getDefaultEnabledImes(mContext, mMethodList,
                             reenableMinimumNonAuxSystemImes);
-            final int N = defaultEnabledIme.size();
-            for (int i = 0; i < N; ++i) {
+            final int numImes = defaultEnabledIme.size();
+            for (int i = 0; i < numImes; ++i) {
                 final InputMethodInfo imi =  defaultEnabledIme.get(i);
                 if (DEBUG) {
                     Slog.d(TAG, "--- enable ime = " + imi);
@@ -5092,23 +5216,6 @@
 
     // ----------------------------------------------------------------------
 
-    private void showInputMethodAndSubtypeEnabler(String inputMethodId) {
-        Intent intent = new Intent(Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS);
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
-                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        if (!TextUtils.isEmpty(inputMethodId)) {
-            intent.putExtra(Settings.EXTRA_INPUT_METHOD_ID, inputMethodId);
-        }
-        final int userId;
-        synchronized (ImfLock.class) {
-            userId = mSettings.getCurrentUserId();
-        }
-        mContext.startActivityAsUser(intent, null, UserHandle.of(userId));
-    }
-
-    // ----------------------------------------------------------------------
-
     /**
      * Enable or disable the given IME by updating {@link Settings.Secure#ENABLED_INPUT_METHODS}.
      *
@@ -5270,7 +5377,7 @@
         if (userId == mSettings.getCurrentUserId()) {
             if (!mMethodMap.containsKey(imeId)
                     || !mSettings.getEnabledInputMethodListLocked()
-                            .contains(mMethodMap.get(imeId))) {
+                    .contains(mMethodMap.get(imeId))) {
                 return false; // IME is not found or not enabled.
             }
             setInputMethodLocked(imeId, NOT_A_SUBTYPE_ID);
@@ -5281,8 +5388,7 @@
                 mContext.getResources(), mContext.getContentResolver(), methodMap,
                 userId, false);
         if (!methodMap.containsKey(imeId)
-                || !settings.getEnabledInputMethodListLocked()
-                        .contains(methodMap.get(imeId))) {
+                || !settings.getEnabledInputMethodListLocked().contains(methodMap.get(imeId))) {
             return false; // IME is not found or not enabled.
         }
         settings.putSelectedInputMethod(imeId);
@@ -5405,10 +5511,12 @@
         @Override
         public void onImeParentChanged() {
             synchronized (ImfLock.class) {
-                // Hide the IME method menu when the IME surface parent will change in
-                // case seeing the dialog dismiss flickering during the next focused window
-                // starting the input connection.
-                mMenuController.hideInputMethodMenu();
+                // Hide the IME method menu only when the IME surface parent is changed by the
+                // input target changed, in case seeing the dialog dismiss flickering during
+                // the next focused window starting the input connection.
+                if (mLastImeTargetWindow != mCurFocusedWindow) {
+                    mMenuController.hideInputMethodMenu();
+                }
             }
         }
 
@@ -5436,18 +5544,18 @@
                     attachNewAccessibilityLocked(StartInputReason.SESSION_CREATED_BY_ACCESSIBILITY,
                             true);
 
-                    final SessionState sessionState = mCurClient.curSession;
+                    final SessionState sessionState = mCurClient.mCurSession;
                     final IInputMethodSession imeSession = sessionState == null
-                            ? null : sessionState.session;
+                            ? null : sessionState.mSession;
                     final SparseArray<IAccessibilityInputMethodSession>
                             accessibilityInputMethodSessions =
-                                    createAccessibilityInputMethodSessions(
-                                            mCurClient.mAccessibilitySessions);
+                            createAccessibilityInputMethodSessions(
+                                    mCurClient.mAccessibilitySessions);
                     final InputBindResult res = new InputBindResult(
                             InputBindResult.ResultCode.SUCCESS_WITH_ACCESSIBILITY_SESSION,
                             imeSession, accessibilityInputMethodSessions, null, getCurIdLocked(),
                             getSequenceNumberLocked(), mCurVirtualDisplayToScreenMatrix, false);
-                    mCurClient.client.onBindAccessibilityService(res, accessibilityConnectionId);
+                    mCurClient.mClient.onBindAccessibilityService(res, accessibilityConnectionId);
                 }
             }
         }
@@ -5458,11 +5566,11 @@
                 if (mCurClient != null) {
                     if (DEBUG) {
                         Slog.v(TAG, "unbindAccessibilityFromCurrentClientLocked: client="
-                                + mCurClient.client.asBinder());
+                                + mCurClient.mClient.asBinder());
                     }
                     // A11yManagerService unbinds the disabled accessibility service. We don't need
                     // to do it here.
-                    mCurClient.client.onUnbindAccessibilityService(getSequenceNumberLocked(),
+                    mCurClient.mClient.onUnbindAccessibilityService(getSequenceNumberLocked(),
                             accessibilityConnectionId);
                 }
                 // We only have sessions when we bound to an input method. Remove this session
@@ -5528,7 +5636,7 @@
             // This user ID can never bee spoofed.
             final int imeUserId = UserHandle.getUserId(uid);
             // This user ID can never bee spoofed.
-            final int appUserId = UserHandle.getUserId(mCurClient.uid);
+            final int appUserId = UserHandle.getUserId(mCurClient.mUid);
             // This user ID may be invalid if "contentUri" embedded an invalid user ID.
             final int contentUriOwnerUserId = ContentProvider.getUserIdFromUri(contentUri,
                     imeUserId);
@@ -5550,9 +5658,9 @@
             if (!calledWithValidTokenLocked(token)) {
                 return;
             }
-            if (mCurClient != null && mCurClient.client != null) {
+            if (mCurClient != null && mCurClient.mClient != null) {
                 mInFullscreenMode = fullscreen;
-                mCurClient.client.reportFullscreenMode(fullscreen);
+                mCurClient.mClient.reportFullscreenMode(fullscreen);
             }
         }
     }
@@ -5630,9 +5738,9 @@
 
         synchronized (ImfLock.class) {
             p.println("Current Input Method Manager state:");
-            int N = mMethodList.size();
+            int numImes = mMethodList.size();
             p.println("  Input Methods: mMethodMapUpdateCount=" + mMethodMapUpdateCount);
-            for (int i=0; i<N; i++) {
+            for (int i = 0; i < numImes; i++) {
                 InputMethodInfo info = mMethodList.get(i);
                 p.println("  InputMethod #" + i + ":");
                 info.dump(p, "    ");
@@ -5642,20 +5750,20 @@
             for (int i = 0; i < numClients; ++i) {
                 final ClientState ci = mClients.valueAt(i);
                 p.println("  Client " + ci + ":");
-                p.println("    client=" + ci.client);
-                p.println("    fallbackInputConnection=" + ci.fallbackInputConnection);
-                p.println("    sessionRequested=" + ci.sessionRequested);
+                p.println("    client=" + ci.mClient);
+                p.println("    fallbackInputConnection=" + ci.mFallbackInputConnection);
+                p.println("    sessionRequested=" + ci.mSessionRequested);
                 p.println("    sessionRequestedForAccessibility="
                         + ci.mSessionRequestedForAccessibility);
-                p.println("    curSession=" + ci.curSession);
+                p.println("    curSession=" + ci.mCurSession);
             }
             p.println("  mCurMethodId=" + getSelectedMethodIdLocked());
             client = mCurClient;
             p.println("  mCurClient=" + client + " mCurSeq=" + getSequenceNumberLocked());
             p.println("  mCurPerceptible=" + mCurPerceptible);
             p.println("  mCurFocusedWindow=" + mCurFocusedWindow
-                    + " softInputMode=" +
-                    InputMethodDebug.softInputModeToString(mCurFocusedWindowSoftInputMode)
+                    + " softInputMode="
+                    + InputMethodDebug.softInputModeToString(mCurFocusedWindowSoftInputMode)
                     + " client=" + mCurFocusedWindowClient);
             focusedWindowClient = mCurFocusedWindowClient;
             p.println("  mCurId=" + getCurIdLocked() + " mHaveConnection=" + hasConnectionLocked()
@@ -5676,6 +5784,8 @@
             p.println("  mSystemReady=" + mSystemReady + " mInteractive=" + mIsInteractive);
             p.println("  mSettingsObserver=" + mSettingsObserver);
             p.println("  mImeHiddenByDisplayPolicy=" + mImeHiddenByDisplayPolicy);
+            p.println("  mStylusIds=" + (mStylusIds != null
+                    ? Arrays.toString(mStylusIds.toArray()) : ""));
             p.println("  mSwitchingController:");
             mSwitchingController.dump(p);
             p.println("  mSettings:");
@@ -5697,7 +5807,7 @@
         if (client != null) {
             pw.flush();
             try {
-                TransferPipe.dumpAsync(client.client.asBinder(), fd, args);
+                TransferPipe.dumpAsync(client.mClient.asBinder(), fd, args);
             } catch (IOException | RemoteException e) {
                 p.println("Failed to dump input method client: " + e);
             }
@@ -5713,7 +5823,7 @@
             p.println(" ");
             pw.flush();
             try {
-                TransferPipe.dumpAsync(focusedWindowClient.client.asBinder(), fd, args);
+                TransferPipe.dumpAsync(focusedWindowClient.mClient.asBinder(), fd, args);
             } catch (IOException | RemoteException e) {
                 p.println("Failed to dump input method client in focused window: " + e);
             }
@@ -5951,25 +6061,26 @@
             }
         }
         synchronized (ImfLock.class) {
-            final PrintWriter pr = shellCommand.getOutPrintWriter();
             final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
                     mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
-            for (int userId : userIds) {
-                final List<InputMethodInfo> methods = all
-                        ? getInputMethodListLocked(userId, DirectBootAwareness.AUTO)
-                        : getEnabledInputMethodListLocked(userId);
-                if (userIds.length > 1) {
-                    pr.print("User #");
-                    pr.print(userId);
-                    pr.println(":");
-                }
-                for (InputMethodInfo info : methods) {
-                    if (brief) {
-                        pr.println(info.getId());
-                    } else {
-                        pr.print(info.getId());
+            try (PrintWriter pr = shellCommand.getOutPrintWriter()) {
+                for (int userId : userIds) {
+                    final List<InputMethodInfo> methods = all
+                            ? getInputMethodListLocked(userId, DirectBootAwareness.AUTO)
+                            : getEnabledInputMethodListLocked(userId);
+                    if (userIds.length > 1) {
+                        pr.print("User #");
+                        pr.print(userId);
                         pr.println(":");
-                        info.dump(pr::println, "  ");
+                    }
+                    for (InputMethodInfo info : methods) {
+                        if (brief) {
+                            pr.println(info.getId());
+                        } else {
+                            pr.print(info.getId());
+                            pr.println(":");
+                            info.dump(pr::println, "  ");
+                        }
                     }
                 }
             }
@@ -5979,8 +6090,9 @@
 
     /**
      * Handles {@code adb shell ime enable} and {@code adb shell ime disable}.
+     *
      * @param shellCommand {@link ShellCommand} object that is handling this command.
-     * @param enabled {@code true} if the command was {@code adb shell ime enable}.
+     * @param enabled      {@code true} if the command was {@code adb shell ime enable}.
      * @return Exit code of the command.
      */
     @BinderThread
@@ -5989,18 +6101,19 @@
             @NonNull ShellCommand shellCommand, boolean enabled) {
         final int userIdToBeResolved = handleOptionsForCommandsThatOnlyHaveUserOption(shellCommand);
         final String imeId = shellCommand.getNextArgRequired();
-        final PrintWriter out = shellCommand.getOutPrintWriter();
-        final PrintWriter error = shellCommand.getErrPrintWriter();
         boolean hasFailed = false;
-        synchronized (ImfLock.class) {
-            final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
-                    mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
-            for (int userId : userIds) {
-                if (!userHasDebugPriv(userId, shellCommand)) {
-                    continue;
+        try (PrintWriter out = shellCommand.getOutPrintWriter();
+             PrintWriter error = shellCommand.getErrPrintWriter()) {
+            synchronized (ImfLock.class) {
+                final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
+                        mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
+                for (int userId : userIds) {
+                    if (!userHasDebugPriv(userId, shellCommand)) {
+                        continue;
+                    }
+                    hasFailed |= !handleShellCommandEnableDisableInputMethodInternalLocked(
+                            userId, imeId, enabled, out, error);
                 }
-                hasFailed |= !handleShellCommandEnableDisableInputMethodInternalLocked(
-                        userId, imeId, enabled, out, error);
             }
         }
         return hasFailed ? ShellCommandResult.FAILURE : ShellCommandResult.SUCCESS;
@@ -6092,7 +6205,6 @@
                     + " failed due to its unrecognized IME ID.");
             return false;
         }
-
         out.print("Input method ");
         out.print(imeId);
         out.print(": ");
@@ -6105,6 +6217,7 @@
 
     /**
      * Handles {@code adb shell ime set}.
+     *
      * @param shellCommand {@link ShellCommand} object that is handling this command.
      * @return Exit code of the command.
      */
@@ -6113,32 +6226,34 @@
     private int handleShellCommandSetInputMethod(@NonNull ShellCommand shellCommand) {
         final int userIdToBeResolved = handleOptionsForCommandsThatOnlyHaveUserOption(shellCommand);
         final String imeId = shellCommand.getNextArgRequired();
-        final PrintWriter out = shellCommand.getOutPrintWriter();
-        final PrintWriter error = shellCommand.getErrPrintWriter();
         boolean hasFailed = false;
-        synchronized (ImfLock.class) {
-            final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
-                    mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
-            for (int userId : userIds) {
-                if (!userHasDebugPriv(userId, shellCommand)) {
-                    continue;
+        try (PrintWriter out = shellCommand.getOutPrintWriter();
+             PrintWriter error = shellCommand.getErrPrintWriter()) {
+            synchronized (ImfLock.class) {
+                final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
+                        mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
+                for (int userId : userIds) {
+                    if (!userHasDebugPriv(userId, shellCommand)) {
+                        continue;
+                    }
+                    boolean failedToSelectUnknownIme = !switchToInputMethodLocked(imeId,
+                            userId);
+                    if (failedToSelectUnknownIme) {
+                        error.print("Unknown input method ");
+                        error.print(imeId);
+                        error.print(" cannot be selected for user #");
+                        error.println(userId);
+                        // Also print this failure into logcat for better debuggability.
+                        Slog.e(TAG, "\"ime set " + imeId + "\" for user #" + userId
+                                + " failed due to its unrecognized IME ID.");
+                    } else {
+                        out.print("Input method ");
+                        out.print(imeId);
+                        out.print(" selected for user #");
+                        out.println(userId);
+                    }
+                    hasFailed |= failedToSelectUnknownIme;
                 }
-                boolean failedToSelectUnknownIme = !switchToInputMethodLocked(imeId, userId);
-                if (failedToSelectUnknownIme) {
-                    error.print("Unknown input method ");
-                    error.print(imeId);
-                    error.print(" cannot be selected for user #");
-                    error.println(userId);
-                    // Also print this failure into logcat for better debuggability.
-                    Slog.e(TAG, "\"ime set " + imeId + "\" for user #" + userId
-                            + " failed due to its unrecognized IME ID.");
-                } else {
-                    out.print("Input method ");
-                    out.print(imeId);
-                    out.print(" selected for user #");
-                    out.println(userId);
-                }
-                hasFailed |= failedToSelectUnknownIme;
             }
         }
         return hasFailed ? ShellCommandResult.FAILURE : ShellCommandResult.SUCCESS;
@@ -6152,70 +6267,72 @@
     @BinderThread
     @ShellCommandResult
     private int handleShellCommandResetInputMethod(@NonNull ShellCommand shellCommand) {
-        final PrintWriter out = shellCommand.getOutPrintWriter();
         final int userIdToBeResolved = handleOptionsForCommandsThatOnlyHaveUserOption(shellCommand);
         synchronized (ImfLock.class) {
-            final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
-                    mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
-            for (int userId : userIds) {
-                if (!userHasDebugPriv(userId, shellCommand)) {
-                    continue;
-                }
-                final String nextIme;
-                final List<InputMethodInfo> nextEnabledImes;
-                if (userId == mSettings.getCurrentUserId()) {
-                    hideCurrentInputLocked(mCurFocusedWindow, 0, null,
-                            SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND);
-                    mBindingController.unbindCurrentMethod();
-                    // Reset the current IME
-                    resetSelectedInputMethodAndSubtypeLocked(null);
-                    // Also reset the settings of the current IME
-                    mSettings.putSelectedInputMethod(null);
-                    // Disable all enabled IMEs.
-                    for (InputMethodInfo inputMethodInfo :
-                            mSettings.getEnabledInputMethodListLocked()) {
-                        setInputMethodEnabledLocked(inputMethodInfo.getId(), false);
+            try (PrintWriter out = shellCommand.getOutPrintWriter()) {
+                final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
+                        mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
+                for (int userId : userIds) {
+                    if (!userHasDebugPriv(userId, shellCommand)) {
+                        continue;
                     }
-                    // Re-enable with default enabled IMEs.
-                    for (InputMethodInfo imi : InputMethodInfoUtils.getDefaultEnabledImes(
-                            mContext, mMethodList)) {
-                        setInputMethodEnabledLocked(imi.getId(), true);
+                    final String nextIme;
+                    final List<InputMethodInfo> nextEnabledImes;
+                    if (userId == mSettings.getCurrentUserId()) {
+                        hideCurrentInputLocked(mCurFocusedWindow, 0, null,
+                                SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND);
+                        mBindingController.unbindCurrentMethod();
+                        // Reset the current IME
+                        resetSelectedInputMethodAndSubtypeLocked(null);
+                        // Also reset the settings of the current IME
+                        mSettings.putSelectedInputMethod(null);
+                        // Disable all enabled IMEs.
+                        for (InputMethodInfo inputMethodInfo :
+                                mSettings.getEnabledInputMethodListLocked()) {
+                            setInputMethodEnabledLocked(inputMethodInfo.getId(), false);
+                        }
+                        // Re-enable with default enabled IMEs.
+                        for (InputMethodInfo imi : InputMethodInfoUtils.getDefaultEnabledImes(
+                                mContext, mMethodList)) {
+                            setInputMethodEnabledLocked(imi.getId(), true);
+                        }
+                        updateInputMethodsFromSettingsLocked(true /* enabledMayChange */);
+                        InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
+                                getPackageManagerForUser(mContext, mSettings.getCurrentUserId()),
+                                mSettings.getEnabledInputMethodListLocked());
+                        nextIme = mSettings.getSelectedInputMethod();
+                        nextEnabledImes = mSettings.getEnabledInputMethodListLocked();
+                    } else {
+                        final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
+                        final ArrayList<InputMethodInfo> methodList = new ArrayList<>();
+                        final ArrayMap<String, List<InputMethodSubtype>> additionalSubtypeMap =
+                                new ArrayMap<>();
+                        AdditionalSubtypeUtils.load(additionalSubtypeMap, userId);
+                        queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap,
+                                methodMap, methodList, DirectBootAwareness.AUTO);
+                        final InputMethodSettings settings = new InputMethodSettings(
+                                mContext.getResources(), mContext.getContentResolver(), methodMap,
+                                userId, false);
+
+                        nextEnabledImes = InputMethodInfoUtils.getDefaultEnabledImes(mContext,
+                                methodList);
+                        nextIme = InputMethodInfoUtils.getMostApplicableDefaultIME(
+                                nextEnabledImes).getId();
+
+                        // Reset enabled IMEs.
+                        settings.putEnabledInputMethodsStr("");
+                        nextEnabledImes.forEach(
+                                imi -> settings.appendAndPutEnabledInputMethodLocked(
+                                        imi.getId(), false));
+
+                        // Reset selected IME.
+                        settings.putSelectedInputMethod(nextIme);
+                        settings.putSelectedSubtype(NOT_A_SUBTYPE_ID);
                     }
-                    updateInputMethodsFromSettingsLocked(true /* enabledMayChange */);
-                    InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
-                            getPackageManagerForUser(mContext, mSettings.getCurrentUserId()),
-                            mSettings.getEnabledInputMethodListLocked());
-                    nextIme = mSettings.getSelectedInputMethod();
-                    nextEnabledImes = mSettings.getEnabledInputMethodListLocked();
-                } else {
-                    final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
-                    final ArrayList<InputMethodInfo> methodList = new ArrayList<>();
-                    final ArrayMap<String, List<InputMethodSubtype>> additionalSubtypeMap =
-                            new ArrayMap<>();
-                    AdditionalSubtypeUtils.load(additionalSubtypeMap, userId);
-                    queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap,
-                            methodMap, methodList, DirectBootAwareness.AUTO);
-                    final InputMethodSettings settings = new InputMethodSettings(
-                            mContext.getResources(), mContext.getContentResolver(), methodMap,
-                            userId, false);
-
-                    nextEnabledImes = InputMethodInfoUtils.getDefaultEnabledImes(mContext,
-                            methodList);
-                    nextIme = InputMethodInfoUtils.getMostApplicableDefaultIME(
-                            nextEnabledImes).getId();
-
-                    // Reset enabled IMEs.
-                    settings.putEnabledInputMethodsStr("");
-                    nextEnabledImes.forEach(imi -> settings.appendAndPutEnabledInputMethodLocked(
-                            imi.getId(), false));
-
-                    // Reset selected IME.
-                    settings.putSelectedInputMethod(nextIme);
-                    settings.putSelectedSubtype(NOT_A_SUBTYPE_ID);
+                    out.println("Reset current and enabled IMEs for user #" + userId);
+                    out.println("  Selected: " + nextIme);
+                    nextEnabledImes.forEach(ime -> out.println("   Enabled: " + ime.getId()));
                 }
-                out.println("Reset current and enabled IMEs for user #" + userId);
-                out.println("  Selected: " + nextIme);
-                nextEnabledImes.forEach(ime -> out.println("   Enabled: " + ime.getId()));
             }
         }
         return ShellCommandResult.SUCCESS;
@@ -6230,23 +6347,26 @@
     @ShellCommandResult
     private int handleShellCommandTraceInputMethod(@NonNull ShellCommand shellCommand) {
         final String cmd = shellCommand.getNextArgRequired();
-        final PrintWriter pw = shellCommand.getOutPrintWriter();
-        switch (cmd) {
-            case "start":
-                ImeTracing.getInstance().startTrace(pw);
-                break;  // proceed to the next step to update the IME client processes.
-            case "stop":
-                ImeTracing.getInstance().stopTrace(pw);
-                break;  // proceed to the next step to update the IME client processes.
-            case "save-for-bugreport":
-                ImeTracing.getInstance().saveForBugreport(pw);
-                return ShellCommandResult.SUCCESS;  // no need to update the IME client processes.
-            default:
-                pw.println("Unknown command: " + cmd);
-                pw.println("Input method trace options:");
-                pw.println("  start: Start tracing");
-                pw.println("  stop: Stop tracing");
-                return ShellCommandResult.FAILURE;  // no need to update the IME client processes.
+        try (PrintWriter pw = shellCommand.getOutPrintWriter()) {
+            switch (cmd) {
+                case "start":
+                    ImeTracing.getInstance().startTrace(pw);
+                    break;  // proceed to the next step to update the IME client processes.
+                case "stop":
+                    ImeTracing.getInstance().stopTrace(pw);
+                    break;  // proceed to the next step to update the IME client processes.
+                case "save-for-bugreport":
+                    ImeTracing.getInstance().saveForBugreport(pw);
+                    // no need to update the IME client processes.
+                    return ShellCommandResult.SUCCESS;
+                default:
+                    pw.println("Unknown command: " + cmd);
+                    pw.println("Input method trace options:");
+                    pw.println("  start: Start tracing");
+                    pw.println("  stop: Stop tracing");
+                    // no need to update the IME client processes.
+                    return ShellCommandResult.FAILURE;
+            }
         }
         boolean isImeTraceEnabled = ImeTracing.getInstance().isEnabled();
         ArrayMap<IBinder, ClientState> clients;
@@ -6255,7 +6375,7 @@
         }
         for (ClientState state : clients.values()) {
             if (state != null) {
-                state.client.setImeTraceEnabled(isImeTraceEnabled);
+                state.mClient.setImeTraceEnabled(isImeTraceEnabled);
             }
         }
         return ShellCommandResult.SUCCESS;
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodUtils.java b/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
index 7013267..3373f0c 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
@@ -142,7 +142,7 @@
                 }
                 continue;
             }
-            ApplicationInfo ai = null;
+            ApplicationInfo ai;
             try {
                 ai = packageManagerForUser.getApplicationInfo(packageName,
                         PackageManager.ApplicationInfoFlags.of(
diff --git a/services/core/java/com/android/server/inputmethod/SubtypeUtils.java b/services/core/java/com/android/server/inputmethod/SubtypeUtils.java
index eb85dd0..7085868 100644
--- a/services/core/java/com/android/server/inputmethod/SubtypeUtils.java
+++ b/services/core/java/com/android/server/inputmethod/SubtypeUtils.java
@@ -85,8 +85,8 @@
                     continue;
                 }
             }
-            if (mode == SUBTYPE_MODE_ANY || TextUtils.isEmpty(mode) ||
-                    mode.equalsIgnoreCase(subtype.getMode())) {
+            if (mode == SUBTYPE_MODE_ANY || TextUtils.isEmpty(mode)
+                    || mode.equalsIgnoreCase(subtype.getMode())) {
                 return true;
             }
         }
@@ -237,17 +237,20 @@
     /**
      * If there are no selected subtypes, tries finding the most applicable one according to the
      * given locale.
-     * @param subtypes this function will search the most applicable subtype in subtypes
-     * @param mode subtypes will be filtered by mode
-     * @param locale subtypes will be filtered by locale
-     * @param canIgnoreLocaleAsLastResort if this function can't find the most applicable subtype,
-     * it will return the first subtype matched with mode
+     *
+     * @param subtypes                    a list of {@link InputMethodSubtype} to search
+     * @param mode                        the mode used for filtering subtypes
+     * @param locale                      the locale used for filtering subtypes
+     * @param canIgnoreLocaleAsLastResort when set to {@code true}, if this function can't find the
+     *                                    most applicable subtype, it will return the first subtype
+     *                                    matched with mode
+     *
      * @return the most applicable subtypeId
      */
     static InputMethodSubtype findLastResortApplicableSubtypeLocked(
             Resources res, List<InputMethodSubtype> subtypes, String mode, String locale,
             boolean canIgnoreLocaleAsLastResort) {
-        if (subtypes == null || subtypes.size() == 0) {
+        if (subtypes == null || subtypes.isEmpty()) {
             return null;
         }
         if (TextUtils.isEmpty(locale)) {
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index c6ea512..25d7d9f 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -938,10 +938,9 @@
         return mLocalService.getGnssTimeMillis();
     }
 
+    @android.annotation.EnforcePermission(allOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_FINE_LOCATION})
     @Override
     public void injectLocation(Location location) {
-        mContext.enforceCallingPermission(permission.LOCATION_HARDWARE, null);
-        mContext.enforceCallingPermission(ACCESS_FINE_LOCATION, null);
 
         Preconditions.checkArgument(location.isComplete());
 
@@ -1150,10 +1149,9 @@
         return Collections.singletonList(identity.getPackageName());
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
     @Override
     public void setExtraLocationControllerPackage(String packageName) {
-        mContext.enforceCallingPermission(permission.LOCATION_HARDWARE,
-                permission.LOCATION_HARDWARE + " permission required");
         synchronized (mLock) {
             mExtraLocationControllerPackage = packageName;
         }
@@ -1166,10 +1164,9 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
     @Override
     public void setExtraLocationControllerPackageEnabled(boolean enabled) {
-        mContext.enforceCallingPermission(permission.LOCATION_HARDWARE,
-                permission.LOCATION_HARDWARE + " permission required");
         synchronized (mLock) {
             mExtraLocationControllerPackageEnabled = enabled;
         }
@@ -1224,10 +1221,10 @@
         return mLocalService.isProviderEnabledForUser(provider, userId);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS)
     @Override
     @RequiresPermission(android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS)
     public void setAutomotiveGnssSuspended(boolean suspended) {
-        mContext.enforceCallingPermission(permission.CONTROL_AUTOMOTIVE_GNSS, null);
 
         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
             throw new IllegalStateException(
@@ -1237,10 +1234,10 @@
         mGnssManagerService.setAutomotiveGnssSuspended(suspended);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS)
     @Override
     @RequiresPermission(android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS)
     public boolean isAutomotiveGnssSuspended() {
-        mContext.enforceCallingPermission(permission.CONTROL_AUTOMOTIVE_GNSS, null);
 
         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
             throw new IllegalStateException(
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubClientBroker.java b/services/core/java/com/android/server/location/contexthub/ContextHubClientBroker.java
index 9fb1d8e..3cb3431 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubClientBroker.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubClientBroker.java
@@ -41,13 +41,18 @@
 import android.hardware.location.NanoAppState;
 import android.os.Binder;
 import android.os.Build;
+import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Looper;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.WorkSource;
 import android.util.Log;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.server.location.ClientBrokerProto;
 
 import java.util.Collections;
@@ -104,7 +109,9 @@
  * @hide
  */
 public class ContextHubClientBroker extends IContextHubClient.Stub
-        implements IBinder.DeathRecipient, AppOpsManager.OnOpChangedListener {
+        implements IBinder.DeathRecipient,
+                AppOpsManager.OnOpChangedListener,
+                PendingIntent.OnFinished {
     private static final String TAG = "ContextHubClientBroker";
 
     /**
@@ -124,6 +131,7 @@
     @ChangeId
     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R)
     private static final long CHANGE_ID_AUTH_STATE_DENIED = 181350407L;
+    private static final long WAKELOCK_TIMEOUT_MILLIS = 5 * 1000;
 
     /*
      * The context of the service.
@@ -154,7 +162,7 @@
      * The remote callback interface for this client. This will be set to null whenever the
      * client connection is closed (either explicitly or via binder death).
      */
-    private IContextHubClientCallback mCallbackInterface = null;
+    private IContextHubClientCallback mCallbackInterface;
 
     /*
      * True if the client is still registered with the Context Hub Service, false otherwise.
@@ -162,10 +170,21 @@
     private boolean mRegistered = true;
 
     /**
-     * String containing an attribution tag that was denoted in the {@link Context} of the
-     * creator of this broker. This is used when attributing the permissions usage of the broker.
+     * String containing an attribution tag that was denoted in the {@link Context} of the creator
+     * of this broker. This is used when attributing the permissions usage of the broker.
      */
-    private @Nullable String mAttributionTag;
+    @Nullable private String mAttributionTag;
+
+    /** Wakelock held while nanoapp message are in flight to the client */
+    @GuardedBy("mWakeLock")
+    private final WakeLock mWakeLock;
+
+    /**
+     * True if {@link #mWakeLock} is open for acquisition. It is set to false after the client is
+     * unregistered.
+     */
+    @GuardedBy("mWakeLock")
+    private boolean mIsWakeLockActive = true;
 
     /*
      * Internal interface used to invoke client callbacks.
@@ -207,13 +226,13 @@
     /*
      * True if a PendingIntent has been cancelled.
      */
-    private AtomicBoolean mIsPendingIntentCancelled = new AtomicBoolean(false);
+    private final AtomicBoolean mIsPendingIntentCancelled = new AtomicBoolean(false);
 
     /**
      * True if a permissions query has been issued and is being processed. Used to prevent too many
      * queries from being issued by a single client at once.
      */
-    private AtomicBoolean mIsPermQueryIssued = new AtomicBoolean(false);
+    private final AtomicBoolean mIsPermQueryIssued = new AtomicBoolean(false);
 
     /*
      * Map containing all nanoapps this client has a messaging channel with and whether it is
@@ -263,7 +282,7 @@
     /*
      * Helper class to manage registered PendingIntent requests from the client.
      */
-    private class PendingIntentRequest {
+    private static class PendingIntentRequest {
         /*
          * The PendingIntent object to request, null if there is no open request.
          */
@@ -322,6 +341,17 @@
         } else {
             mPendingIntentRequest = new PendingIntentRequest(pendingIntent, nanoAppId);
         }
+
+        if (packageName == null) {
+            String[] packages = mContext.getPackageManager().getPackagesForUid(
+                    Binder.getCallingUid());
+            if (packages != null && packages.length > 0) {
+                packageName = packages[0];
+            }
+            Log.e(TAG, "createClient: Provided package name null. Using first package name "
+                    + packageName);
+        }
+
         mPackage = packageName;
         mAttributionTag = attributionTag;
         mTransactionManager = transactionManager;
@@ -330,27 +360,60 @@
         mUid = Binder.getCallingUid();
         mAppOpsManager = context.getSystemService(AppOpsManager.class);
 
+        PowerManager powerManager = context.getSystemService(PowerManager.class);
+        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+        mWakeLock.setWorkSource(new WorkSource(mUid, mPackage));
+        mWakeLock.setReferenceCounted(true);
+
         startMonitoringOpChanges();
         sendHostEndpointConnectedEvent();
     }
 
     /* package */ ContextHubClientBroker(
-            Context context, IContextHubWrapper contextHubProxy,
-            ContextHubClientManager clientManager, ContextHubInfo contextHubInfo,
-            short hostEndPointId, IContextHubClientCallback callback, String attributionTag,
-            ContextHubTransactionManager transactionManager, String packageName) {
-        this(context, contextHubProxy, clientManager, contextHubInfo, hostEndPointId, callback,
-                attributionTag, transactionManager, null /* pendingIntent */, 0 /* nanoAppId */,
+            Context context,
+            IContextHubWrapper contextHubProxy,
+            ContextHubClientManager clientManager,
+            ContextHubInfo contextHubInfo,
+            short hostEndPointId,
+            IContextHubClientCallback callback,
+            String attributionTag,
+            ContextHubTransactionManager transactionManager,
+            String packageName) {
+        this(
+                context,
+                contextHubProxy,
+                clientManager,
+                contextHubInfo,
+                hostEndPointId,
+                callback,
+                attributionTag,
+                transactionManager,
+                /* pendingIntent= */ null,
+                /* nanoAppId= */ 0,
                 packageName);
     }
 
     /* package */ ContextHubClientBroker(
-            Context context, IContextHubWrapper contextHubProxy,
-            ContextHubClientManager clientManager, ContextHubInfo contextHubInfo,
-            short hostEndPointId, PendingIntent pendingIntent, long nanoAppId,
-            String attributionTag, ContextHubTransactionManager transactionManager) {
-        this(context, contextHubProxy, clientManager, contextHubInfo, hostEndPointId,
-                null /* callback */, attributionTag, transactionManager, pendingIntent, nanoAppId,
+            Context context,
+            IContextHubWrapper contextHubProxy,
+            ContextHubClientManager clientManager,
+            ContextHubInfo contextHubInfo,
+            short hostEndPointId,
+            PendingIntent pendingIntent,
+            long nanoAppId,
+            String attributionTag,
+            ContextHubTransactionManager transactionManager) {
+        this(
+                context,
+                contextHubProxy,
+                clientManager,
+                contextHubInfo,
+                hostEndPointId,
+                /* callback= */ null,
+                attributionTag,
+                transactionManager,
+                pendingIntent,
+                nanoAppId,
                 pendingIntent.getCreatorPackage());
     }
 
@@ -546,7 +609,7 @@
      * Notifies the client of a hub reset event if the connection is open.
      */
     /* package */ void onHubReset() {
-        invokeCallback(callback -> callback.onHubReset());
+        invokeCallback(IContextHubClientCallback::onHubReset);
         sendPendingIntent(() -> createIntent(ContextHubManager.EVENT_HUB_RESET));
 
         // Re-send the host endpoint connected event as the Context Hub restarted.
@@ -574,7 +637,7 @@
      * @return true if the given PendingIntent is currently registered, false otherwise
      */
     /* package */ boolean hasPendingIntent(PendingIntent intent, long nanoAppId) {
-        PendingIntent pendingIntent = null;
+        PendingIntent pendingIntent;
         long intentNanoAppId;
         synchronized (this) {
             pendingIntent = mPendingIntentRequest.getPendingIntent();
@@ -620,7 +683,7 @@
      */
     /* package */ boolean notePermissions(List<String> permissions, String noteMessage) {
         for (String permission : permissions) {
-            int opCode = mAppOpsManager.permissionToOpCode(permission);
+            int opCode = AppOpsManager.permissionToOpCode(permission);
             if (opCode != AppOpsManager.OP_NONE) {
                 try {
                     if (mAppOpsManager.noteOp(opCode, mUid, mPackage, mAttributionTag, noteMessage)
@@ -773,6 +836,7 @@
     private synchronized void invokeCallback(CallbackConsumer consumer) {
         if (mCallbackInterface != null) {
             try {
+                acquireWakeLock();
                 consumer.accept(mCallbackInterface);
             } catch (RemoteException e) {
                 Log.e(TAG, "RemoteException while invoking client callback (host endpoint ID = "
@@ -836,19 +900,29 @@
      * Sends a PendingIntent with extra Intent data
      *
      * @param pendingIntent the PendingIntent
-     * @param intent        the extra Intent data
+     * @param intent the extra Intent data
      */
     private void doSendPendingIntent(PendingIntent pendingIntent, Intent intent) {
         try {
             String requiredPermission = Manifest.permission.ACCESS_CONTEXT_HUB;
+            acquireWakeLock();
             pendingIntent.send(
-                    mContext, 0 /* code */, intent, null /* onFinished */, null /* Handler */,
-                    requiredPermission, null /* options */);
+                    mContext,
+                    /* code= */ 0,
+                    intent,
+                    /* onFinished= */ this,
+                    /* handler= */ null,
+                    requiredPermission,
+                    /* options= */ null);
         } catch (PendingIntent.CanceledException e) {
             mIsPendingIntentCancelled.set(true);
             // The PendingIntent is no longer valid
-            Log.w(TAG, "PendingIntent has been canceled, unregistering from client"
-                    + " (host endpoint ID " + mHostEndPointId + ")");
+            Log.w(
+                    TAG,
+                    "PendingIntent has been canceled, unregistering from client"
+                            + " (host endpoint ID "
+                            + mHostEndPointId
+                            + ")");
             close();
         }
     }
@@ -868,13 +942,14 @@
             mCallbackInterface.asBinder().unlinkToDeath(this, 0 /* flags */);
             mCallbackInterface = null;
         }
+        // The client is only unregistered and cleared when there is NOT any PendingIntent
         if (!mPendingIntentRequest.hasPendingIntent() && mRegistered) {
             mClientManager.unregisterClient(mHostEndPointId);
             mRegistered = false;
+            mAppOpsManager.stopWatchingMode(this);
+            mContextHubProxy.onHostEndpointDisconnected(mHostEndPointId);
+            releaseWakeLockOnExit();
         }
-        mAppOpsManager.stopWatchingMode(this);
-
-        mContextHubProxy.onHostEndpointDisconnected(mHostEndPointId);
     }
 
     private String authStateToString(@ContextHubManager.AuthorizationState int state) {
@@ -925,34 +1000,111 @@
 
     @Override
     public String toString() {
-        String out = "[ContextHubClient ";
-        out += "endpointID: " + getHostEndPointId() + ", ";
-        out += "contextHub: " + getAttachedContextHubId() + ", ";
+        StringBuilder out = new StringBuilder("[ContextHubClient ");
+        out.append("endpointID: ").append(getHostEndPointId()).append(", ");
+        out.append("contextHub: ").append(getAttachedContextHubId()).append(", ");
         if (mAttributionTag != null) {
-            out += "attributionTag: " + getAttributionTag() + ", ";
+            out.append("attributionTag: ").append(getAttributionTag()).append(", ");
         }
         if (mPendingIntentRequest.isValid()) {
-            out += "intentCreatorPackage: " + mPackage + ", ";
-            out += "nanoAppId: 0x" + Long.toHexString(mPendingIntentRequest.getNanoAppId());
+            out.append("intentCreatorPackage: ").append(mPackage).append(", ");
+            out.append("nanoAppId: 0x")
+                    .append(Long.toHexString(mPendingIntentRequest.getNanoAppId()));
         } else {
-            out += "package: " + mPackage;
+            out.append("package: ").append(mPackage);
         }
         if (mMessageChannelNanoappIdMap.size() > 0) {
-            out += " messageChannelNanoappSet: (";
+            out.append(" messageChannelNanoappSet: (");
             Iterator<Map.Entry<Long, Integer>> it =
                     mMessageChannelNanoappIdMap.entrySet().iterator();
             while (it.hasNext()) {
                 Map.Entry<Long, Integer> entry = it.next();
-                out += "0x" + Long.toHexString(entry.getKey()) + " auth state: "
-                        + authStateToString(entry.getValue());
+                out.append("0x")
+                        .append(Long.toHexString(entry.getKey()))
+                        .append(" auth state: ")
+                        .append(authStateToString(entry.getValue()));
                 if (it.hasNext()) {
-                    out += ",";
+                    out.append(",");
                 }
             }
-            out += ")";
+            out.append(")");
         }
-        out += "]";
+        synchronized (mWakeLock) {
+            out.append("wakelock: ").append(mWakeLock);
+        }
+        out.append("]");
+        return out.toString();
+    }
 
-        return out;
+    /** Callback that arrives when direct-call message callback delivery completed */
+    @Override
+    public void callbackFinished() {
+        releaseWakeLock();
+    }
+
+    @Override
+    public void onSendFinished(
+            PendingIntent pendingIntent,
+            Intent intent,
+            int resultCode,
+            String resultData,
+            Bundle resultExtras) {
+        releaseWakeLock();
+    }
+
+    private void acquireWakeLock() {
+        Binder.withCleanCallingIdentity(
+                () -> {
+                    synchronized (mWakeLock) {
+                        if (mIsWakeLockActive) {
+                            mWakeLock.acquire(WAKELOCK_TIMEOUT_MILLIS);
+                        }
+                    }
+                });
+    }
+
+    /**
+     * Releases the wakelock.
+     *
+     * <p>The check-and-release operation should be atomic to avoid overly release.
+     */
+    private void releaseWakeLock() {
+        Binder.withCleanCallingIdentity(
+                () -> {
+                    synchronized (mWakeLock) {
+                        if (mWakeLock.isHeld()) {
+                            try {
+                                mWakeLock.release();
+                            } catch (RuntimeException e) {
+                                Log.e(TAG, "Releasing the wakelock fails - ", e);
+                            }
+                        }
+                    }
+                });
+    }
+
+    /**
+     * Releases the wakelock for all the acquisitions during cleanup.
+     *
+     * <p>The check-and-release operation should be atomic to avoid overly release.
+     */
+    private void releaseWakeLockOnExit() {
+        Binder.withCleanCallingIdentity(
+                () -> {
+                    synchronized (mWakeLock) {
+                        mIsWakeLockActive = false;
+                        while (mWakeLock.isHeld()) {
+                            try {
+                                mWakeLock.release();
+                            } catch (RuntimeException e) {
+                                Log.e(
+                                        TAG,
+                                        "Releasing the wakelock for all acquisitions fails - ",
+                                        e);
+                                break;
+                            }
+                        }
+                    }
+                });
     }
 }
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
index 95178f4..3ad5fc1 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
@@ -374,44 +374,69 @@
      */
     private IContextHubClientCallback createDefaultClientCallback(int contextHubId) {
         return new IContextHubClientCallback.Stub() {
+            private void finishCallback() {
+                try {
+                    IContextHubClient client = mDefaultClientMap.get(contextHubId);
+                    client.callbackFinished();
+                } catch (RemoteException e) {
+                    Log.e(
+                            TAG,
+                            "RemoteException while finishing callback for hub (ID = "
+                                    + contextHubId
+                                    + ")",
+                            e);
+                }
+            }
+
             @Override
             public void onMessageFromNanoApp(NanoAppMessage message) {
-                int nanoAppHandle = mNanoAppStateManager.getNanoAppHandle(
-                        contextHubId, message.getNanoAppId());
+                int nanoAppHandle =
+                        mNanoAppStateManager.getNanoAppHandle(contextHubId, message.getNanoAppId());
 
                 onMessageReceiptOldApi(
-                        message.getMessageType(), contextHubId, nanoAppHandle,
+                        message.getMessageType(),
+                        contextHubId,
+                        nanoAppHandle,
                         message.getMessageBody());
+
+                finishCallback();
             }
 
             @Override
             public void onHubReset() {
                 byte[] data = {android.hardware.contexthub.V1_0.TransactionResult.SUCCESS};
                 onMessageReceiptOldApi(MSG_HUB_RESET, contextHubId, OS_APP_INSTANCE, data);
+                finishCallback();
             }
 
             @Override
             public void onNanoAppAborted(long nanoAppId, int abortCode) {
+                finishCallback();
             }
 
             @Override
             public void onNanoAppLoaded(long nanoAppId) {
+                finishCallback();
             }
 
             @Override
             public void onNanoAppUnloaded(long nanoAppId) {
+                finishCallback();
             }
 
             @Override
             public void onNanoAppEnabled(long nanoAppId) {
+                finishCallback();
             }
 
             @Override
             public void onNanoAppDisabled(long nanoAppId) {
+                finishCallback();
             }
 
             @Override
             public void onClientAuthorizationChanged(long nanoAppId, int authorization) {
+                finishCallback();
             }
         };
     }
@@ -440,9 +465,9 @@
         new ContextHubShellCommand(mContext, this).exec(this, in, out, err, args, callback, result);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
     public int registerCallback(IContextHubCallback callback) throws RemoteException {
-        checkPermissions();
         mCallbacksList.register(callback);
 
         Log.d(TAG, "Added callback, total callbacks " +
@@ -450,15 +475,15 @@
         return 0;
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
     public int[] getContextHubHandles() throws RemoteException {
-        checkPermissions();
         return ContextHubServiceUtil.createPrimitiveIntArray(mContextHubIdToInfoMap.keySet());
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
     public ContextHubInfo getContextHubInfo(int contextHubHandle) throws RemoteException {
-        checkPermissions();
         if (!mContextHubIdToInfoMap.containsKey(contextHubHandle)) {
             Log.e(TAG, "Invalid Context Hub handle " + contextHubHandle + " in getContextHubInfo");
             return null;
@@ -467,6 +492,7 @@
         return mContextHubIdToInfoMap.get(contextHubHandle);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     /**
      * Returns a List of ContextHubInfo object describing the available hubs.
      *
@@ -474,7 +500,6 @@
      */
     @Override
     public List<ContextHubInfo> getContextHubs() throws RemoteException {
-        checkPermissions();
         return mContextHubInfoList;
     }
 
@@ -538,9 +563,9 @@
         };
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
     public int loadNanoApp(int contextHubHandle, NanoApp nanoApp) throws RemoteException {
-        checkPermissions();
         if (mContextHubWrapper == null) {
             return -1;
         }
@@ -565,9 +590,9 @@
         return 0;
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
     public int unloadNanoApp(int nanoAppHandle) throws RemoteException {
-        checkPermissions();
         if (mContextHubWrapper == null) {
             return -1;
         }
@@ -590,17 +615,17 @@
         return 0;
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
     public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppHandle) throws RemoteException {
-        checkPermissions();
 
         return mNanoAppStateManager.getNanoAppInstanceInfo(nanoAppHandle);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
     public int[] findNanoAppOnHub(
             int contextHubHandle, NanoAppFilter filter) throws RemoteException {
-        checkPermissions();
 
         ArrayList<Integer> foundInstances = new ArrayList<>();
         if (filter != null) {
@@ -642,10 +667,10 @@
         return true;
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
     public int sendMessage(int contextHubHandle, int nanoAppHandle, ContextHubMessage msg)
             throws RemoteException {
-        checkPermissions();
         if (mContextHubWrapper == null) {
             return -1;
         }
@@ -824,6 +849,7 @@
         return mContextHubIdToInfoMap.containsKey(contextHubId);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     /**
      * Creates and registers a client at the service for the specified Context Hub.
      *
@@ -840,7 +866,6 @@
     public IContextHubClient createClient(
             int contextHubId, IContextHubClientCallback clientCallback,
             @Nullable String attributionTag, String packageName) throws RemoteException {
-        checkPermissions();
         if (!isValidContextHubId(contextHubId)) {
             throw new IllegalArgumentException("Invalid context hub ID " + contextHubId);
         }
@@ -853,6 +878,7 @@
                 contextHubInfo, clientCallback, attributionTag, mTransactionManager, packageName);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     /**
      * Creates and registers a PendingIntent client at the service for the specified Context Hub.
      *
@@ -868,7 +894,6 @@
     public IContextHubClient createPendingIntentClient(
             int contextHubId, PendingIntent pendingIntent, long nanoAppId,
             @Nullable String attributionTag) throws RemoteException {
-        checkPermissions();
         if (!isValidContextHubId(contextHubId)) {
             throw new IllegalArgumentException("Invalid context hub ID " + contextHubId);
         }
@@ -878,6 +903,7 @@
                 contextHubInfo, pendingIntent, nanoAppId, attributionTag, mTransactionManager);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     /**
      * Loads a nanoapp binary at the specified Context hub.
      *
@@ -890,7 +916,6 @@
     public void loadNanoAppOnHub(
             int contextHubId, IContextHubTransactionCallback transactionCallback,
             NanoAppBinary nanoAppBinary) throws RemoteException {
-        checkPermissions();
         if (!checkHalProxyAndContextHubId(
                 contextHubId, transactionCallback, ContextHubTransaction.TYPE_LOAD_NANOAPP)) {
             return;
@@ -907,6 +932,7 @@
         mTransactionManager.addTransaction(transaction);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     /**
      * Unloads a nanoapp from the specified Context Hub.
      *
@@ -919,7 +945,6 @@
     public void unloadNanoAppFromHub(
             int contextHubId, IContextHubTransactionCallback transactionCallback, long nanoAppId)
             throws RemoteException {
-        checkPermissions();
         if (!checkHalProxyAndContextHubId(
                 contextHubId, transactionCallback, ContextHubTransaction.TYPE_UNLOAD_NANOAPP)) {
             return;
@@ -930,6 +955,7 @@
         mTransactionManager.addTransaction(transaction);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     /**
      * Enables a nanoapp at the specified Context Hub.
      *
@@ -942,7 +968,6 @@
     public void enableNanoApp(
             int contextHubId, IContextHubTransactionCallback transactionCallback, long nanoAppId)
             throws RemoteException {
-        checkPermissions();
         if (!checkHalProxyAndContextHubId(
                 contextHubId, transactionCallback, ContextHubTransaction.TYPE_ENABLE_NANOAPP)) {
             return;
@@ -953,6 +978,7 @@
         mTransactionManager.addTransaction(transaction);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     /**
      * Disables a nanoapp at the specified Context Hub.
      *
@@ -965,7 +991,6 @@
     public void disableNanoApp(
             int contextHubId, IContextHubTransactionCallback transactionCallback, long nanoAppId)
             throws RemoteException {
-        checkPermissions();
         if (!checkHalProxyAndContextHubId(
                 contextHubId, transactionCallback, ContextHubTransaction.TYPE_DISABLE_NANOAPP)) {
             return;
@@ -976,6 +1001,7 @@
         mTransactionManager.addTransaction(transaction);
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     /**
      * Queries for a list of nanoapps from the specified Context hub.
      *
@@ -986,7 +1012,6 @@
     @Override
     public void queryNanoApps(int contextHubId, IContextHubTransactionCallback transactionCallback)
             throws RemoteException {
-        checkPermissions();
         if (!checkHalProxyAndContextHubId(
                 contextHubId, transactionCallback, ContextHubTransaction.TYPE_QUERY_NANOAPPS)) {
             return;
@@ -1042,6 +1067,9 @@
     }
 
     /* package */ void denyClientAuthState(int contextHubId, String packageName, long nanoAppId) {
+        Log.i(TAG, "Denying " + packageName + " access to " + Long.toHexString(nanoAppId)
+                + " on context hub # " + contextHubId);
+
         mClientManager.forEachClientOfHub(contextHubId, client -> {
             if (client.getPackageName().equals(packageName)) {
                 client.updateNanoAppAuthState(
@@ -1201,11 +1229,11 @@
             }
         } else {
             Log.d(TAG, "BT adapter not available. Defaulting to disabled");
-            if (mIsBtMainEnabled) {
+            if (forceUpdate || mIsBtMainEnabled) {
                 mIsBtMainEnabled = false;
                 mContextHubWrapper.onBtMainSettingChanged(mIsBtMainEnabled);
             }
-            if (mIsBtScanningEnabled) {
+            if (forceUpdate || mIsBtScanningEnabled) {
                 mIsBtScanningEnabled = false;
                 mContextHubWrapper.onBtScanningSettingChanged(mIsBtScanningEnabled);
             }
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index ee8a23c..f9dd7a9 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -95,7 +95,6 @@
 import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.provider.Settings.Secure;
-import android.provider.Settings.SettingNotFoundException;
 import android.security.AndroidKeyStoreMaintenance;
 import android.security.Authorization;
 import android.security.KeyStore;
@@ -144,8 +143,6 @@
 import com.android.server.locksettings.SyntheticPasswordManager.TokenType;
 import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager;
 import com.android.server.pm.UserManagerInternal;
-import com.android.server.utils.Watchable;
-import com.android.server.utils.Watcher;
 import com.android.server.wm.WindowManagerInternal;
 
 import libcore.util.HexEncoding;
@@ -227,7 +224,6 @@
     protected final Handler mHandler;
     @VisibleForTesting
     protected final LockSettingsStorage mStorage;
-    private final Watcher mStorageWatcher;
     private final LockSettingsStrongAuth mStrongAuth;
     private final SynchronizedStrongAuthTracker mStrongAuthTracker;
     private final BiometricDeferredQueue mBiometricDeferredQueue;
@@ -564,12 +560,6 @@
         }
     }
 
-    private class StorageWatcher extends Watcher {
-        public void onChange(Watchable what) {
-            LockSettingsService.this.onChange();
-        }
-    }
-
     public LockSettingsService(Context context) {
         this(new Injector(context));
     }
@@ -609,16 +599,6 @@
                 mStorage);
 
         LocalServices.addService(LockSettingsInternal.class, new LocalService());
-
-        mStorageWatcher = new StorageWatcher();
-        mStorage.registerObserver(mStorageWatcher);
-    }
-
-    /**
-     * Invalidate caches if the storage has changed.
-     */
-    private void onChange() {
-        LockPatternUtils.invalidateCredentialTypeCache();
     }
 
     /**
@@ -888,123 +868,6 @@
     }
 
     private void migrateOldData() {
-        // These Settings moved before multi-user was enabled, so we only have to do it for the
-        // root user.
-        if (getString("migrated", null, 0) == null) {
-            final ContentResolver cr = mContext.getContentResolver();
-            for (String validSetting : VALID_SETTINGS) {
-                String value = Settings.Secure.getStringForUser(cr, validSetting, cr.getUserId());
-                if (value != null) {
-                    setString(validSetting, value, 0);
-                }
-            }
-            // No need to move the password / pattern files. They're already in the right place.
-            setString("migrated", "true", 0);
-            Slog.i(TAG, "Migrated lock settings to new location");
-        }
-
-        // These Settings changed after multi-user was enabled, hence need to be moved per user.
-        if (getString("migrated_user_specific", null, 0) == null) {
-            final ContentResolver cr = mContext.getContentResolver();
-            List<UserInfo> users = mUserManager.getUsers();
-            for (int user = 0; user < users.size(); user++) {
-                // Migrate owner info
-                final int userId = users.get(user).id;
-                final String OWNER_INFO = Secure.LOCK_SCREEN_OWNER_INFO;
-                String ownerInfo = Settings.Secure.getStringForUser(cr, OWNER_INFO, userId);
-                if (!TextUtils.isEmpty(ownerInfo)) {
-                    setString(OWNER_INFO, ownerInfo, userId);
-                    Settings.Secure.putStringForUser(cr, OWNER_INFO, "", userId);
-                }
-
-                // Migrate owner info enabled. Note there was a bug where older platforms only
-                // stored this value if the checkbox was toggled at least once. The code detects
-                // this case by handling the exception.
-                final String OWNER_INFO_ENABLED = Secure.LOCK_SCREEN_OWNER_INFO_ENABLED;
-                boolean enabled;
-                try {
-                    int ivalue = Settings.Secure.getIntForUser(cr, OWNER_INFO_ENABLED, userId);
-                    enabled = ivalue != 0;
-                    setLong(OWNER_INFO_ENABLED, enabled ? 1 : 0, userId);
-                } catch (SettingNotFoundException e) {
-                    // Setting was never stored. Store it if the string is not empty.
-                    if (!TextUtils.isEmpty(ownerInfo)) {
-                        setLong(OWNER_INFO_ENABLED, 1, userId);
-                    }
-                }
-                Settings.Secure.putIntForUser(cr, OWNER_INFO_ENABLED, 0, userId);
-            }
-            // No need to move the password / pattern files. They're already in the right place.
-            setString("migrated_user_specific", "true", 0);
-            Slog.i(TAG, "Migrated per-user lock settings to new location");
-        }
-
-        // Migrates biometric weak such that the fallback mechanism becomes the primary.
-        if (getString("migrated_biometric_weak", null, 0) == null) {
-            List<UserInfo> users = mUserManager.getUsers();
-            for (int i = 0; i < users.size(); i++) {
-                int userId = users.get(i).id;
-                long type = getLong(LockPatternUtils.PASSWORD_TYPE_KEY,
-                        DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
-                        userId);
-                long alternateType = getLong(LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
-                        DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
-                        userId);
-                if (type == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK) {
-                    setLong(LockPatternUtils.PASSWORD_TYPE_KEY,
-                            alternateType,
-                            userId);
-                }
-                setLong(LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
-                        DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
-                        userId);
-            }
-            setString("migrated_biometric_weak", "true", 0);
-            Slog.i(TAG, "Migrated biometric weak to use the fallback instead");
-        }
-
-        // Migrates lockscreen.disabled. Prior to M, the flag was ignored when more than one
-        // user was present on the system, so if we're upgrading to M and there is more than one
-        // user we disable the flag to remain consistent.
-        if (getString("migrated_lockscreen_disabled", null, 0) == null) {
-            final List<UserInfo> users = mUserManager.getUsers();
-            final int userCount = users.size();
-            int switchableUsers = 0;
-            for (int i = 0; i < userCount; i++) {
-                if (users.get(i).supportsSwitchTo()) {
-                    switchableUsers++;
-                }
-            }
-
-            if (switchableUsers > 1) {
-                for (int i = 0; i < userCount; i++) {
-                    int id = users.get(i).id;
-
-                    if (getBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id)) {
-                        setBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id);
-                    }
-                }
-            }
-
-            setString("migrated_lockscreen_disabled", "true", 0);
-            Slog.i(TAG, "Migrated lockscreen disabled flag");
-        }
-
-        boolean isWatch = mContext.getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_WATCH);
-        // Wear used to set DISABLE_LOCKSCREEN to 'true', but because Wear now allows accounts
-        // and device management the lockscreen must be re-enabled now for users that upgrade.
-        if (isWatch && getString("migrated_wear_lockscreen_disabled", null, 0) == null) {
-            final List<UserInfo> users = mUserManager.getUsers();
-            final int userCount = users.size();
-            for (int i = 0; i < userCount; i++) {
-                int id = users.get(i).id;
-                setBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id);
-            }
-            setString("migrated_wear_lockscreen_disabled", "true", 0);
-            Slog.i(TAG, "Migrated lockscreen_disabled for Wear devices");
-        }
-
         if (getString("migrated_keystore_namespace", null, 0) == null) {
             boolean success = true;
             synchronized (mSpManager) {
@@ -1588,6 +1451,11 @@
             return;
         }
 
+        // Don't send empty credentials on unlock.
+        if (credential.isNone()) {
+            return;
+        }
+
         // A profile with a unified lock screen stores a randomly generated credential, so skip it.
         // Its parent will send credentials for the profile, as it stores the unified lock
         // credential.
@@ -1595,12 +1463,10 @@
             return;
         }
 
-        // RecoverableKeyStoreManager expects null for empty credential.
-        final byte[] secret = credential.isNone() ? null : credential.getCredential();
         // Send credentials for the user and any child profiles that share its lock screen.
         for (int profileId : getProfilesWithSameLockScreen(userId)) {
             mRecoverableKeyStoreManager.lockScreenSecretAvailable(
-                    credential.getType(), secret, profileId);
+                    credential.getType(), credential.getCredential(), profileId);
         }
     }
 
@@ -2573,24 +2439,6 @@
         return mRecoverableKeyStoreManager.getKey(alias);
     }
 
-    private static final String[] VALID_SETTINGS = new String[] {
-            LockPatternUtils.LOCKOUT_PERMANENT_KEY,
-            LockPatternUtils.PATTERN_EVER_CHOSEN_KEY,
-            LockPatternUtils.PASSWORD_TYPE_KEY,
-            LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
-            LockPatternUtils.LOCK_PASSWORD_SALT_KEY,
-            LockPatternUtils.DISABLE_LOCKSCREEN_KEY,
-            LockPatternUtils.LOCKSCREEN_OPTIONS,
-            LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK,
-            LockPatternUtils.BIOMETRIC_WEAK_EVER_CHOSEN_KEY,
-            LockPatternUtils.LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS,
-            LockPatternUtils.PASSWORD_HISTORY_KEY,
-            Secure.LOCK_PATTERN_ENABLED,
-            Secure.LOCK_BIOMETRIC_WEAK_FLAGS,
-            Secure.LOCK_PATTERN_VISIBLE,
-            Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED
-    };
-
     // Reading these settings needs the contacts permission
     private static final String[] READ_CONTACTS_PROTECTED_SETTINGS = new String[] {
             Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
@@ -2865,6 +2713,7 @@
             removeBiometricsForUser(userId);
         }
         setSyntheticPasswordHandleLocked(newHandle, userId);
+        LockPatternUtils.invalidateCredentialTypeCache();
         synchronizeUnifiedWorkChallengeForProfiles(userId, profilePasswords);
 
         setUserPasswordMetrics(credential, userId);
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
index d5a759d..76032f4 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
@@ -43,7 +43,6 @@
     private static final String COMMAND_SET_PIN = "set-pin";
     private static final String COMMAND_SET_PASSWORD = "set-password";
     private static final String COMMAND_CLEAR = "clear";
-    private static final String COMMAND_SP = "sp";
     private static final String COMMAND_SET_DISABLED = "set-disabled";
     private static final String COMMAND_VERIFY = "verify";
     private static final String COMMAND_GET_DISABLED = "get-disabled";
@@ -125,9 +124,6 @@
                 case COMMAND_CLEAR:
                     success = runClear();
                     break;
-                case COMMAND_SP:
-                    runChangeSp();
-                    break;
                 case COMMAND_SET_DISABLED:
                     runSetDisabled();
                     break;
@@ -224,20 +220,6 @@
         mNew = getNextArg();
     }
 
-    private void runChangeSp() {
-        if (mNew != null ) {
-            if ("1".equals(mNew)) {
-                mLockPatternUtils.enableSyntheticPassword();
-                getOutPrintWriter().println("Synthetic password enabled");
-            } else if ("0".equals(mNew)) {
-                mLockPatternUtils.disableSyntheticPassword();
-                getOutPrintWriter().println("Synthetic password disabled");
-            }
-        }
-        getOutPrintWriter().println(String.format("SP Enabled = %b",
-                mLockPatternUtils.isSyntheticPasswordEnabled()));
-    }
-
     private LockscreenCredential getOldCredential() {
         if (TextUtils.isEmpty(mOld)) {
             return LockscreenCredential.createNone();
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
index 9ddf1ef..92bb26a 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
@@ -44,10 +44,8 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
 import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.LockPatternUtils.CredentialType;
 import com.android.server.LocalServices;
 import com.android.server.PersistentDataBlockManagerInternal;
-import com.android.server.utils.WatchableImpl;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -67,11 +65,10 @@
 /**
  * Storage for the lock settings service.
  */
-class LockSettingsStorage extends WatchableImpl {
+class LockSettingsStorage {
 
     private static final String TAG = "LockSettingsStorage";
     private static final String TABLE = "locksettings";
-    private static final boolean DEBUG = false;
 
     private static final String COLUMN_KEY = "name";
     private static final String COLUMN_USERID = "user";
@@ -84,11 +81,10 @@
             COLUMN_KEY, COLUMN_VALUE
     };
 
-    private static final String SYSTEM_DIRECTORY = "/system/";
     private static final String CHILD_PROFILE_LOCK_FILE = "gatekeeper.profile.key";
 
     private static final String REBOOT_ESCROW_FILE = "reboot.escrow.key";
-    private static final String REBOOT_ESCROW_SERVER_BLOB = "reboot.escrow.server.blob.key";
+    private static final String REBOOT_ESCROW_SERVER_BLOB_FILE = "reboot.escrow.server.blob.key";
 
     private static final String SYNTHETIC_PASSWORD_DIRECTORY = "spblob/";
 
@@ -108,39 +104,6 @@
 
     private PersistentDataBlockManagerInternal mPersistentDataBlockManagerInternal;
 
-    @VisibleForTesting
-    public static class CredentialHash {
-
-        private CredentialHash(byte[] hash, @CredentialType int type) {
-            if (type != LockPatternUtils.CREDENTIAL_TYPE_NONE) {
-                if (hash == null) {
-                    throw new IllegalArgumentException("Empty hash for CredentialHash");
-                }
-            } else /* type == LockPatternUtils.CREDENTIAL_TYPE_NONE */ {
-                if (hash != null) {
-                    throw new IllegalArgumentException(
-                            "None type CredentialHash should not have hash");
-                }
-            }
-            this.hash = hash;
-            this.type = type;
-        }
-
-        static CredentialHash create(byte[] hash, int type) {
-            if (type == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
-                throw new IllegalArgumentException("Bad type for CredentialHash");
-            }
-            return new CredentialHash(hash, type);
-        }
-
-        static CredentialHash createEmptyHash() {
-            return new CredentialHash(null, LockPatternUtils.CREDENTIAL_TYPE_NONE);
-        }
-
-        byte[] hash;
-        @CredentialType int type;
-    }
-
     public LockSettingsStorage(Context context) {
         mContext = context;
         mOpenHelper = new DatabaseHelper(context);
@@ -172,7 +135,6 @@
         } finally {
             db.endTransaction();
         }
-        dispatchChange(this);
     }
 
     @VisibleForTesting
@@ -202,6 +164,16 @@
     }
 
     @VisibleForTesting
+    boolean isKeyValueCached(String key, int userId) {
+        return mCache.hasKeyValue(key, userId);
+    }
+
+    @VisibleForTesting
+    boolean isUserPrefetched(int userId) {
+        return mCache.isFetched(userId);
+    }
+
+    @VisibleForTesting
     public void removeKey(String key, int userId) {
         removeKey(mOpenHelper.getWritableDatabase(), key, userId);
     }
@@ -220,7 +192,6 @@
         } finally {
             db.endTransaction();
         }
-        dispatchChange(this);
     }
 
     public void prefetchUser(int userId) {
@@ -249,13 +220,7 @@
     }
 
     public void removeChildProfileLock(int userId) {
-        if (DEBUG)
-            Slog.e(TAG, "Remove child profile lock for user: " + userId);
-        try {
-            deleteFile(getChildProfileLockFile(userId));
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
+        deleteFile(getChildProfileLockFile(userId));
     }
 
     public void writeChildProfileLock(int userId, byte[] lock) {
@@ -287,39 +252,39 @@
     }
 
     public void writeRebootEscrowServerBlob(byte[] serverBlob) {
-        writeFile(getRebootEscrowServerBlob(), serverBlob);
+        writeFile(getRebootEscrowServerBlobFile(), serverBlob);
     }
 
     public byte[] readRebootEscrowServerBlob() {
-        return readFile(getRebootEscrowServerBlob());
+        return readFile(getRebootEscrowServerBlobFile());
     }
 
     public boolean hasRebootEscrowServerBlob() {
-        return hasFile(getRebootEscrowServerBlob());
+        return hasFile(getRebootEscrowServerBlobFile());
     }
 
     public void removeRebootEscrowServerBlob() {
-        deleteFile(getRebootEscrowServerBlob());
+        deleteFile(getRebootEscrowServerBlobFile());
     }
 
-    private boolean hasFile(String name) {
-        byte[] contents = readFile(name);
+    private boolean hasFile(File path) {
+        byte[] contents = readFile(path);
         return contents != null && contents.length > 0;
     }
 
-    private byte[] readFile(String name) {
+    private byte[] readFile(File path) {
         int version;
         synchronized (mCache) {
-            if (mCache.hasFile(name)) {
-                return mCache.peekFile(name);
+            if (mCache.hasFile(path)) {
+                return mCache.peekFile(path);
             }
             version = mCache.getVersion();
         }
 
-        byte[] stored = null;
-        try (RandomAccessFile raf = new RandomAccessFile(name, "r")) {
-            stored = new byte[(int) raf.length()];
-            raf.readFully(stored, 0, stored.length);
+        byte[] data = null;
+        try (RandomAccessFile raf = new RandomAccessFile(path, "r")) {
+            data = new byte[(int) raf.length()];
+            raf.readFully(data, 0, data.length);
             raf.close();
         } catch (FileNotFoundException suppressed) {
             // readFile() is also called by hasFile() to check the existence of files, in this
@@ -327,8 +292,8 @@
         } catch (IOException e) {
             Slog.e(TAG, "Cannot read file " + e);
         }
-        mCache.putFileIfUnchanged(name, stored, version);
-        return stored;
+        mCache.putFileIfUnchanged(path, data, version);
+        return data;
     }
 
     private void fsyncDirectory(File directory) {
@@ -342,23 +307,21 @@
         }
     }
 
-    private void writeFile(String name, byte[] hash) {
+    private void writeFile(File path, byte[] data) {
         synchronized (mFileWriteLock) {
             RandomAccessFile raf = null;
             try {
-                // Write the hash to file, requiring each write to be synchronized to the
+                // Write the data to the file, requiring each write to be synchronized to the
                 // underlying storage device immediately to avoid data loss in case of power loss.
-                // This also ensures future secdiscard operation on the file succeeds since the
-                // file would have been allocated on flash.
-                raf = new RandomAccessFile(name, "rws");
-                // Truncate the file if pattern is null, to clear the lock
-                if (hash == null || hash.length == 0) {
+                raf = new RandomAccessFile(path, "rws");
+                // Truncate the file if the data is empty.
+                if (data == null || data.length == 0) {
                     raf.setLength(0);
                 } else {
-                    raf.write(hash, 0, hash.length);
+                    raf.write(data, 0, data.length);
                 }
                 raf.close();
-                fsyncDirectory((new File(name)).getAbsoluteFile().getParentFile());
+                fsyncDirectory(path.getParentFile());
             } catch (IOException e) {
                 Slog.e(TAG, "Error writing to file " + e);
             } finally {
@@ -370,74 +333,64 @@
                     }
                 }
             }
-            mCache.putFile(name, hash);
-            dispatchChange(this);
+            mCache.putFile(path, data);
         }
     }
 
-    private void deleteFile(String name) {
-        if (DEBUG) Slog.e(TAG, "Delete file " + name);
+    private void deleteFile(File path) {
         synchronized (mFileWriteLock) {
-            File file = new File(name);
-            if (file.exists()) {
-                file.delete();
-                mCache.putFile(name, null);
+            if (path.exists()) {
+                // Zeroize the file to try to make its contents unrecoverable.  This is *not*
+                // guaranteed to be effective, and in fact it usually isn't, but it doesn't hurt.
+                try (RandomAccessFile raf = new RandomAccessFile(path, "rws")) {
+                    final int fileSize = (int) raf.length();
+                    raf.write(new byte[fileSize]);
+                } catch (Exception e) {
+                    Slog.w(TAG, "Failed to zeroize " + path, e);
+                }
+                path.delete();
+                mCache.putFile(path, null);
             }
-            dispatchChange(this);
         }
     }
 
     @VisibleForTesting
-    String getChildProfileLockFile(int userId) {
-        return getLockCredentialFilePathForUser(userId, CHILD_PROFILE_LOCK_FILE);
+    File getChildProfileLockFile(int userId) {
+        return getLockCredentialFileForUser(userId, CHILD_PROFILE_LOCK_FILE);
     }
 
     @VisibleForTesting
-    String getRebootEscrowFile(int userId) {
-        return getLockCredentialFilePathForUser(userId, REBOOT_ESCROW_FILE);
+    File getRebootEscrowFile(int userId) {
+        return getLockCredentialFileForUser(userId, REBOOT_ESCROW_FILE);
     }
 
     @VisibleForTesting
-    String getRebootEscrowServerBlob() {
+    File getRebootEscrowServerBlobFile() {
         // There is a single copy of server blob for all users.
-        return getLockCredentialFilePathForUser(UserHandle.USER_SYSTEM, REBOOT_ESCROW_SERVER_BLOB);
+        return getLockCredentialFileForUser(UserHandle.USER_SYSTEM, REBOOT_ESCROW_SERVER_BLOB_FILE);
     }
 
-    private String getLockCredentialFilePathForUser(int userId, String basename) {
-        String dataSystemDirectory = Environment.getDataDirectory().getAbsolutePath() +
-                        SYSTEM_DIRECTORY;
+    private File getLockCredentialFileForUser(int userId, String fileName) {
         if (userId == 0) {
-            // Leave it in the same place for user 0
-            return dataSystemDirectory + basename;
+            // The files for user 0 are stored directly in /data/system, since this is where they
+            // originally were, and they haven't been moved yet.
+            return new File(Environment.getDataSystemDirectory(), fileName);
         } else {
-            return new File(Environment.getUserSystemDirectory(userId), basename).getAbsolutePath();
+            return new File(Environment.getUserSystemDirectory(userId), fileName);
         }
     }
 
     public void writeSyntheticPasswordState(int userId, long handle, String name, byte[] data) {
         ensureSyntheticPasswordDirectoryForUser(userId);
-        writeFile(getSynthenticPasswordStateFilePathForUser(userId, handle, name), data);
+        writeFile(getSyntheticPasswordStateFileForUser(userId, handle, name), data);
     }
 
     public byte[] readSyntheticPasswordState(int userId, long handle, String name) {
-        return readFile(getSynthenticPasswordStateFilePathForUser(userId, handle, name));
+        return readFile(getSyntheticPasswordStateFileForUser(userId, handle, name));
     }
 
     public void deleteSyntheticPasswordState(int userId, long handle, String name) {
-        String path = getSynthenticPasswordStateFilePathForUser(userId, handle, name);
-        File file = new File(path);
-        if (file.exists()) {
-            try (RandomAccessFile raf = new RandomAccessFile(path, "rws")) {
-                final int fileSize = (int) raf.length();
-                raf.write(new byte[fileSize]);
-            } catch (Exception e) {
-                Slog.w(TAG, "Failed to zeroize " + path, e);
-            } finally {
-                file.delete();
-                dispatchChange(this);
-            }
-            mCache.putFile(path, null);
-        }
+        deleteFile(getSyntheticPasswordStateFileForUser(userId, handle, name));
     }
 
     public Map<Integer, List<Long>> listSyntheticPasswordHandlesForAllUsers(String stateName) {
@@ -471,7 +424,7 @@
 
     @VisibleForTesting
     protected File getSyntheticPasswordDirectoryForUser(int userId) {
-        return new File(Environment.getDataSystemDeDirectory(userId) ,SYNTHETIC_PASSWORD_DIRECTORY);
+        return new File(Environment.getDataSystemDeDirectory(userId), SYNTHETIC_PASSWORD_DIRECTORY);
     }
 
     /** Ensure per-user directory for synthetic password state exists */
@@ -482,12 +435,9 @@
         }
     }
 
-    @VisibleForTesting
-    protected String getSynthenticPasswordStateFilePathForUser(int userId, long handle,
-            String name) {
-        final File baseDir = getSyntheticPasswordDirectoryForUser(userId);
-        final String baseName = formatSimple("%016x.%s", handle, name);
-        return new File(baseDir, baseName).getAbsolutePath();
+    private File getSyntheticPasswordStateFileForUser(int userId, long handle, String name) {
+        String fileName = formatSimple("%016x.%s", handle, name);
+        return new File(getSyntheticPasswordDirectoryForUser(userId), fileName);
     }
 
     public void removeUser(int userId) {
@@ -513,11 +463,10 @@
             // The directory itself will be deleted as part of user deletion operation by the
             // framework, so only need to purge cache here.
             //TODO: (b/34600579) invoke secdiscardable
-            mCache.purgePath(spStateDir.getAbsolutePath());
+            mCache.purgePath(spStateDir);
         } finally {
             db.endTransaction();
         }
-        dispatchChange(this);
     }
 
     public void setBoolean(String key, boolean value, int userId) {
@@ -596,7 +545,6 @@
         }
         persistentDataBlock.setFrpCredentialHandle(PersistentData.toBytes(
                 persistentType, userId, qualityForUi, payload));
-        dispatchChange(this);
     }
 
     public PersistentData readPersistentDataBlock() {
@@ -694,7 +642,7 @@
         final UserManager um = UserManager.get(mContext);
         for (UserInfo user : um.getUsers()) {
             File userPath = getSyntheticPasswordDirectoryForUser(user.id);
-            pw.println(String.format("User %d [%s]:", user.id, userPath.getAbsolutePath()));
+            pw.println(String.format("User %d [%s]:", user.id, userPath));
             pw.increaseIndent();
             File[] files = userPath.listFiles();
             if (files != null) {
@@ -762,19 +710,24 @@
         }
     }
 
-    /**
-     * Cache consistency model:
-     * - Writes to storage write directly to the cache, but this MUST happen within the atomic
-     *   section either provided by the database transaction or mWriteLock, such that writes to the
-     *   cache and writes to the backing storage are guaranteed to occur in the same order
+    /*
+     * A cache for the following types of data:
      *
-     * - Reads can populate the cache, but because they are no strong ordering guarantees with
-     *   respect to writes this precaution is taken:
-     *   - The cache is assigned a version number that increases every time the cache is modified.
-     *     Reads from backing storage can only populate the cache if the backing storage
-     *     has not changed since the load operation has begun.
-     *     This guarantees that no read operation can shadow a write to the cache that happens
-     *     after it had begun.
+     *  - Key-value entries from the locksettings database, where the key is the combination of a
+     *    userId and a string key, and the value is a string.
+     *  - File paths to file contents.
+     *  - The per-user "prefetched" flag.
+     *
+     * Cache consistency model:
+     *  - Writes to storage write directly to the cache, but this MUST happen within an atomic
+     *    section either provided by the database transaction or mFileWriteLock, such that writes to
+     *    the cache and writes to the backing storage are guaranteed to occur in the same order.
+     *  - Reads can populate the cache, but because there are no strong ordering guarantees with
+     *    respect to writes the following precaution is taken: The cache is assigned a version
+     *    number that increases every time the backing storage is modified. Reads from backing
+     *    storage can only populate the cache if the backing storage has not changed since the load
+     *    operation has begun. This guarantees that a read operation can't clobber a different value
+     *    that was written to the cache by a concurrent write operation.
      */
     private static class Cache {
         private final ArrayMap<CacheKey, Object> mCache = new ArrayMap<>();
@@ -802,24 +755,25 @@
             remove(CacheKey.TYPE_KEY_VALUE, key, userId);
         }
 
-        byte[] peekFile(String fileName) {
-            return copyOf((byte[]) peek(CacheKey.TYPE_FILE, fileName, -1 /* userId */));
+        byte[] peekFile(File path) {
+            return copyOf((byte[]) peek(CacheKey.TYPE_FILE, path.toString(), -1 /* userId */));
         }
 
-        boolean hasFile(String fileName) {
-            return contains(CacheKey.TYPE_FILE, fileName, -1 /* userId */);
+        boolean hasFile(File path) {
+            return contains(CacheKey.TYPE_FILE, path.toString(), -1 /* userId */);
         }
 
-        void putFile(String key, byte[] value) {
-            put(CacheKey.TYPE_FILE, key, copyOf(value), -1 /* userId */);
+        void putFile(File path, byte[] data) {
+            put(CacheKey.TYPE_FILE, path.toString(), copyOf(data), -1 /* userId */);
         }
 
-        void putFileIfUnchanged(String key, byte[] value, int version) {
-            putIfUnchanged(CacheKey.TYPE_FILE, key, copyOf(value), -1 /* userId */, version);
+        void putFileIfUnchanged(File path, byte[] data, int version) {
+            putIfUnchanged(CacheKey.TYPE_FILE, path.toString(), copyOf(data), -1 /* userId */,
+                    version);
         }
 
         void setFetched(int userId) {
-            put(CacheKey.TYPE_FETCHED, "isFetched", "true", userId);
+            put(CacheKey.TYPE_FETCHED, "", "true", userId);
         }
 
         boolean isFetched(int userId) {
@@ -828,10 +782,11 @@
 
         private synchronized void remove(int type, String key, int userId) {
             mCache.remove(mCacheKey.set(type, key, userId));
+            mVersion++;
         }
 
         private synchronized void put(int type, String key, Object value, int userId) {
-            // Create a new CachKey here because it may be saved in the map if the key is absent.
+            // Create a new CacheKey here because it may be saved in the map if the key is absent.
             mCache.put(new CacheKey().set(type, key, userId), value);
             mVersion++;
         }
@@ -839,7 +794,9 @@
         private synchronized void putIfUnchanged(int type, String key, Object value, int userId,
                 int version) {
             if (!contains(type, key, userId) && mVersion == version) {
-                put(type, key, value, userId);
+                mCache.put(new CacheKey().set(type, key, userId), value);
+                // Don't increment mVersion, as this method should only be called in cases where the
+                // backing storage isn't being modified.
             }
         }
 
@@ -870,10 +827,11 @@
             return data != null ? Arrays.copyOf(data, data.length) : null;
         }
 
-        synchronized void purgePath(String path) {
+        synchronized void purgePath(File path) {
+            final String pathStr = path.toString();
             for (int i = mCache.size() - 1; i >= 0; i--) {
                 CacheKey entry = mCache.keyAt(i);
-                if (entry.type == CacheKey.TYPE_FILE && entry.key.startsWith(path)) {
+                if (entry.type == CacheKey.TYPE_FILE && entry.key.startsWith(pathStr)) {
                     mCache.removeAt(i);
                 }
             }
diff --git a/services/core/java/com/android/server/locksettings/ResumeOnRebootServiceProvider.java b/services/core/java/com/android/server/locksettings/ResumeOnRebootServiceProvider.java
index ec80521..70fdccd 100644
--- a/services/core/java/com/android/server/locksettings/ResumeOnRebootServiceProvider.java
+++ b/services/core/java/com/android/server/locksettings/ResumeOnRebootServiceProvider.java
@@ -182,7 +182,7 @@
             waitForLatch(binderLatch, "wrapSecret", timeOutInMillis);
             if (resultCallback.getResult().containsKey(ResumeOnRebootService.EXCEPTION_KEY)) {
                 throwTypedException(resultCallback.getResult().getParcelable(
-                        ResumeOnRebootService.EXCEPTION_KEY));
+                        ResumeOnRebootService.EXCEPTION_KEY, android.os.ParcelableException.class));
             }
             return resultCallback.mResult.getByteArray(ResumeOnRebootService.WRAPPED_BLOB_KEY);
         }
@@ -202,7 +202,7 @@
             waitForLatch(binderLatch, "unWrapSecret", timeOut);
             if (resultCallback.getResult().containsKey(ResumeOnRebootService.EXCEPTION_KEY)) {
                 throwTypedException(resultCallback.getResult().getParcelable(
-                        ResumeOnRebootService.EXCEPTION_KEY));
+                        ResumeOnRebootService.EXCEPTION_KEY, android.os.ParcelableException.class));
             }
             return resultCallback.getResult().getByteArray(
                     ResumeOnRebootService.UNWRAPPED_BLOB_KEY);
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
index 2cb89b3..ec0d985 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
@@ -122,7 +122,7 @@
      * @param recoverableKeyStoreDb Database where the keys are stored.
      * @param userId The uid of the user whose profile has been unlocked.
      * @param credentialType The type of credential as defined in {@code LockPatternUtils}
-     * @param credential The credential, encoded as a {@link String}.
+     * @param credential The credential, encoded as a byte array
      * @param credentialUpdated signals weather credentials were updated.
      * @param platformKeyManager platform key manager
      * @param testOnlyInsecureCertificateHelper utility class used for end-to-end tests
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
index b49bced..e620c80 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
@@ -900,14 +900,13 @@
     /**
      * This function can only be used inside LockSettingsService.
      *
-     * @param storedHashType from {@code CredentialHash}
-     * @param credential - unencrypted byte array. Password length should be at most 16 symbols
-     *     {@code mPasswordMaxLength}
-     * @param userId for user who just unlocked the device.
+     * @param credentialType the type of credential, as defined in {@code LockPatternUtils}
+     * @param credential the credential, encoded as a byte array
+     * @param userId the ID of the user to whom the credential belongs
      * @hide
      */
     public void lockScreenSecretAvailable(
-            int storedHashType, @NonNull byte[] credential, int userId) {
+            int credentialType, @NonNull byte[] credential, int userId) {
         // So as not to block the critical path unlocking the phone, defer to another thread.
         try {
             mExecutorService.schedule(KeySyncTask.newInstance(
@@ -916,7 +915,7 @@
                     mSnapshotStorage,
                     mListenersStorage,
                     userId,
-                    storedHashType,
+                    credentialType,
                     credential,
                     /*credentialUpdated=*/ false),
                     SYNC_DELAY_MILLIS,
@@ -934,13 +933,13 @@
     /**
      * This function can only be used inside LockSettingsService.
      *
-     * @param storedHashType from {@code CredentialHash}
-     * @param credential - unencrypted byte array
-     * @param userId for the user whose lock screen credentials were changed.
+     * @param credentialType the type of the new credential, as defined in {@code LockPatternUtils}
+     * @param credential the new credential, encoded as a byte array
+     * @param userId the ID of the user whose credential was changed
      * @hide
      */
     public void lockScreenSecretChanged(
-            int storedHashType,
+            int credentialType,
             @Nullable byte[] credential,
             int userId) {
         // So as not to block the critical path unlocking the phone, defer to another thread.
@@ -951,7 +950,7 @@
                     mSnapshotStorage,
                     mListenersStorage,
                     userId,
-                    storedHashType,
+                    credentialType,
                     credential,
                     /*credentialUpdated=*/ true),
                     SYNC_DELAY_MILLIS,
diff --git a/services/core/java/com/android/server/media/BluetoothRouteProvider.java b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
index d4d3a39..e1a990d 100644
--- a/services/core/java/com/android/server/media/BluetoothRouteProvider.java
+++ b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
@@ -500,7 +500,7 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
-            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, android.bluetooth.BluetoothDevice.class);
 
             BluetoothEventReceiver receiver = mEventReceiverMap.get(action);
             if (receiver != null) {
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index e61f553..82dfd3a 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -956,7 +956,7 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             if (intent.getAction().equals(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED)) {
-                BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+                BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, android.bluetooth.BluetoothDevice.class);
                 synchronized (mLock) {
                     mActiveBluetoothDevice = btDevice;
                     mGlobalBluetoothA2dpOn = btDevice != null;
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 1ea949e..99a488c 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1299,7 +1299,7 @@
             // on background handler thread, and verified MANAGE_NETWORK_POLICY
             // permission above.
 
-            final NetworkTemplate template = intent.getParcelableExtra(EXTRA_NETWORK_TEMPLATE);
+            final NetworkTemplate template = intent.getParcelableExtra(EXTRA_NETWORK_TEMPLATE, android.net.NetworkTemplate.class);
             if (ACTION_SNOOZE_WARNING.equals(intent.getAction())) {
                 performSnooze(template, TYPE_WARNING);
             } else if (ACTION_SNOOZE_RAPID.equals(intent.getAction())) {
@@ -4035,6 +4035,14 @@
                 }
                 fout.decreaseIndent();
 
+                fout.println("Network to interfaces:");
+                fout.increaseIndent();
+                for (int i = 0; i < mNetworkToIfaces.size(); ++i) {
+                    final int key = mNetworkToIfaces.keyAt(i);
+                    fout.println(key + ": " + mNetworkToIfaces.get(key));
+                }
+                fout.decreaseIndent();
+
                 fout.println();
                 mStatLogger.dump(fout);
 
diff --git a/services/core/java/com/android/server/notification/CountdownConditionProvider.java b/services/core/java/com/android/server/notification/CountdownConditionProvider.java
index 4b70e2e..efca598 100644
--- a/services/core/java/com/android/server/notification/CountdownConditionProvider.java
+++ b/services/core/java/com/android/server/notification/CountdownConditionProvider.java
@@ -155,7 +155,7 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             if (ACTION.equals(intent.getAction())) {
-                final Uri conditionId = intent.getParcelableExtra(EXTRA_CONDITION_ID);
+                final Uri conditionId = intent.getParcelableExtra(EXTRA_CONDITION_ID, android.net.Uri.class);
                 final boolean alarm = ZenModeConfig.isValidCountdownToAlarmConditionId(conditionId);
                 final long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
                 if (DEBUG) Slog.d(TAG, "Countdown condition fired: " + conditionId);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index d3580a4..172cf29 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1795,6 +1795,7 @@
                 if (userHandle >= 0) {
                     cancelAllNotificationsInt(MY_UID, MY_PID, null, null, 0, 0, true, userHandle,
                             REASON_PROFILE_TURNED_OFF, null);
+                    mSnoozeHelper.clearData(userHandle);
                 }
             } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
                 // turn off LED when user passes through lock screen
@@ -2459,11 +2460,11 @@
         SnoozeHelper snoozeHelper = new SnoozeHelper(getContext(), (userId, r, muteOnReturn) -> {
             try {
                 if (DBG) {
-                    Slog.d(TAG, "Reposting " + r.getKey());
+                    Slog.d(TAG, "Reposting " + r.getKey() + " " + muteOnReturn);
                 }
                 enqueueNotificationInternal(r.getSbn().getPackageName(), r.getSbn().getOpPkg(),
                         r.getSbn().getUid(), r.getSbn().getInitialPid(), r.getSbn().getTag(),
-                        r.getSbn().getId(),  r.getSbn().getNotification(), userId, true);
+                        r.getSbn().getId(),  r.getSbn().getNotification(), userId, muteOnReturn);
             } catch (Exception e) {
                 Slog.e(TAG, "Cannot un-snooze notification", e);
             }
@@ -3386,11 +3387,9 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_TOAST_RATE_LIMITING)
         @Override
         public void setToastRateLimitingEnabled(boolean enable) {
-            getContext().enforceCallingPermission(
-                    android.Manifest.permission.MANAGE_TOAST_RATE_LIMITING,
-                    "App doesn't have the permission to enable/disable toast rate limiting");
 
             synchronized (mToastQueue) {
                 int uid = Binder.getCallingUid();
@@ -7031,6 +7030,7 @@
 
         @GuardedBy("mNotificationLock")
         void snoozeLocked(NotificationRecord r) {
+            final List<NotificationRecord> recordsToSnooze = new ArrayList<>();
             if (r.getSbn().isGroup()) {
                 final List<NotificationRecord> groupNotifications =
                         findCurrentAndSnoozedGroupNotificationsLocked(
@@ -7039,8 +7039,8 @@
                 if (r.getNotification().isGroupSummary()) {
                     // snooze all children
                     for (int i = 0; i < groupNotifications.size(); i++) {
-                        if (mKey != groupNotifications.get(i).getKey()) {
-                            snoozeNotificationLocked(groupNotifications.get(i));
+                        if (!mKey.equals(groupNotifications.get(i).getKey())) {
+                            recordsToSnooze.add(groupNotifications.get(i));
                         }
                     }
                 } else {
@@ -7050,8 +7050,8 @@
                         if (groupNotifications.size() == 2) {
                             // snooze summary and the one child
                             for (int i = 0; i < groupNotifications.size(); i++) {
-                                if (mKey != groupNotifications.get(i).getKey()) {
-                                    snoozeNotificationLocked(groupNotifications.get(i));
+                                if (!mKey.equals(groupNotifications.get(i).getKey())) {
+                                    recordsToSnooze.add(groupNotifications.get(i));
                                 }
                             }
                         }
@@ -7059,7 +7059,15 @@
                 }
             }
             // snooze the notification
-            snoozeNotificationLocked(r);
+            recordsToSnooze.add(r);
+
+            if (mSnoozeHelper.canSnooze(recordsToSnooze.size())) {
+                for (int i = 0; i < recordsToSnooze.size(); i++) {
+                    snoozeNotificationLocked(recordsToSnooze.get(i));
+                }
+            } else {
+                Log.w(TAG, "Cannot snooze " + r.getKey() + ": too many snoozed notifications");
+            }
 
         }
 
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index cbaf485..6dd0daa 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -682,7 +682,7 @@
                 if (signals.containsKey(Adjustment.KEY_SNOOZE_CRITERIA)) {
                     final ArrayList<SnoozeCriterion> snoozeCriterionList =
                             adjustment.getSignals().getParcelableArrayList(
-                                    Adjustment.KEY_SNOOZE_CRITERIA);
+                                    Adjustment.KEY_SNOOZE_CRITERIA, android.service.notification.SnoozeCriterion.class);
                     setSnoozeCriteria(snoozeCriterionList);
                     EventLogTags.writeNotificationAdjusted(getKey(), Adjustment.KEY_SNOOZE_CRITERIA,
                             snoozeCriterionList.toString());
@@ -708,7 +708,7 @@
                 }
                 if (signals.containsKey(Adjustment.KEY_CONTEXTUAL_ACTIONS)) {
                     setSystemGeneratedSmartActions(
-                            signals.getParcelableArrayList(Adjustment.KEY_CONTEXTUAL_ACTIONS));
+                            signals.getParcelableArrayList(Adjustment.KEY_CONTEXTUAL_ACTIONS, android.app.Notification.Action.class));
                     EventLogTags.writeNotificationAdjusted(getKey(),
                             Adjustment.KEY_CONTEXTUAL_ACTIONS,
                             getSystemGeneratedSmartActions().toString());
diff --git a/services/core/java/com/android/server/notification/NotificationRecordLogger.java b/services/core/java/com/android/server/notification/NotificationRecordLogger.java
index 9a89efa..2789bcf 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordLogger.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordLogger.java
@@ -399,7 +399,7 @@
         private int getNumPeople(@Nullable Bundle extras) {
             if (extras != null) {
                 ArrayList<Person> people = extras.getParcelableArrayList(
-                        Notification.EXTRA_PEOPLE_LIST);
+                        Notification.EXTRA_PEOPLE_LIST, android.app.Person.class);
                 if (people != null && !people.isEmpty()) {
                     return people.size();
                 }
diff --git a/services/core/java/com/android/server/notification/PermissionHelper.java b/services/core/java/com/android/server/notification/PermissionHelper.java
index 09ed567..12324bf 100644
--- a/services/core/java/com/android/server/notification/PermissionHelper.java
+++ b/services/core/java/com/android/server/notification/PermissionHelper.java
@@ -16,6 +16,8 @@
 
 package com.android.server.notification;
 
+import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
 import static android.content.pm.PackageManager.GET_PERMISSIONS;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -175,12 +177,14 @@
                 mPermManager.revokeRuntimePermission(packageName, NOTIFICATION_PERMISSION,
                         userId, TAG);
             }
+            int flagMask = FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED;
+            flagMask = userSet || !grant ? flagMask | FLAG_PERMISSION_GRANTED_BY_DEFAULT : flagMask;
             if (userSet) {
                 mPermManager.updatePermissionFlags(packageName, NOTIFICATION_PERMISSION,
-                        FLAG_PERMISSION_USER_SET, FLAG_PERMISSION_USER_SET, true, userId);
+                        flagMask, FLAG_PERMISSION_USER_SET, true, userId);
             } else {
                 mPermManager.updatePermissionFlags(packageName, NOTIFICATION_PERMISSION,
-                        0, FLAG_PERMISSION_USER_SET, true, userId);
+                        flagMask, 0, true, userId);
             }
         } catch (RemoteException e) {
             Slog.e(TAG, "Could not reach system server", e);
diff --git a/services/core/java/com/android/server/notification/SnoozeHelper.java b/services/core/java/com/android/server/notification/SnoozeHelper.java
index 7f265df..61936df 100644
--- a/services/core/java/com/android/server/notification/SnoozeHelper.java
+++ b/services/core/java/com/android/server/notification/SnoozeHelper.java
@@ -16,7 +16,6 @@
 package com.android.server.notification;
 
 import android.annotation.NonNull;
-import android.annotation.UserIdInt;
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
@@ -25,7 +24,6 @@
 import android.content.IntentFilter;
 import android.net.Uri;
 import android.os.Binder;
-import android.os.SystemClock;
 import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
 import android.util.ArrayMap;
@@ -38,18 +36,15 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
-import com.android.internal.util.XmlUtils;
 import com.android.server.pm.PackageManagerService;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -59,15 +54,15 @@
 /**
  * NotificationManagerService helper for handling snoozed notifications.
  */
-public class SnoozeHelper {
+public final class SnoozeHelper {
     public static final int XML_SNOOZED_NOTIFICATION_VERSION = 1;
 
+    static final int CONCURRENT_SNOOZE_LIMIT = 500;
+
     protected static final String XML_TAG_NAME = "snoozed-notifications";
 
     private static final String XML_SNOOZED_NOTIFICATION = "notification";
     private static final String XML_SNOOZED_NOTIFICATION_CONTEXT = "context";
-    private static final String XML_SNOOZED_NOTIFICATION_PKG = "pkg";
-    private static final String XML_SNOOZED_NOTIFICATION_USER_ID = "user-id";
     private static final String XML_SNOOZED_NOTIFICATION_KEY = "key";
     //the time the snoozed notification should be reposted
     private static final String XML_SNOOZED_NOTIFICATION_TIME = "time";
@@ -89,24 +84,19 @@
     private AlarmManager mAm;
     private final ManagedServices.UserProfiles mUserProfiles;
 
-    // User id | package name : notification key : record.
-    private ArrayMap<String, ArrayMap<String, NotificationRecord>>
-            mSnoozedNotifications = new ArrayMap<>();
-    // User id | package name : notification key : time-milliseconds .
+    // notification key : record.
+    private ArrayMap<String, NotificationRecord> mSnoozedNotifications = new ArrayMap<>();
+    // notification key : time-milliseconds .
     // This member stores persisted snoozed notification trigger times. it persists through reboots
     // It should have the notifications that haven't expired or re-posted yet
-    private final ArrayMap<String, ArrayMap<String, Long>>
-            mPersistedSnoozedNotifications = new ArrayMap<>();
-    // User id | package name : notification key : creation ID .
+    private final ArrayMap<String, Long> mPersistedSnoozedNotifications = new ArrayMap<>();
+    // notification key : creation ID.
     // This member stores persisted snoozed notification trigger context for the assistant
     // it persists through reboots.
     // It should have the notifications that haven't expired or re-posted yet
-    private final ArrayMap<String, ArrayMap<String, String>>
+    private final ArrayMap<String, String>
             mPersistedSnoozedNotificationsWithContext = new ArrayMap<>();
-    // notification key : package.
-    private ArrayMap<String, String> mPackages = new ArrayMap<>();
-    // key : userId
-    private ArrayMap<String, Integer> mUsers = new ArrayMap<>();
+
     private Callback mCallback;
 
     private final Object mLock = new Object();
@@ -123,27 +113,20 @@
         mUserProfiles = userProfiles;
     }
 
-    private String getPkgKey(@UserIdInt int userId, String pkg) {
-        return userId + "|" + pkg;
-    }
-
-    void cleanupPersistedContext(String key){
+    protected boolean canSnooze(int numberToSnooze) {
         synchronized (mLock) {
-            int userId = mUsers.get(key);
-            String pkg = mPackages.get(key);
-            removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotificationsWithContext);
+            if ((mSnoozedNotifications.size() + numberToSnooze) > CONCURRENT_SNOOZE_LIMIT) {
+                return false;
+            }
         }
+        return true;
     }
 
     @NonNull
     protected Long getSnoozeTimeForUnpostedNotification(int userId, String pkg, String key) {
         Long time = null;
         synchronized (mLock) {
-           ArrayMap<String, Long> snoozed =
-                   mPersistedSnoozedNotifications.get(getPkgKey(userId, pkg));
-           if (snoozed != null) {
-               time = snoozed.get(key);
-           }
+            time = mPersistedSnoozedNotifications.get(key);
         }
         if (time == null) {
             time = 0L;
@@ -153,29 +136,26 @@
 
     protected String getSnoozeContextForUnpostedNotification(int userId, String pkg, String key) {
         synchronized (mLock) {
-            ArrayMap<String, String> snoozed =
-                    mPersistedSnoozedNotificationsWithContext.get(getPkgKey(userId, pkg));
-            if (snoozed != null) {
-                return snoozed.get(key);
-            }
+            return mPersistedSnoozedNotificationsWithContext.get(key);
         }
-        return null;
     }
 
     protected boolean isSnoozed(int userId, String pkg, String key) {
         synchronized (mLock) {
-            return mSnoozedNotifications.containsKey(getPkgKey(userId, pkg))
-                    && mSnoozedNotifications.get(getPkgKey(userId, pkg)).containsKey(key);
+            return mSnoozedNotifications.containsKey(key);
         }
     }
 
     protected Collection<NotificationRecord> getSnoozed(int userId, String pkg) {
         synchronized (mLock) {
-            if (mSnoozedNotifications.containsKey(getPkgKey(userId, pkg))) {
-                return mSnoozedNotifications.get(getPkgKey(userId, pkg)).values();
+            ArrayList snoozed = new ArrayList();
+            for (NotificationRecord r : mSnoozedNotifications.values()) {
+                if (r.getUserId() == userId && r.getSbn().getPackageName().equals(pkg)) {
+                    snoozed.add(r);
+                }
             }
+            return snoozed;
         }
-        return Collections.EMPTY_LIST;
     }
 
     @NonNull
@@ -183,15 +163,11 @@
             String groupKey, Integer userId) {
         ArrayList<NotificationRecord> records =  new ArrayList<>();
         synchronized (mLock) {
-            ArrayMap<String, NotificationRecord> allRecords =
-                    mSnoozedNotifications.get(getPkgKey(userId, pkg));
-            if (allRecords != null) {
-                for (int i = 0; i < allRecords.size(); i++) {
-                    NotificationRecord r = allRecords.valueAt(i);
-                    String currentGroupKey = r.getSbn().getGroup();
-                    if (Objects.equals(currentGroupKey, groupKey)) {
-                        records.add(r);
-                    }
+            for (int i = 0; i < mSnoozedNotifications.size(); i++) {
+                NotificationRecord r = mSnoozedNotifications.valueAt(i);
+                if (r.getSbn().getPackageName().equals(pkg) && r.getUserId() == userId
+                        && Objects.equals(r.getSbn().getGroup(), groupKey)) {
+                    records.add(r);
                 }
             }
         }
@@ -200,31 +176,16 @@
 
     protected NotificationRecord getNotification(String key) {
         synchronized (mLock) {
-            if (!mUsers.containsKey(key) || !mPackages.containsKey(key)) {
-                Slog.w(TAG, "Snoozed data sets no longer agree for " + key);
-                return null;
-            }
-            int userId = mUsers.get(key);
-            String pkg = mPackages.get(key);
-            ArrayMap<String, NotificationRecord> snoozed =
-                    mSnoozedNotifications.get(getPkgKey(userId, pkg));
-            if (snoozed == null) {
-                return null;
-            }
-            return snoozed.get(key);
+            return mSnoozedNotifications.get(key);
         }
     }
 
     protected @NonNull List<NotificationRecord> getSnoozed() {
         synchronized (mLock) {
-            // caller filters records based on the current user profiles and listener access, so just
-            // return everything
+            // caller filters records based on the current user profiles and listener access,
+            // so just return everything
             List<NotificationRecord> snoozed = new ArrayList<>();
-            for (String userPkgKey : mSnoozedNotifications.keySet()) {
-                ArrayMap<String, NotificationRecord> snoozedRecords =
-                        mSnoozedNotifications.get(userPkgKey);
-                snoozed.addAll(snoozedRecords.values());
-            }
+            snoozed.addAll(mSnoozedNotifications.values());
             return snoozed;
         }
     }
@@ -233,15 +194,13 @@
      * Snoozes a notification and schedules an alarm to repost at that time.
      */
     protected void snooze(NotificationRecord record, long duration) {
-        String pkg = record.getSbn().getPackageName();
         String key = record.getKey();
-        int userId = record.getUser().getIdentifier();
 
         snooze(record);
-        scheduleRepost(pkg, key, userId, duration);
+        scheduleRepost(key, duration);
         Long activateAt = System.currentTimeMillis() + duration;
         synchronized (mLock) {
-            storeRecordLocked(pkg, key, userId, mPersistedSnoozedNotifications, activateAt);
+            mPersistedSnoozedNotifications.put(key, activateAt);
         }
     }
 
@@ -249,66 +208,33 @@
      * Records a snoozed notification.
      */
     protected void snooze(NotificationRecord record, String contextId) {
-        int userId = record.getUser().getIdentifier();
         if (contextId != null) {
             synchronized (mLock) {
-                storeRecordLocked(record.getSbn().getPackageName(), record.getKey(),
-                        userId, mPersistedSnoozedNotificationsWithContext, contextId);
+                mPersistedSnoozedNotificationsWithContext.put(record.getKey(), contextId);
             }
         }
         snooze(record);
     }
 
     private void snooze(NotificationRecord record) {
-        int userId = record.getUser().getIdentifier();
         if (DEBUG) {
             Slog.d(TAG, "Snoozing " + record.getKey());
         }
         synchronized (mLock) {
-            storeRecordLocked(record.getSbn().getPackageName(), record.getKey(),
-                    userId, mSnoozedNotifications, record);
+            mSnoozedNotifications.put(record.getKey(), record);
         }
     }
 
-    private <T> void storeRecordLocked(String pkg, String key, Integer userId,
-            ArrayMap<String, ArrayMap<String, T>> targets, T object) {
-
-        mPackages.put(key, pkg);
-        mUsers.put(key, userId);
-        ArrayMap<String, T> keyToValue = targets.get(getPkgKey(userId, pkg));
-        if (keyToValue == null) {
-            keyToValue = new ArrayMap<>();
-        }
-        keyToValue.put(key, object);
-        targets.put(getPkgKey(userId, pkg), keyToValue);
-    }
-
-    private <T> T removeRecordLocked(String pkg, String key, Integer userId,
-            ArrayMap<String, ArrayMap<String, T>> targets) {
-        T object = null;
-        ArrayMap<String, T> keyToValue = targets.get(getPkgKey(userId, pkg));
-        if (keyToValue == null) {
-            return null;
-        }
-        object = keyToValue.remove(key);
-        if (keyToValue.size() == 0) {
-            targets.remove(getPkgKey(userId, pkg));
-        }
-        return object;
-    }
-
     protected boolean cancel(int userId, String pkg, String tag, int id) {
         synchronized (mLock) {
-            ArrayMap<String, NotificationRecord> recordsForPkg =
-                    mSnoozedNotifications.get(getPkgKey(userId, pkg));
-            if (recordsForPkg != null) {
-                final Set<Map.Entry<String, NotificationRecord>> records = recordsForPkg.entrySet();
-                for (Map.Entry<String, NotificationRecord> record : records) {
-                    final StatusBarNotification sbn = record.getValue().getSbn();
-                    if (Objects.equals(sbn.getTag(), tag) && sbn.getId() == id) {
-                        record.getValue().isCanceled = true;
-                        return true;
-                    }
+            final Set<Map.Entry<String, NotificationRecord>> records =
+                    mSnoozedNotifications.entrySet();
+            for (Map.Entry<String, NotificationRecord> record : records) {
+                final StatusBarNotification sbn = record.getValue().getSbn();
+                if (sbn.getPackageName().equals(pkg) && sbn.getUserId() == userId
+                        && Objects.equals(sbn.getTag(), tag) && sbn.getId() == id) {
+                    record.getValue().isCanceled = true;
+                    return true;
                 }
             }
         }
@@ -325,11 +251,9 @@
             if (includeCurrentProfiles) {
                 userIds = mUserProfiles.getCurrentProfileIds();
             }
-            for (ArrayMap<String, NotificationRecord> snoozedRecords : mSnoozedNotifications.values()) {
-                for (NotificationRecord r : snoozedRecords.values()) {
-                    if (userIds.binarySearch(r.getUserId()) >= 0) {
-                        r.isCanceled = true;
-                    }
+            for (NotificationRecord r : mSnoozedNotifications.values()) {
+                if (userIds.binarySearch(r.getUserId()) >= 0) {
+                    r.isCanceled = true;
                 }
             }
         }
@@ -337,14 +261,12 @@
 
     protected boolean cancel(int userId, String pkg) {
         synchronized (mLock) {
-            ArrayMap<String, NotificationRecord> records =
-                    mSnoozedNotifications.get(getPkgKey(userId, pkg));
-            if (records == null) {
-                return false;
-            }
-            int N = records.size();
-            for (int i = 0; i < N; i++) {
-                records.valueAt(i).isCanceled = true;
+            int n = mSnoozedNotifications.size();
+            for (int i = 0; i < n; i++) {
+                final NotificationRecord r = mSnoozedNotifications.valueAt(i);
+                if (r.getSbn().getPackageName().equals(pkg) && r.getUserId() == userId) {
+                    r.isCanceled = true;
+                }
             }
             return true;
         }
@@ -355,20 +277,17 @@
      */
     protected void update(int userId, NotificationRecord record) {
         synchronized (mLock) {
-            ArrayMap<String, NotificationRecord> records =
-                    mSnoozedNotifications.get(getPkgKey(userId, record.getSbn().getPackageName()));
-            if (records == null) {
-                return;
+            if (mSnoozedNotifications.containsKey(record.getKey())) {
+                mSnoozedNotifications.put(record.getKey(), record);
             }
-            records.put(record.getKey(), record);
         }
     }
 
     protected void repost(String key, boolean muteOnReturn) {
         synchronized (mLock) {
-            Integer userId = mUsers.get(key);
-            if (userId != null) {
-                repost(key, userId, muteOnReturn);
+            final NotificationRecord r = mSnoozedNotifications.get(key);
+            if (r != null) {
+                repost(key, r.getUserId(), muteOnReturn);
             }
         }
     }
@@ -376,43 +295,30 @@
     protected void repost(String key, int userId, boolean muteOnReturn) {
         NotificationRecord record;
         synchronized (mLock) {
-            final String pkg = mPackages.remove(key);
-            mUsers.remove(key);
-            removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotifications);
-            removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotificationsWithContext);
-            ArrayMap<String, NotificationRecord> records =
-                    mSnoozedNotifications.get(getPkgKey(userId, pkg));
-            if (records == null) {
-                return;
-            }
-            record = records.remove(key);
-
+            mPersistedSnoozedNotifications.remove(key);
+            mPersistedSnoozedNotificationsWithContext.remove(key);
+            record = mSnoozedNotifications.remove(key);
         }
 
         if (record != null && !record.isCanceled) {
-            final PendingIntent pi = createPendingIntent(
-                    record.getSbn().getPackageName(), record.getKey(), userId);
+            final PendingIntent pi = createPendingIntent(record.getKey());
             mAm.cancel(pi);
             MetricsLogger.action(record.getLogMaker()
                     .setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
                     .setType(MetricsProto.MetricsEvent.TYPE_OPEN));
-            mCallback.repost(userId, record, muteOnReturn);
+            mCallback.repost(record.getUserId(), record, muteOnReturn);
         }
     }
 
     protected void repostGroupSummary(String pkg, int userId, String groupKey) {
         synchronized (mLock) {
-            ArrayMap<String, NotificationRecord> recordsByKey
-                    = mSnoozedNotifications.get(getPkgKey(userId, pkg));
-            if (recordsByKey == null) {
-                return;
-            }
-
             String groupSummaryKey = null;
-            int N = recordsByKey.size();
-            for (int i = 0; i < N; i++) {
-                final NotificationRecord potentialGroupSummary = recordsByKey.valueAt(i);
-                if (potentialGroupSummary.getSbn().isGroup()
+            int n = mSnoozedNotifications.size();
+            for (int i = 0; i < n; i++) {
+                final NotificationRecord potentialGroupSummary = mSnoozedNotifications.valueAt(i);
+                if (potentialGroupSummary.getSbn().getPackageName().equals(pkg)
+                        && potentialGroupSummary.getUserId() == userId
+                        && potentialGroupSummary.getSbn().isGroup()
                         && potentialGroupSummary.getNotification().isGroupSummary()
                         && groupKey.equals(potentialGroupSummary.getGroupKey())) {
                     groupSummaryKey = potentialGroupSummary.getKey();
@@ -421,16 +327,14 @@
             }
 
             if (groupSummaryKey != null) {
-                NotificationRecord record = recordsByKey.remove(groupSummaryKey);
-                mPackages.remove(groupSummaryKey);
-                mUsers.remove(groupSummaryKey);
+                NotificationRecord record = mSnoozedNotifications.remove(groupSummaryKey);
 
                 if (record != null && !record.isCanceled) {
                     Runnable runnable = () -> {
                         MetricsLogger.action(record.getLogMaker()
                                 .setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
                                 .setType(MetricsProto.MetricsEvent.TYPE_OPEN));
-                        mCallback.repost(userId, record, false);
+                        mCallback.repost(record.getUserId(), record, false);
                     };
                     runnable.run();
                 }
@@ -440,20 +344,17 @@
 
     protected void clearData(int userId, String pkg) {
         synchronized (mLock) {
-            ArrayMap<String, NotificationRecord> records =
-                    mSnoozedNotifications.get(getPkgKey(userId, pkg));
-            if (records == null) {
-                return;
-            }
-            for (int i = records.size() - 1; i >= 0; i--) {
-                final NotificationRecord r = records.removeAt(i);
-                if (r != null) {
-                    mPackages.remove(r.getKey());
-                    mUsers.remove(r.getKey());
+            int n = mSnoozedNotifications.size();
+            for (int i = n - 1; i >= 0; i--) {
+                final NotificationRecord record = mSnoozedNotifications.valueAt(i);
+                if (record.getUserId() == userId && record.getSbn().getPackageName().equals(pkg)) {
+                    mSnoozedNotifications.removeAt(i);
+                    mPersistedSnoozedNotificationsWithContext.remove(record.getKey());
+                    mPersistedSnoozedNotifications.remove(record.getKey());
                     Runnable runnable = () -> {
-                        final PendingIntent pi = createPendingIntent(pkg, r.getKey(), userId);
+                        final PendingIntent pi = createPendingIntent(record.getKey());
                         mAm.cancel(pi);
-                        MetricsLogger.action(r.getLogMaker()
+                        MetricsLogger.action(record.getLogMaker()
                                 .setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
                                 .setType(MetricsProto.MetricsEvent.TYPE_DISMISS));
                     };
@@ -463,47 +364,61 @@
         }
     }
 
-    private PendingIntent createPendingIntent(String pkg, String key, int userId) {
+    protected void clearData(int userId) {
+        synchronized (mLock) {
+            int n = mSnoozedNotifications.size();
+            for (int i = n - 1; i >= 0; i--) {
+                final NotificationRecord record = mSnoozedNotifications.valueAt(i);
+                if (record.getUserId() == userId) {
+                    mSnoozedNotifications.removeAt(i);
+                    mPersistedSnoozedNotificationsWithContext.remove(record.getKey());
+                    mPersistedSnoozedNotifications.remove(record.getKey());
+
+                    Runnable runnable = () -> {
+                        final PendingIntent pi = createPendingIntent(record.getKey());
+                        mAm.cancel(pi);
+                        MetricsLogger.action(record.getLogMaker()
+                                .setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
+                                .setType(MetricsProto.MetricsEvent.TYPE_DISMISS));
+                    };
+                    runnable.run();
+                }
+            }
+        }
+    }
+
+    private PendingIntent createPendingIntent(String key) {
         return PendingIntent.getBroadcast(mContext,
                 REQUEST_CODE_REPOST,
                 new Intent(REPOST_ACTION)
                         .setPackage(PackageManagerService.PLATFORM_PACKAGE_NAME)
                         .setData(new Uri.Builder().scheme(REPOST_SCHEME).appendPath(key).build())
                         .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
-                        .putExtra(EXTRA_KEY, key)
-                        .putExtra(EXTRA_USER_ID, userId),
+                        .putExtra(EXTRA_KEY, key),
                 PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
     }
 
     public void scheduleRepostsForPersistedNotifications(long currentTime) {
         synchronized (mLock) {
-            for (ArrayMap<String, Long> snoozed : mPersistedSnoozedNotifications.values()) {
-                for (int i = 0; i < snoozed.size(); i++) {
-                    String key = snoozed.keyAt(i);
-                    Long time = snoozed.valueAt(i);
-                    String pkg = mPackages.get(key);
-                    Integer userId = mUsers.get(key);
-                    if (time == null || pkg == null || userId == null) {
-                        Slog.w(TAG, "data out of sync: " + time + "|" + pkg + "|" + userId);
-                        continue;
-                    }
-                    if (time != null && time > currentTime) {
-                        scheduleRepostAtTime(pkg, key, userId, time);
-                    }
+            for (int i = 0; i < mPersistedSnoozedNotifications.size(); i++) {
+                String key = mPersistedSnoozedNotifications.keyAt(i);
+                Long time = mPersistedSnoozedNotifications.valueAt(i);
+                if (time != null && time > currentTime) {
+                    scheduleRepostAtTime(key, time);
                 }
             }
         }
     }
 
-    private void scheduleRepost(String pkg, String key, int userId, long duration) {
-        scheduleRepostAtTime(pkg, key, userId, System.currentTimeMillis() + duration);
+    private void scheduleRepost(String key, long duration) {
+        scheduleRepostAtTime(key, System.currentTimeMillis() + duration);
     }
 
-    private void scheduleRepostAtTime(String pkg, String key, int userId, long time) {
+    private void scheduleRepostAtTime(String key, long time) {
         Runnable runnable = () -> {
             final long identity = Binder.clearCallingIdentity();
             try {
-                final PendingIntent pi = createPendingIntent(pkg, key, userId);
+                final PendingIntent pi = createPendingIntent(key);
                 mAm.cancel(pi);
                 if (DEBUG) Slog.d(TAG, "Scheduling evaluate for " + new Date(time));
                 mAm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, pi);
@@ -517,37 +432,14 @@
     public void dump(PrintWriter pw, NotificationManagerService.DumpFilter filter) {
         synchronized (mLock) {
             pw.println("\n  Snoozed notifications:");
-            for (String userPkgKey : mSnoozedNotifications.keySet()) {
+            for (String key : mSnoozedNotifications.keySet()) {
                 pw.print(INDENT);
-                pw.println("key: " + userPkgKey);
-                ArrayMap<String, NotificationRecord> snoozedRecords =
-                        mSnoozedNotifications.get(userPkgKey);
-                Set<String> snoozedKeys = snoozedRecords.keySet();
-                for (String key : snoozedKeys) {
-                    pw.print(INDENT);
-                    pw.print(INDENT);
-                    pw.print(INDENT);
-                    pw.println(key);
-                }
+                pw.println("key: " + key);
             }
             pw.println("\n Pending snoozed notifications");
-            for (String userPkgKey : mPersistedSnoozedNotifications.keySet()) {
+            for (String key : mPersistedSnoozedNotifications.keySet()) {
                 pw.print(INDENT);
-                pw.println("key: " + userPkgKey);
-                ArrayMap<String, Long> snoozedRecords =
-                        mPersistedSnoozedNotifications.get(userPkgKey);
-                if (snoozedRecords == null) {
-                    continue;
-                }
-                Set<String> snoozedKeys = snoozedRecords.keySet();
-                for (String key : snoozedKeys) {
-                    pw.print(INDENT);
-                    pw.print(INDENT);
-                    pw.print(INDENT);
-                    pw.print(key);
-                    pw.print(INDENT);
-                    pw.println(snoozedRecords.get(key));
-                }
+                pw.println("key: " + key + " until: " + mPersistedSnoozedNotifications.get(key));
             }
         }
     }
@@ -578,37 +470,22 @@
         void insert(T t) throws IOException;
     }
 
-    private <T> void writeXml(TypedXmlSerializer out,
-            ArrayMap<String, ArrayMap<String, T>> targets, String tag,
-            Inserter<T> attributeInserter)
-            throws IOException {
-        final int M = targets.size();
-        for (int i = 0; i < M; i++) {
+    private <T> void writeXml(TypedXmlSerializer out, ArrayMap<String, T> targets, String tag,
+            Inserter<T> attributeInserter) throws IOException {
+        for (int j = 0; j < targets.size(); j++) {
+            String key = targets.keyAt(j);
             // T is a String (snoozed until context) or Long (snoozed until time)
-            ArrayMap<String, T> keyToValue = targets.valueAt(i);
-            for (int j = 0; j < keyToValue.size(); j++) {
-                String key = keyToValue.keyAt(j);
-                T value = keyToValue.valueAt(j);
-                String pkg = mPackages.get(key);
-                Integer userId = mUsers.get(key);
+            T value = targets.valueAt(j);
 
-                if (pkg == null || userId == null) {
-                    Slog.w(TAG, "pkg " + pkg + " or user " + userId + " missing for " + key);
-                    continue;
-                }
+            out.startTag(null, tag);
 
-                out.startTag(null, tag);
+            attributeInserter.insert(value);
 
-                attributeInserter.insert(value);
+            out.attributeInt(null, XML_SNOOZED_NOTIFICATION_VERSION_LABEL,
+                    XML_SNOOZED_NOTIFICATION_VERSION);
+            out.attribute(null, XML_SNOOZED_NOTIFICATION_KEY, key);
 
-                out.attributeInt(null, XML_SNOOZED_NOTIFICATION_VERSION_LABEL,
-                        XML_SNOOZED_NOTIFICATION_VERSION);
-                out.attribute(null, XML_SNOOZED_NOTIFICATION_KEY, key);
-                out.attribute(null, XML_SNOOZED_NOTIFICATION_PKG, pkg);
-                out.attributeInt(null, XML_SNOOZED_NOTIFICATION_USER_ID, userId);
-
-                out.endTag(null, tag);
-            }
+            out.endTag(null, tag);
         }
     }
 
@@ -628,16 +505,12 @@
                         == XML_SNOOZED_NOTIFICATION_VERSION) {
                 try {
                     final String key = parser.getAttributeValue(null, XML_SNOOZED_NOTIFICATION_KEY);
-                    final String pkg = parser.getAttributeValue(null, XML_SNOOZED_NOTIFICATION_PKG);
-                    final int userId = parser.getAttributeInt(
-                            null, XML_SNOOZED_NOTIFICATION_USER_ID, UserHandle.USER_ALL);
                     if (tag.equals(XML_SNOOZED_NOTIFICATION)) {
                         final Long time = parser.getAttributeLong(
                                 null, XML_SNOOZED_NOTIFICATION_TIME, 0);
                         if (time > currentTime) { //only read new stuff
                             synchronized (mLock) {
-                                storeRecordLocked(
-                                        pkg, key, userId, mPersistedSnoozedNotifications, time);
+                                mPersistedSnoozedNotifications.put(key, time);
                             }
                         }
                     }
@@ -645,9 +518,7 @@
                         final String creationId = parser.getAttributeValue(
                                 null, XML_SNOOZED_NOTIFICATION_CONTEXT_ID);
                         synchronized (mLock) {
-                            storeRecordLocked(
-                                    pkg, key, userId, mPersistedSnoozedNotificationsWithContext,
-                                    creationId);
+                            mPersistedSnoozedNotificationsWithContext.put(key, creationId);
                         }
                     }
                 } catch (Exception e) {
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 0ba8d2c..7159673 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -942,7 +942,7 @@
                         final FabricatedOverlayInternal fabricated =
                                 request.extras.getParcelable(
                                         OverlayManagerTransaction.Request.BUNDLE_FABRICATED_OVERLAY
-                                );
+                                , android.os.FabricatedOverlayInternal.class);
                         Objects.requireNonNull(fabricated,
                                 "no fabricated overlay attached to request");
                         return mImpl.registerFabricatedOverlay(fabricated);
diff --git a/services/core/java/com/android/server/pm/AppDataHelper.java b/services/core/java/com/android/server/pm/AppDataHelper.java
index 84c7c55..da8992a 100644
--- a/services/core/java/com/android/server/pm/AppDataHelper.java
+++ b/services/core/java/com/android/server/pm/AppDataHelper.java
@@ -88,6 +88,7 @@
      * <p>
      * <em>Note: To avoid a deadlock, do not call this method with {@code mLock} lock held</em>
      */
+    @GuardedBy("mPm.mInstallLock")
     public void prepareAppDataAfterInstallLIF(AndroidPackage pkg) {
         prepareAppDataPostCommitLIF(pkg, 0 /* previousAppId */);
     }
@@ -97,6 +98,7 @@
      * {@link #prepareAppData(Installer.Batch, AndroidPackage, int, int, int)}
      * @see #prepareAppDataAfterInstallLIF(AndroidPackage)
      */
+    @GuardedBy("mPm.mInstallLock")
     public void prepareAppDataPostCommitLIF(AndroidPackage pkg, int previousAppId) {
         final PackageSetting ps;
         synchronized (mPm.mLock) {
diff --git a/services/core/java/com/android/server/pm/AppsFilterBase.java b/services/core/java/com/android/server/pm/AppsFilterBase.java
index 56582b9..8501c5e 100644
--- a/services/core/java/com/android/server/pm/AppsFilterBase.java
+++ b/services/core/java/com/android/server/pm/AppsFilterBase.java
@@ -128,6 +128,16 @@
     protected SnapshotCache<WatchedSparseSetArray<Integer>> mQueryableViaUsesLibrarySnapshot;
 
     /**
+     * A mapping from the set of App IDs that query other App IDs via custom permissions to the
+     * list of packages that they can see.
+     */
+    @NonNull
+    @Watched
+    protected WatchedSparseSetArray<Integer> mQueryableViaUsesPermission;
+    @NonNull
+    protected SnapshotCache<WatchedSparseSetArray<Integer>> mQueryableViaUsesPermissionSnapshot;
+
+    /**
      * Handler for running reasonably short background tasks such as building the initial
      * visibility cache.
      */
@@ -217,6 +227,10 @@
         return mQueryableViaUsesLibrary.contains(callingAppId, targetAppId);
     }
 
+    protected boolean isQueryableViaUsesPermission(int callingAppId, int targetAppId) {
+        return mQueryableViaUsesPermission.contains(callingAppId, targetAppId);
+    }
+
     protected boolean isQueryableViaComponentWhenRequireRecompute(
             ArrayMap<String, ? extends PackageStateInternal> existingSettings,
             PackageStateInternal callingPkgSetting,
@@ -323,7 +337,8 @@
                 return false;
             } else if (Process.isSdkSandboxUid(callingAppId)) {
                 // we only allow sdk sandbox processes access to forcequeryable packages
-                return !isForceQueryable(targetPkgSetting.getAppId());
+                return !isForceQueryable(targetPkgSetting.getAppId())
+                      && !isImplicitlyQueryable(callingAppId, targetPkgSetting.getAppId());
             }
             if (mCacheReady) { // use cache
                 if (!shouldFilterApplicationUsingCache(callingUid,
@@ -627,6 +642,22 @@
                 }
             }
 
+            try {
+                if (DEBUG_TRACING) {
+                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueryableViaUsesPermission");
+                }
+                if (isQueryableViaUsesPermission(callingAppId, targetAppId)) {
+                    if (DEBUG_LOGGING) {
+                        log(callingSetting, targetPkgSetting, "queryable for permission users");
+                    }
+                    return false;
+                }
+            } finally {
+                if (DEBUG_TRACING) {
+                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+                }
+            }
+
             return true;
         } finally {
             if (DEBUG_TRACING) {
@@ -762,6 +793,13 @@
                 expandPackages);
     }
 
+    protected void dumpQueriesViaUsesPermission(PrintWriter pw, @Nullable Integer filteringAppId,
+            ToString<Integer> expandPackages) {
+        pw.println("  queryable via uses-permission:");
+        dumpQueriesMap(pw, filteringAppId, mQueryableViaUsesPermission, "    ",
+                expandPackages);
+    }
+
     private static void dumpQueriesMap(PrintWriter pw, @Nullable Integer filteringId,
             WatchedSparseSetArray<Integer> queriesMap, String spacing,
             @Nullable ToString<Integer> toString) {
diff --git a/services/core/java/com/android/server/pm/AppsFilterImpl.java b/services/core/java/com/android/server/pm/AppsFilterImpl.java
index dae7a6f..5e0b47a 100644
--- a/services/core/java/com/android/server/pm/AppsFilterImpl.java
+++ b/services/core/java/com/android/server/pm/AppsFilterImpl.java
@@ -55,6 +55,8 @@
 import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
 import com.android.server.pm.pkg.PackageStateInternal;
 import com.android.server.pm.pkg.component.ParsedInstrumentation;
+import com.android.server.pm.pkg.component.ParsedPermission;
+import com.android.server.pm.pkg.component.ParsedUsesPermission;
 import com.android.server.utils.Snappable;
 import com.android.server.utils.SnapshotCache;
 import com.android.server.utils.Watchable;
@@ -68,8 +70,11 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * Implementation of the methods that update the internal structures of AppsFilter. Because of the
@@ -90,6 +95,26 @@
     private final WatchableImpl mWatchable = new WatchableImpl();
 
     /**
+     * A cache that maps parsed {@link android.R.styleable#AndroidManifestPermission
+     * &lt;permission&gt;} to the packages that define them. While computing visibility based on
+     * permissions, this cache is used to save the cost of reading through every existing package
+     * to determine the App Ids that define a particular permission.
+     */
+    @GuardedBy("mQueryableViaUsesPermissionLock")
+    @NonNull
+    private HashMap<String, Set<Integer>> mPermissionToUids;
+
+    /**
+     * A cache that maps parsed {@link android.R.styleable#AndroidManifestUsesPermission
+     * &lt;uses-permission&gt;} to the packages that request them. While computing visibility based
+     * on permissions, this cache is used to save the cost of reading through every existing
+     * package to determine the App Ids that request a particular permission.
+     */
+    @GuardedBy("mQueryableViaUsesPermissionLock")
+    @NonNull
+    private HashMap<String, Set<Integer>> mUsesPermissionToUids;
+
+    /**
      * Ensures an observer is in the list, exactly once. The observer cannot be null.  The
      * function quietly returns if the observer is already in the list.
      *
@@ -179,12 +204,18 @@
         mQueryableViaUsesLibrarySnapshot = new SnapshotCache.Auto<>(
                 mQueryableViaUsesLibrary, mQueryableViaUsesLibrary,
                 "AppsFilter.mQueryableViaUsesLibrary");
+        mQueryableViaUsesPermission = new WatchedSparseSetArray<>();
+        mQueryableViaUsesPermissionSnapshot = new SnapshotCache.Auto<>(
+                mQueryableViaUsesPermission, mQueryableViaUsesPermission,
+                "AppsFilter.mQueryableViaUsesPermission");
         mForceQueryable = new WatchedArraySet<>();
         mForceQueryableSnapshot = new SnapshotCache.Auto<>(
                 mForceQueryable, mForceQueryable, "AppsFilter.mForceQueryable");
         mProtectedBroadcasts = new WatchedArrayList<>();
         mProtectedBroadcastsSnapshot = new SnapshotCache.Auto<>(
                 mProtectedBroadcasts, mProtectedBroadcasts, "AppsFilter.mProtectedBroadcasts");
+        mPermissionToUids = new HashMap<>();
+        mUsesPermissionToUids = new HashMap<>();
 
         mSnapshot = new SnapshotCache<AppsFilterSnapshot>(this, this) {
             @Override
@@ -532,6 +563,54 @@
             }
         }
 
+        if (!newPkg.getUsesPermissions().isEmpty()) {
+            // newPkg requests some permissions
+            synchronized (mQueryableViaUsesPermissionLock) {
+                for (ParsedUsesPermission usesPermission : newPkg.getUsesPermissions()) {
+                    String usesPermissionName = usesPermission.getName();
+                    // Lookup in the mPermissionToUids cache if installed packages have
+                    // defined this permission.
+                    if (mPermissionToUids.containsKey(usesPermissionName)) {
+                        for (int targetAppId : mPermissionToUids.get(usesPermissionName)) {
+                            if (targetAppId != newPkgSetting.getAppId()) {
+                                mQueryableViaUsesPermission.add(newPkgSetting.getAppId(),
+                                        targetAppId);
+                            }
+                        }
+                    }
+                    // Record in mUsesPermissionToUids that a permission was requested
+                    // by a new package
+                    if (!mUsesPermissionToUids.containsKey(usesPermissionName)) {
+                        mUsesPermissionToUids.put(usesPermissionName, new HashSet<>());
+                    }
+                    mUsesPermissionToUids.get(usesPermissionName).add(newPkgSetting.getAppId());
+                }
+            }
+        }
+        if (!newPkg.getPermissions().isEmpty()) {
+            synchronized (mQueryableViaUsesPermissionLock) {
+                // newPkg defines some permissions
+                for (ParsedPermission permission : newPkg.getPermissions()) {
+                    String permissionName = permission.getName();
+                    // Lookup in the mUsesPermissionToUids cache if installed packages have
+                    // requested this permission.
+                    if (mUsesPermissionToUids.containsKey(permissionName)) {
+                        for (int queryingAppId : mUsesPermissionToUids.get(permissionName)) {
+                            if (queryingAppId != newPkgSetting.getAppId()) {
+                                mQueryableViaUsesPermission.add(queryingAppId,
+                                        newPkgSetting.getAppId());
+                            }
+                        }
+                    }
+                    // Record in mPermissionToUids that a permission was defined by a new package
+                    if (!mPermissionToUids.containsKey(permissionName)) {
+                        mPermissionToUids.put(permissionName, new HashSet<>());
+                    }
+                    mPermissionToUids.get(permissionName).add(newPkgSetting.getAppId());
+                }
+            }
+        }
+
         for (int i = existingSettings.size() - 1; i >= 0; i--) {
             final PackageStateInternal existingSetting = existingSettings.valueAt(i);
             if (existingSetting.getAppId() == newPkgSetting.getAppId()
@@ -960,6 +1039,32 @@
             }
         }
 
+        synchronized (mQueryableViaUsesPermissionLock) {
+            if (setting.getPkg() != null && !setting.getPkg().getPermissions().isEmpty()) {
+                for (ParsedPermission permission : setting.getPkg().getPermissions()) {
+                    String permissionName = permission.getName();
+                    if (mPermissionToUids.containsKey(permissionName)) {
+                        mPermissionToUids.get(permissionName).remove(setting.getAppId());
+                        if (mPermissionToUids.get(permissionName).isEmpty()) {
+                            mPermissionToUids.remove(permissionName);
+                        }
+                    }
+                }
+            }
+            if (setting.getPkg() != null && !setting.getPkg().getUsesPermissions().isEmpty()) {
+                for (ParsedUsesPermission usesPermission : setting.getPkg().getUsesPermissions()) {
+                    String usesPermissionName = usesPermission.getName();
+                    if (mUsesPermissionToUids.containsKey(usesPermissionName)) {
+                        mUsesPermissionToUids.get(usesPermissionName).remove(setting.getAppId());
+                        if (mUsesPermissionToUids.get(usesPermissionName).isEmpty()) {
+                            mUsesPermissionToUids.remove(usesPermissionName);
+                        }
+                    }
+                }
+            }
+            mQueryableViaUsesPermission.remove(setting.getAppId());
+        }
+
         synchronized (mForceQueryableLock) {
             mForceQueryable.remove(setting.getAppId());
         }
diff --git a/services/core/java/com/android/server/pm/AppsFilterLocked.java b/services/core/java/com/android/server/pm/AppsFilterLocked.java
index 30eb09e..870f9da 100644
--- a/services/core/java/com/android/server/pm/AppsFilterLocked.java
+++ b/services/core/java/com/android/server/pm/AppsFilterLocked.java
@@ -33,10 +33,11 @@
     protected final Object mQueriesViaComponentLock = new Object();
     /**
      * This lock covers both {@link #mImplicitlyQueryable} and {@link #mRetainedImplicitlyQueryable}
-      */
+     */
     protected final Object mImplicitlyQueryableLock = new Object();
     protected final Object mQueryableViaUsesLibraryLock = new Object();
     protected final Object mProtectedBroadcastsLock = new Object();
+    protected final Object mQueryableViaUsesPermissionLock = new Object();
 
     /**
      * Guards the access for {@link AppsFilterBase#mShouldFilterCache};
@@ -86,6 +87,13 @@
     }
 
     @Override
+    protected boolean isQueryableViaUsesPermission(int callingAppId, int targetAppId) {
+        synchronized (mQueryableViaUsesPermissionLock) {
+            return super.isQueryableViaUsesPermission(callingAppId, targetAppId);
+        }
+    }
+
+    @Override
     protected boolean shouldFilterApplicationUsingCache(int callingUid, int appId, int userId) {
         synchronized (mCacheLock) {
             return super.shouldFilterApplicationUsingCache(callingUid, appId, userId);
diff --git a/services/core/java/com/android/server/pm/AppsFilterSnapshotImpl.java b/services/core/java/com/android/server/pm/AppsFilterSnapshotImpl.java
index 6ae6efa..019c853 100644
--- a/services/core/java/com/android/server/pm/AppsFilterSnapshotImpl.java
+++ b/services/core/java/com/android/server/pm/AppsFilterSnapshotImpl.java
@@ -44,6 +44,10 @@
             mQueryableViaUsesLibrary = orig.mQueryableViaUsesLibrarySnapshot.snapshot();
         }
         mQueryableViaUsesLibrarySnapshot = new SnapshotCache.Sealed<>();
+        synchronized (orig.mQueryableViaUsesPermissionLock) {
+            mQueryableViaUsesPermission = orig.mQueryableViaUsesPermissionSnapshot.snapshot();
+        }
+        mQueryableViaUsesPermissionSnapshot = new SnapshotCache.Sealed<>();
         synchronized (orig.mForceQueryableLock) {
             mForceQueryable = orig.mForceQueryableSnapshot.snapshot();
         }
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 7e16925..63c25ea 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -5008,6 +5008,8 @@
         final int callingUid = Binder.getCallingUid();
         final int userId = processName != null ? UserHandle.getUserId(uid)
                 : UserHandle.getCallingUserId();
+        enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
+                false /* checkShell */, "queryContentProviders");
         if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
         flags = updateFlagsForComponent(flags, userId);
         ArrayList<ProviderInfo> finalList = null;
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index 075fb47..48ec436 100644
--- a/services/core/java/com/android/server/pm/DeletePackageHelper.java
+++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java
@@ -271,7 +271,7 @@
         // other processes clean up before deleting resources.
         synchronized (mPm.mInstallLock) {
             if (info.mArgs != null) {
-                info.mArgs.doPostDeleteLI(true);
+                mRemovePackageHelper.cleanUpResources(info.mArgs);
             }
 
             boolean reEnableStub = false;
@@ -341,6 +341,7 @@
     /*
      * This method handles package deletion in general
      */
+    @GuardedBy("mPm.mInstallLock")
     public boolean deletePackageLIF(@NonNull String packageName, UserHandle user,
             boolean deleteCodeAndResources, @NonNull int[] allUserHandles, int flags,
             PackageRemovedInfo outInfo, boolean writeSettings) {
@@ -393,8 +394,18 @@
         return new DeletePackageAction(ps, disabledPs, outInfo, flags, user);
     }
 
+    public void executeDeletePackage(DeletePackageAction action, String packageName,
+            boolean deleteCodeAndResources, @NonNull int[] allUserHandles, boolean writeSettings)
+            throws SystemDeleteException {
+        synchronized (mPm.mInstallLock) {
+            executeDeletePackageLIF(action, packageName, deleteCodeAndResources, allUserHandles,
+                    writeSettings);
+        }
+    }
+
     /** Deletes a package. Only throws when install of a disabled package fails. */
-    public void executeDeletePackageLIF(DeletePackageAction action,
+    @GuardedBy("mPm.mInstallLock")
+    private void executeDeletePackageLIF(DeletePackageAction action,
             String packageName, boolean deleteCodeAndResources,
             @NonNull int[] allUserHandles, boolean writeSettings) throws SystemDeleteException {
         final PackageSetting ps = action.mDeletingPs;
@@ -487,7 +498,9 @@
 
         // Take a note whether we deleted the package for all users
         if (outInfo != null) {
-            outInfo.mRemovedForAllUsers = mPm.mPackages.get(ps.getPackageName()) == null;
+            synchronized (mPm.mLock) {
+                outInfo.mRemovedForAllUsers = mPm.mPackages.get(ps.getPackageName()) == null;
+            }
         }
     }
 
@@ -538,6 +551,7 @@
         }
     }
 
+    @GuardedBy("mPm.mInstallLock")
     private void deleteInstalledPackageLIF(PackageSetting ps,
             boolean deleteCodeAndResources, int flags, @NonNull int[] allUserHandles,
             PackageRemovedInfo outInfo, boolean writeSettings) {
@@ -556,7 +570,7 @@
 
         // Delete application code and resources only for parent packages
         if (deleteCodeAndResources && (outInfo != null)) {
-            outInfo.mArgs = new FileInstallArgs(
+            outInfo.mArgs = new InstallArgs(
                     ps.getPathString(), getAppDexInstructionSets(
                             ps.getPrimaryCpuAbi(), ps.getSecondaryCpuAbi()), mPm);
             if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.mArgs);
@@ -636,7 +650,10 @@
             flags |= PackageManager.DELETE_KEEP_DATA;
         }
 
-        deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles, outInfo, writeSettings);
+        synchronized (mPm.mInstallLock) {
+            deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles, outInfo,
+                    writeSettings);
+        }
     }
 
     public void deletePackageVersionedInternal(VersionedPackage versionedPackage,
diff --git a/services/core/java/com/android/server/pm/FileInstallArgs.java b/services/core/java/com/android/server/pm/FileInstallArgs.java
deleted file mode 100644
index 4d9e2a3..0000000
--- a/services/core/java/com/android/server/pm/FileInstallArgs.java
+++ /dev/null
@@ -1,268 +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 com.android.server.pm;
-
-import static android.app.AppOpsManager.MODE_DEFAULT;
-import static android.content.pm.PackageManager.INSTALL_STAGED;
-import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
-import static android.os.incremental.IncrementalManager.isIncrementalPath;
-
-import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
-import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
-import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
-import static com.android.server.pm.PackageManagerService.TAG;
-import static com.android.server.pm.PackageManagerServiceUtils.makeDirRecursive;
-
-import android.content.pm.DataLoaderType;
-import android.content.pm.PackageInstaller;
-import android.content.pm.PackageManager;
-import android.content.pm.SigningDetails;
-import android.content.pm.parsing.ApkLiteParseUtils;
-import android.content.pm.parsing.PackageLite;
-import android.content.pm.parsing.result.ParseResult;
-import android.content.pm.parsing.result.ParseTypeImpl;
-import android.os.Environment;
-import android.os.FileUtils;
-import android.os.SELinux;
-import android.os.Trace;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.util.Slog;
-
-import com.android.internal.content.NativeLibraryHelper;
-import com.android.server.pm.parsing.pkg.ParsedPackage;
-
-import libcore.io.IoUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Logic to handle installation of new applications, including copying
- * and renaming logic.
- */
-class FileInstallArgs extends InstallArgs {
-    private File mCodeFile;
-
-    // Example topology:
-    // /data/app/com.example/base.apk
-    // /data/app/com.example/split_foo.apk
-    // /data/app/com.example/lib/arm/libfoo.so
-    // /data/app/com.example/lib/arm64/libfoo.so
-    // /data/app/com.example/dalvik/arm/base.apk@classes.dex
-
-    /** New install */
-    FileInstallArgs(InstallingSession params) {
-        super(params);
-    }
-
-    /**
-     * Create args that describe an existing installed package. Typically used
-     * when cleaning up old installs, or used as a move source.
-     */
-    FileInstallArgs(String codePath, String[] instructionSets, PackageManagerService pm) {
-        super(OriginInfo.fromNothing(), null, null, 0, InstallSource.EMPTY,
-                null, null, instructionSets, null, null, null, MODE_DEFAULT, null, 0,
-                SigningDetails.UNKNOWN,
-                PackageManager.INSTALL_REASON_UNKNOWN, PackageManager.INSTALL_SCENARIO_DEFAULT,
-                false, DataLoaderType.NONE,
-                PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED, pm);
-        mCodeFile = (codePath != null) ? new File(codePath) : null;
-    }
-
-    int copyApk() {
-        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
-        try {
-            return doCopyApk();
-        } finally {
-            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-        }
-    }
-
-    private int doCopyApk() {
-        if (mOriginInfo.mStaged) {
-            if (DEBUG_INSTALL) Slog.d(TAG, mOriginInfo.mFile + " already staged; skipping copy");
-            mCodeFile = mOriginInfo.mFile;
-            return PackageManager.INSTALL_SUCCEEDED;
-        }
-
-        try {
-            final boolean isEphemeral = (mInstallFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
-            final File tempDir =
-                    mPm.mInstallerService.allocateStageDirLegacy(mVolumeUuid, isEphemeral);
-            mCodeFile = tempDir;
-        } catch (IOException e) {
-            Slog.w(TAG, "Failed to create copy file: " + e);
-            return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
-        }
-
-        int ret = PackageManagerServiceUtils.copyPackage(
-                mOriginInfo.mFile.getAbsolutePath(), mCodeFile);
-        if (ret != PackageManager.INSTALL_SUCCEEDED) {
-            Slog.e(TAG, "Failed to copy package");
-            return ret;
-        }
-
-        final boolean isIncremental = isIncrementalPath(mCodeFile.getAbsolutePath());
-        final File libraryRoot = new File(mCodeFile, LIB_DIR_NAME);
-        NativeLibraryHelper.Handle handle = null;
-        try {
-            handle = NativeLibraryHelper.Handle.create(mCodeFile);
-            ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
-                    mAbiOverride, isIncremental);
-        } catch (IOException e) {
-            Slog.e(TAG, "Copying native libraries failed", e);
-            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
-        } finally {
-            IoUtils.closeQuietly(handle);
-        }
-
-        return ret;
-    }
-
-    int doPreInstall(int status) {
-        if (status != PackageManager.INSTALL_SUCCEEDED) {
-            cleanUp();
-        }
-        return status;
-    }
-
-    @Override
-    boolean doRename(int status, ParsedPackage parsedPackage) {
-        if (status != PackageManager.INSTALL_SUCCEEDED) {
-            cleanUp();
-            return false;
-        }
-
-        final File targetDir = resolveTargetDir();
-        final File beforeCodeFile = mCodeFile;
-        final File afterCodeFile = PackageManagerServiceUtils.getNextCodePath(targetDir,
-                parsedPackage.getPackageName());
-
-        if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
-        final boolean onIncremental = mPm.mIncrementalManager != null
-                && isIncrementalPath(beforeCodeFile.getAbsolutePath());
-        try {
-            makeDirRecursive(afterCodeFile.getParentFile(), 0775);
-            if (onIncremental) {
-                // Just link files here. The stage dir will be removed when the installation
-                // session is completed.
-                mPm.mIncrementalManager.linkCodePath(beforeCodeFile, afterCodeFile);
-            } else {
-                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
-            }
-        } catch (IOException | ErrnoException e) {
-            Slog.w(TAG, "Failed to rename", e);
-            return false;
-        }
-
-        if (!onIncremental && !SELinux.restoreconRecursive(afterCodeFile)) {
-            Slog.w(TAG, "Failed to restorecon");
-            return false;
-        }
-
-        // Reflect the rename internally
-        mCodeFile = afterCodeFile;
-
-        // Reflect the rename in scanned details
-        try {
-            parsedPackage.setPath(afterCodeFile.getCanonicalPath());
-        } catch (IOException e) {
-            Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
-            return false;
-        }
-        parsedPackage.setBaseApkPath(FileUtils.rewriteAfterRename(beforeCodeFile,
-                afterCodeFile, parsedPackage.getBaseApkPath()));
-        parsedPackage.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
-                afterCodeFile, parsedPackage.getSplitCodePaths()));
-
-        return true;
-    }
-
-    // TODO(b/168126411): Once staged install flow starts using the same folder as non-staged
-    //  flow, we won't need this method anymore.
-    private File resolveTargetDir() {
-        boolean isStagedInstall = (mInstallFlags & INSTALL_STAGED) != 0;
-        if (isStagedInstall) {
-            return Environment.getDataAppDirectory(null);
-        } else {
-            return mCodeFile.getParentFile();
-        }
-    }
-
-    int doPostInstall(int status, int uid) {
-        if (status != PackageManager.INSTALL_SUCCEEDED) {
-            cleanUp();
-        }
-        return status;
-    }
-
-    @Override
-    String getCodePath() {
-        return (mCodeFile != null) ? mCodeFile.getAbsolutePath() : null;
-    }
-
-    private boolean cleanUp() {
-        if (mCodeFile == null || !mCodeFile.exists()) {
-            return false;
-        }
-        mRemovePackageHelper.removeCodePathLI(mCodeFile);
-        return true;
-    }
-
-    void cleanUpResourcesLI() {
-        // Try enumerating all code paths before deleting
-        List<String> allCodePaths = Collections.EMPTY_LIST;
-        if (mCodeFile != null && mCodeFile.exists()) {
-            final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
-            final ParseResult<PackageLite> result = ApkLiteParseUtils.parsePackageLite(
-                    input.reset(), mCodeFile, /* flags */ 0);
-            if (result.isSuccess()) {
-                // Ignore error; we tried our best
-                allCodePaths = result.getResult().getAllApkPaths();
-            }
-        }
-
-        cleanUp();
-        removeDexFiles(allCodePaths, mInstructionSets);
-    }
-
-    void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
-        if (!allCodePaths.isEmpty()) {
-            if (instructionSets == null) {
-                throw new IllegalStateException("instructionSet == null");
-            }
-            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
-            for (String codePath : allCodePaths) {
-                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
-                    try {
-                        mPm.mInstaller.rmdex(codePath, dexCodeInstructionSet);
-                    } catch (Installer.InstallerException ignored) {
-                    }
-                }
-            }
-        }
-    }
-
-    boolean doPostDeleteLI(boolean delete) {
-        // XXX err, shouldn't we respect the delete flag?
-        cleanUpResourcesLI();
-        return true;
-    }
-}
diff --git a/services/core/java/com/android/server/pm/IPackageManagerBase.java b/services/core/java/com/android/server/pm/IPackageManagerBase.java
index f4285eb..c70e6ad 100644
--- a/services/core/java/com/android/server/pm/IPackageManagerBase.java
+++ b/services/core/java/com/android/server/pm/IPackageManagerBase.java
@@ -387,14 +387,6 @@
         return snapshot().getComponentEnabledSetting(component, Binder.getCallingUid(), userId);
     }
 
-    @Override
-    @Deprecated
-    public final String getContentCaptureServicePackageName() {
-        return mService.ensureSystemPackageName(snapshot(),
-                mService.getPackageFromComponentString(
-                        R.string.config_defaultContentCaptureService));
-    }
-
     @Nullable
     @Override
     @Deprecated
diff --git a/services/core/java/com/android/server/pm/InstallArgs.java b/services/core/java/com/android/server/pm/InstallArgs.java
index fa8a975..616bb8f 100644
--- a/services/core/java/com/android/server/pm/InstallArgs.java
+++ b/services/core/java/com/android/server/pm/InstallArgs.java
@@ -16,19 +16,24 @@
 
 package com.android.server.pm;
 
+import static android.app.AppOpsManager.MODE_DEFAULT;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.pm.DataLoaderType;
 import android.content.pm.IPackageInstallObserver2;
+import android.content.pm.PackageInstaller;
 import android.content.pm.PackageManager;
 import android.content.pm.SigningDetails;
 import android.os.UserHandle;
 
 import com.android.internal.util.Preconditions;
-import com.android.server.pm.parsing.pkg.ParsedPackage;
 
+import java.io.File;
 import java.util.List;
 
-abstract class InstallArgs {
+final class InstallArgs {
+    File mCodeFile;
     /** @see InstallingSession#mOriginInfo */
     final OriginInfo mOriginInfo;
     /** @see InstallingSession#mMoveInfo */
@@ -108,28 +113,21 @@
                 params.mDataLoaderType, params.mPackageSource, params.mPm);
     }
 
-    abstract int copyApk();
-    abstract int doPreInstall(int status);
-
     /**
-     * Rename package into final resting place. All paths on the given
-     * scanned package should be updated to reflect the rename.
+     * Create args that describe an existing installed package. Typically used
+     * when cleaning up old installs, or used as a move source.
      */
-    abstract boolean doRename(int status, ParsedPackage parsedPackage);
-    abstract int doPostInstall(int status, int uid);
-
-    /** @see PackageSettingBase#getPath() */
-    abstract String getCodePath();
-
-    // Need installer lock especially for dex file removal.
-    abstract void cleanUpResourcesLI();
-    abstract boolean doPostDeleteLI(boolean delete);
-
-    protected boolean isEphemeral() {
-        return (mInstallFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
+    InstallArgs(String codePath, String[] instructionSets, PackageManagerService pm) {
+        this(OriginInfo.fromNothing(), null, null, 0, InstallSource.EMPTY,
+                null, null, instructionSets, null, null, null, MODE_DEFAULT, null, 0,
+                SigningDetails.UNKNOWN, PackageManager.INSTALL_REASON_UNKNOWN,
+                PackageManager.INSTALL_SCENARIO_DEFAULT, false, DataLoaderType.NONE,
+                PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED, pm);
+        mCodeFile = (codePath != null) ? new File(codePath) : null;
     }
 
-    UserHandle getUser() {
-        return mUser;
+    /** @see PackageSettingBase#getPath() */
+    String getCodePath() {
+        return (mCodeFile != null) ? mCodeFile.getAbsolutePath() : null;
     }
 }
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index e2bf4a4..8bb9b84 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -34,6 +34,7 @@
 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
 import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_RESTORE;
 import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_SETUP;
+import static android.content.pm.PackageManager.INSTALL_STAGED;
 import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
 import static android.content.pm.PackageManager.UNINSTALL_REASON_UNKNOWN;
 import static android.content.pm.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V4;
@@ -89,6 +90,7 @@
 import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
 import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride;
 import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
+import static com.android.server.pm.PackageManagerServiceUtils.makeDirRecursive;
 import static com.android.server.pm.SharedUidMigration.BEST_EFFORT;
 
 import android.annotation.NonNull;
@@ -123,9 +125,11 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
+import android.os.FileUtils;
 import android.os.Message;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.SELinux;
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
@@ -135,6 +139,8 @@
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
 import android.stats.storage.StorageEnums;
+import android.system.ErrnoException;
+import android.system.Os;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.EventLog;
@@ -236,7 +242,7 @@
      * This needs to be fixed so, once we get to this point, no errors are
      * possible and the system is not left in an inconsistent state.
      */
-    @GuardedBy({"mPm.mLock", "mPm.mInstallLock"})
+    @GuardedBy("mPm.mLock")
     public AndroidPackage commitReconciledScanResultLocked(
             @NonNull ReconciledPackage reconciledPkg, int[] allUsers) {
         final ScanResult result = reconciledPkg.mScanResult;
@@ -347,7 +353,7 @@
                 || (oldPkgSetting != null && oldPkgSetting.getUsesLibraryInfos() != null)) {
             // Reconcile if the new package or the old package uses shared libraries.
             // It is possible that the old package uses shared libraries but the new one doesn't.
-            mSharedLibraries.executeSharedLibrariesUpdateLPw(pkg, pkgSetting, null, null,
+            mSharedLibraries.executeSharedLibrariesUpdate(pkg, pkgSetting, null, null,
                     reconciledPkg.mCollectedSharedLibraryInfos, allUsers);
         }
 
@@ -365,8 +371,10 @@
             for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
                 final String codePathString = changedAbiCodePath.get(i);
                 try {
-                    mPm.mInstaller.rmdex(codePathString,
-                            getDexCodeInstructionSet(getPreferredInstructionSet()));
+                    synchronized (mPm.mInstallLock) {
+                        mPm.mInstaller.rmdex(codePathString,
+                                getDexCodeInstructionSet(getPreferredInstructionSet()));
+                    }
                 } catch (Installer.InstallerException ignored) {
                 }
             }
@@ -405,30 +413,12 @@
             mPm.setPlatformPackage(pkg, pkgSetting);
         }
 
-        ArrayList<AndroidPackage> clientLibPkgs = null;
         // writer
-        synchronized (mPm.mLock) {
-            if (!ArrayUtils.isEmpty(reconciledPkg.mAllowedSharedLibraryInfos)) {
-                for (SharedLibraryInfo info : reconciledPkg.mAllowedSharedLibraryInfos) {
-                    mSharedLibraries.commitSharedLibraryInfoLPw(info);
-                }
-                final Map<String, AndroidPackage> combinedSigningDetails =
-                        reconciledPkg.getCombinedAvailablePackages();
-                try {
-                    // Shared libraries for the package need to be updated.
-                    mSharedLibraries.updateSharedLibrariesLPw(pkg, pkgSetting, null, null,
-                            combinedSigningDetails);
-                } catch (PackageManagerException e) {
-                    Slog.e(TAG, "updateSharedLibrariesLPr failed: ", e);
-                }
-                // Update all applications that use this library. Skip when booting
-                // since this will be done after all packages are scaned.
-                if ((scanFlags & SCAN_BOOTING) == 0) {
-                    clientLibPkgs = mSharedLibraries.updateAllSharedLibrariesLPw(pkg, pkgSetting,
-                            combinedSigningDetails);
-                }
-            }
-        }
+        ArrayList<AndroidPackage> clientLibPkgs =
+                mSharedLibraries.commitSharedLibraryChanges(pkg, pkgSetting,
+                        reconciledPkg.mAllowedSharedLibraryInfos,
+                        reconciledPkg.getCombinedAvailablePackages(), scanFlags);
+
         if (reconciledPkg.mInstallResult != null) {
             reconciledPkg.mInstallResult.mLibraryConsumers = clientLibPkgs;
         }
@@ -473,9 +463,13 @@
                 mApexManager.registerApkInApex(pkg);
             }
 
-            // Add the package's KeySets to the global KeySetManagerService
-            KeySetManagerService ksms = mPm.mSettings.getKeySetManagerService();
-            ksms.addScannedPackageLPw(pkg);
+            // Don't add keysets for APEX as their package settings are not persisted and will
+            // result in orphaned keysets.
+            if ((scanFlags & SCAN_AS_APEX) == 0) {
+                // Add the package's KeySets to the global KeySetManagerService
+                KeySetManagerService ksms = mPm.mSettings.getKeySetManagerService();
+                ksms.addScannedPackageLPw(pkg);
+            }
 
             final Computer snapshot = mPm.snapshotComputer();
             mPm.mComponentResolver.addAllComponents(pkg, chatty, mPm.mSetupWizardPackage, snapshot);
@@ -791,127 +785,15 @@
         return false;
     }
 
-    public void processInstallRequests(boolean success, List<InstallRequest> installRequests) {
-        List<InstallRequest> apexInstallRequests = new ArrayList<>();
-        List<InstallRequest> apkInstallRequests = new ArrayList<>();
-        for (InstallRequest request : installRequests) {
-            if ((request.mArgs.mInstallFlags & PackageManager.INSTALL_APEX) != 0) {
-                apexInstallRequests.add(request);
-            } else {
-                apkInstallRequests.add(request);
+    void installPackagesTraced(List<InstallRequest> requests) {
+        synchronized (mPm.mInstallLock) {
+            try {
+                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackages");
+                installPackagesLI(requests);
+            } finally {
+                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
             }
         }
-        // Note: supporting multi package install of both APEXes and APKs might requir some
-        // thinking to ensure atomicity of the install.
-        if (!apexInstallRequests.isEmpty() && !apkInstallRequests.isEmpty()) {
-            // This should've been caught at the validation step, but for some reason wasn't.
-            throw new IllegalStateException(
-                    "Attempted to do a multi package install of both APEXes and APKs");
-        }
-        if (!apexInstallRequests.isEmpty()) {
-            if (success) {
-                // Since installApexPackages requires talking to external service (apexd), we
-                // schedule to run it async. Once it finishes, it will resume the install.
-                Thread t = new Thread(() -> installApexPackagesTraced(apexInstallRequests),
-                        "installApexPackages");
-                t.start();
-            } else {
-                // Non-staged APEX installation failed somewhere before
-                // processInstallRequestAsync. In that case just notify the observer about the
-                // failure.
-                InstallRequest request = apexInstallRequests.get(0);
-                mPm.notifyInstallObserver(request.mInstallResult,
-                        request.mArgs.mObserver);
-            }
-            return;
-        }
-
-        processApkInstallRequests(success, installRequests);
-    }
-
-    private void processApkInstallRequests(boolean success, List<InstallRequest> installRequests) {
-        if (success) {
-            for (InstallRequest request : installRequests) {
-                request.mArgs.doPreInstall(request.mInstallResult.mReturnCode);
-            }
-            synchronized (mPm.mInstallLock) {
-                installPackagesTracedLI(installRequests);
-            }
-            for (InstallRequest request : installRequests) {
-                request.mArgs.doPostInstall(
-                        request.mInstallResult.mReturnCode, request.mInstallResult.mUid);
-            }
-        }
-        for (InstallRequest request : installRequests) {
-            restoreAndPostInstall(request.mArgs.mUser.getIdentifier(),
-                    request.mInstallResult,
-                    new PostInstallData(request.mArgs,
-                            request.mInstallResult, null));
-        }
-    }
-
-    private void installApexPackagesTraced(List<InstallRequest> requests) {
-        try {
-            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installApexPackages");
-            installApexPackages(requests);
-        } finally {
-            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-        }
-    }
-
-    private void installApexPackages(List<InstallRequest> requests) {
-        if (requests.isEmpty()) {
-            return;
-        }
-        if (requests.size() != 1) {
-            throw new IllegalStateException(
-                    "Only a non-staged install of a single APEX is supported");
-        }
-        InstallRequest request = requests.get(0);
-        try {
-            // Should directory scanning logic be moved to ApexManager for better test coverage?
-            final File dir = request.mArgs.mOriginInfo.mResolvedFile;
-            final File[] apexes = dir.listFiles();
-            if (apexes == null) {
-                throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
-                        dir.getAbsolutePath() + " is not a directory");
-            }
-            if (apexes.length != 1) {
-                throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
-                        "Expected exactly one .apex file under " + dir.getAbsolutePath()
-                                + " got: " + apexes.length);
-            }
-            try (PackageParser2 packageParser = mPm.mInjector.getScanningPackageParser()) {
-                ApexInfo apexInfo = mApexManager.installPackage(apexes[0]);
-                if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
-                    // APEX has been handled successfully by apexd. Let's continue the install flow
-                    // so it will be scanned and registered with the system.
-                    // TODO(b/225756739): Improve atomicity of rebootless APEX install.
-                    // The newly installed APEX will not be reverted even if
-                    // processApkInstallRequests() fails. Need a way to keep info stored in apexd
-                    // and PMS in sync in the face of install failures.
-                    request.mInstallResult.mApexInfo = apexInfo;
-                    mPm.mHandler.post(() -> processApkInstallRequests(true, requests));
-                    return;
-                } else {
-                    mPm.mApexPackageInfo.notifyPackageInstalled(apexInfo, packageParser);
-                }
-            }
-        } catch (PackageManagerException e) {
-            request.mInstallResult.setError("APEX installation failed", e);
-        }
-        PackageManagerService.invalidatePackageInfoCache();
-        mPm.notifyInstallObserver(request.mInstallResult, request.mArgs.mObserver);
-    }
-
-    @GuardedBy("mPm.mInstallLock")
-    private void installPackagesTracedLI(List<InstallRequest> requests) {
-        try {
-            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackages");
-            installPackagesLI(requests);
-        } finally {
-            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-        }
     }
 
     /**
@@ -1006,11 +888,12 @@
                     return;
                 }
             }
-            ReconcileRequest reconcileRequest = new ReconcileRequest(preparedScans, installArgs,
-                    installResults, prepareResults,
-                    Collections.unmodifiableMap(mPm.mPackages), versionInfos);
-            CommitRequest commitRequest = null;
+
+            CommitRequest commitRequest;
             synchronized (mPm.mLock) {
+                ReconcileRequest reconcileRequest = new ReconcileRequest(preparedScans, installArgs,
+                        installResults, prepareResults,
+                        Collections.unmodifiableMap(mPm.mPackages), versionInfos);
                 Map<String, ReconciledPackage> reconciledPackages;
                 try {
                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "reconcilePackages");
@@ -1035,7 +918,7 @@
                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                 }
             }
-            executePostCommitSteps(commitRequest);
+            executePostCommitStepsLIF(commitRequest);
         } finally {
             if (success) {
                 for (InstallRequest request : requests) {
@@ -1057,7 +940,7 @@
                             .buildVerificationRootHashString(baseCodePath, splitCodePaths);
                     VerificationUtils.broadcastPackageVerified(verificationId, originUri,
                             PackageManager.VERIFICATION_ALLOW, rootHashString,
-                            args.mDataLoaderType, args.getUser(), mContext);
+                            args.mDataLoaderType, args.mUser, mContext);
                 }
             } else {
                 for (ScanResult result : preparedScans.values()) {
@@ -1284,7 +1167,7 @@
             // the package setting for the latest library version.
             if (parsedPackage.isStaticSharedLibrary()) {
                 SharedLibraryInfo libraryInfo =
-                        mSharedLibraries.getLatestStaticSharedLibraVersionLPr(parsedPackage);
+                        mSharedLibraries.getLatestStaticSharedLibraVersion(parsedPackage);
                 if (libraryInfo != null) {
                     signatureCheckPs = mPm.mSettings.getPackageLPr(libraryInfo.getPackageName());
                 }
@@ -1537,7 +1420,7 @@
         }
 
         if (!isApex) {
-            if (!args.doRename(res.mReturnCode, parsedPackage)) {
+            if (!doRenameLI(args, res.mReturnCode, parsedPackage)) {
                 throw new PrepareFailure(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
             }
 
@@ -1801,6 +1684,82 @@
         }
     }
 
+    /**
+     * Rename package into final resting place. All paths on the given
+     * scanned package should be updated to reflect the rename.
+     */
+    @GuardedBy("mPm.mInstallLock")
+    private boolean doRenameLI(InstallArgs args, int status, ParsedPackage parsedPackage) {
+        if (args.mMoveInfo != null) {
+            if (status != PackageManager.INSTALL_SUCCEEDED) {
+                mRemovePackageHelper.cleanUpForMoveInstall(args.mMoveInfo.mToUuid,
+                        args.mMoveInfo.mPackageName, args.mMoveInfo.mFromCodePath);
+                return false;
+            }
+            return true;
+        }
+        // For file installations
+        if (status != PackageManager.INSTALL_SUCCEEDED) {
+            mRemovePackageHelper.removeCodePath(args.mCodeFile);
+            return false;
+        }
+
+        final File targetDir = resolveTargetDir(args);
+        final File beforeCodeFile = args.mCodeFile;
+        final File afterCodeFile = PackageManagerServiceUtils.getNextCodePath(targetDir,
+                parsedPackage.getPackageName());
+
+        if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
+        final boolean onIncremental = mPm.mIncrementalManager != null
+                && isIncrementalPath(beforeCodeFile.getAbsolutePath());
+        try {
+            makeDirRecursive(afterCodeFile.getParentFile(), 0775);
+            if (onIncremental) {
+                // Just link files here. The stage dir will be removed when the installation
+                // session is completed.
+                mPm.mIncrementalManager.linkCodePath(beforeCodeFile, afterCodeFile);
+            } else {
+                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
+            }
+        } catch (IOException | ErrnoException e) {
+            Slog.w(TAG, "Failed to rename", e);
+            return false;
+        }
+
+        if (!onIncremental && !SELinux.restoreconRecursive(afterCodeFile)) {
+            Slog.w(TAG, "Failed to restorecon");
+            return false;
+        }
+
+        // Reflect the rename internally
+        args.mCodeFile = afterCodeFile;
+
+        // Reflect the rename in scanned details
+        try {
+            parsedPackage.setPath(afterCodeFile.getCanonicalPath());
+        } catch (IOException e) {
+            Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
+            return false;
+        }
+        parsedPackage.setBaseApkPath(FileUtils.rewriteAfterRename(beforeCodeFile,
+                afterCodeFile, parsedPackage.getBaseApkPath()));
+        parsedPackage.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
+                afterCodeFile, parsedPackage.getSplitCodePaths()));
+
+        return true;
+    }
+
+    // TODO(b/168126411): Once staged install flow starts using the same folder as non-staged
+    //  flow, we won't need this method anymore.
+    private File resolveTargetDir(InstallArgs args) {
+        boolean isStagedInstall = (args.mInstallFlags & INSTALL_STAGED) != 0;
+        if (isStagedInstall) {
+            return Environment.getDataAppDirectory(null);
+        } else {
+            return args.mCodeFile.getParentFile();
+        }
+    }
+
     /*
      * Cannot properly check CANNOT_INSTALL_WITH_BAD_PERMISSION_GROUPS using CompatChanges
      * as this only works for packages that are installed
@@ -1898,7 +1857,6 @@
             }
         }
 
-        final String packageName = pkg.getPackageName();
         for (Map.Entry<String, String> entry : fsverityCandidates.entrySet()) {
             final String filePath = entry.getKey();
             final String signaturePath = entry.getValue();
@@ -1969,12 +1927,12 @@
                         mPm.mSettings.getPackagesLocked());
                 if (reconciledPkg.mPrepareResult.mSystem) {
                     // Remove existing system package
-                    removePackageHelper.removePackageLI(oldPackage, true);
+                    removePackageHelper.removePackage(oldPackage, true);
                     if (!disableSystemPackageLPw(oldPackage)) {
                         // We didn't need to disable the .apk as a current system package,
                         // which means we are replacing another update that is already
                         // installed.  We need to make sure to delete the older one's .apk.
-                        res.mRemovedInfo.mArgs = new FileInstallArgs(
+                        res.mRemovedInfo.mArgs = new InstallArgs(
                                 oldPackage.getPath(),
                                 getAppDexInstructionSets(
                                         AndroidPackageUtils.getPrimaryCpuAbi(oldPackage,
@@ -1987,7 +1945,7 @@
                 } else {
                     try {
                         // Settings will be written during the call to updateSettingsLI().
-                        deletePackageHelper.executeDeletePackageLIF(
+                        deletePackageHelper.executeDeletePackage(
                                 reconciledPkg.mDeletePackageAction, packageName,
                                 true, request.mAllUsers, false);
                     } catch (SystemDeleteException e) {
@@ -2257,7 +2215,8 @@
      * is released. These are typically more expensive or require calls to installd, which often
      * locks on {@link com.android.server.pm.PackageManagerService.mLock}.
      */
-    private void executePostCommitSteps(CommitRequest commitRequest) {
+    @GuardedBy("mPm.mInstallLock")
+    private void executePostCommitStepsLIF(CommitRequest commitRequest) {
         final ArraySet<IncrementalStorage> incrementalStorages = new ArraySet<>();
         for (ReconciledPackage reconciledPkg : commitRequest.mReconciledPackages.values()) {
             final boolean instantApp = ((reconciledPkg.mScanResult.mRequest.mScanFlags
@@ -2648,9 +2607,7 @@
             // Remove the update failed package's older resources safely now
             InstallArgs args = res.mRemovedInfo != null ? res.mRemovedInfo.mArgs : null;
             if (args != null) {
-                synchronized (mPm.mInstallLock) {
-                    args.doPostDeleteLI(true);
-                }
+                mRemovePackageHelper.cleanUpResources(args);
             }
             mPm.notifyInstallObserver(res, installObserver);
             return;
@@ -2888,9 +2845,7 @@
                     // ApplicationInfo changes have propagated to all application threads.
                     mPm.scheduleDeferredNoKillPostDelete(args);
                 } else {
-                    synchronized (mPm.mInstallLock) {
-                        args.doPostDeleteLI(true);
-                    }
+                    mRemovePackageHelper.cleanUpResources(args);
                 }
             } else {
                 // Force a gc to clear up things. Ask for a background one, it's fine to go on
@@ -3024,7 +2979,7 @@
                 mAppDataHelper.prepareAppDataAfterInstallLIF(pkg);
                 synchronized (mPm.mLock) {
                     try {
-                        mSharedLibraries.updateSharedLibrariesLPw(
+                        mSharedLibraries.updateSharedLibraries(
                                 pkg, stubPkgSetting, null, null,
                                 Collections.unmodifiableMap(mPm.mPackages));
                     } catch (PackageManagerException e) {
@@ -3096,14 +3051,14 @@
             mPm.mSettings.disableSystemPackageLPw(stubPkg.getPackageName(), true /*replaced*/);
         }
         final RemovePackageHelper removePackageHelper = new RemovePackageHelper(mPm);
-        removePackageHelper.removePackageLI(stubPkg, true /*chatty*/);
+        removePackageHelper.removePackage(stubPkg, true /*chatty*/);
         try {
             return scanSystemPackageTracedLI(scanFile, parseFlags, scanFlags, null);
         } catch (PackageManagerException e) {
             Slog.w(TAG, "Failed to install compressed system package:" + stubPkg.getPackageName(),
                     e);
             // Remove the failed install
-            removePackageHelper.removeCodePathLI(scanFile);
+            removePackageHelper.removeCodePath(scanFile);
             throw e;
         }
     }
@@ -3146,7 +3101,7 @@
             if (!dstCodePath.exists()) {
                 return null;
             }
-            new RemovePackageHelper(mPm).removeCodePathLI(dstCodePath);
+            new RemovePackageHelper(mPm).removeCodePath(dstCodePath);
             return null;
         }
 
@@ -3232,16 +3187,16 @@
         final AndroidPackage pkg = scanSystemPackageTracedLI(
                 codePath, parseFlags, scanFlags, null);
 
-        PackageSetting pkgSetting = mPm.mSettings.getPackageLPr(pkg.getPackageName());
-
-        try {
-            // update shared libraries for the newly re-installed system package
-            mSharedLibraries.updateSharedLibrariesLPw(pkg, pkgSetting, null, null,
-                    Collections.unmodifiableMap(mPm.mPackages));
-        } catch (PackageManagerException e) {
-            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
+        synchronized (mPm.mLock) {
+            PackageSetting pkgSetting = mPm.mSettings.getPackageLPr(pkg.getPackageName());
+            try {
+                // update shared libraries for the newly re-installed system package
+                mSharedLibraries.updateSharedLibraries(pkg, pkgSetting, null, null,
+                        Collections.unmodifiableMap(mPm.mPackages));
+            } catch (PackageManagerException e) {
+                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
+            }
         }
-
         mAppDataHelper.prepareAppDataAfterInstallLIF(pkg);
 
         setPackageInstalledForSystemPackage(pkg, allUserHandles, origUserHandles, writeSettings);
@@ -3344,7 +3299,7 @@
                                     + ", versionCode=" + ps.getVersionCode()
                                     + "; scanned versionCode="
                                     + scannedPkg.getLongVersionCode());
-                    mRemovePackageHelper.removePackageLI(scannedPkg, true);
+                    mRemovePackageHelper.removePackage(scannedPkg, true);
                     expectingBetter.put(ps.getPackageName(), ps.getPath());
                 }
 
@@ -3354,7 +3309,7 @@
             if (disabledPs == null) {
                 logCriticalInfo(Log.WARN, "System package " + packageName
                         + " no longer exists; its data will be wiped");
-                mRemovePackageHelper.removePackageDataLIF(ps, userIds, null, 0, false);
+                mRemovePackageHelper.removePackageData(ps, userIds, null, 0, false);
             } else {
                 // we still have a disabled system package, but, it still might have
                 // been removed. check the code path still exists and check there's
@@ -3405,10 +3360,12 @@
 
                 // remove the package from the system and re-scan it without any
                 // special privileges
-                mRemovePackageHelper.removePackageLI(pkg, true);
+                mRemovePackageHelper.removePackage(pkg, true);
                 try {
                     final File codePath = new File(pkg.getPath());
-                    scanSystemPackageTracedLI(codePath, 0, scanFlags, null);
+                    synchronized (mPm.mInstallLock) {
+                        scanSystemPackageTracedLI(codePath, 0, scanFlags, null);
+                    }
                 } catch (PackageManagerException e) {
                     Slog.e(TAG, "Failed to parse updated, ex-system package: "
                             + e.getMessage());
@@ -3421,7 +3378,7 @@
             // partition], completely remove the package data.
             final PackageSetting ps = mPm.mSettings.getPackageLPr(packageName);
             if (ps != null && mPm.mPackages.get(packageName) == null) {
-                mRemovePackageHelper.removePackageDataLIF(ps, userIds, null, 0, false);
+                mRemovePackageHelper.removePackageData(ps, userIds, null, 0, false);
             }
             logCriticalInfo(Log.WARN, msg);
         }
@@ -3464,8 +3421,9 @@
         }
         // Sort the list to ensure we always process factory packages first
         Collections.sort(parseResults, (a, b) -> {
-            ApexInfo ai = parsingApexInfo.get(a.scanFile);
-            return ai.isFactory ? -1 : 1;
+            ApexInfo i1 = parsingApexInfo.get(a.scanFile);
+            ApexInfo i2 = parsingApexInfo.get(b.scanFile);
+            return Boolean.compare(i2.isFactory, i1.isFactory);
         });
 
 
@@ -3476,7 +3434,8 @@
             Throwable throwable = parseResult.throwable;
             ApexInfo ai = parsingApexInfo.get(parseResult.scanFile);
             int newParseFlags = parseFlags;
-            int newScanFlags = scanFlags | SCAN_AS_APEX;
+            int newScanFlags = scanFlags | SCAN_AS_APEX
+                    | mPm.getSystemPackageScanFlags(parseResult.scanFile);
             if (!ai.isFactory) {
                 newParseFlags &= ~ParsingPackageUtils.PARSE_IS_SYSTEM_DIR;
                 newScanFlags |= SCAN_NEW_INSTALL;
@@ -3580,7 +3539,7 @@
                     && errorCode != PackageManager.INSTALL_SUCCEEDED) {
                 logCriticalInfo(Log.WARN,
                         "Deleting invalid package at " + parseResult.scanFile);
-                mRemovePackageHelper.removeCodePathLI(parseResult.scanFile);
+                mRemovePackageHelper.removeCodePath(parseResult.scanFile);
             }
         }
     }
@@ -3616,11 +3575,13 @@
             mPm.mSettings.enableSystemPackageLPw(packageName);
 
             try {
-                final AndroidPackage newPkg = scanSystemPackageTracedLI(
-                        scanFile, reparseFlags, rescanFlags, null);
-                // We rescanned a stub, add it to the list of stubbed system packages
-                if (newPkg.isStub()) {
-                    stubSystemApps.add(packageName);
+                synchronized (mPm.mInstallLock) {
+                    final AndroidPackage newPkg = scanSystemPackageTracedLI(
+                            scanFile, reparseFlags, rescanFlags, null);
+                    // We rescanned a stub, add it to the list of stubbed system packages
+                    if (newPkg.isStub()) {
+                        stubSystemApps.add(packageName);
+                    }
                 }
             } catch (PackageManagerException e) {
                 Slog.e(TAG, "Failed to parse original system package: "
@@ -3633,7 +3594,7 @@
      *  Traces a package scan.
      *  @see #scanSystemPackageLI(File, int, int, UserHandle)
      */
-    @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
+    @GuardedBy("mPm.mInstallLock")
     public AndroidPackage scanSystemPackageTracedLI(File scanFile, final int parseFlags,
             int scanFlags, UserHandle user) throws PackageManagerException {
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
@@ -3648,7 +3609,7 @@
      *  Scans a package and returns the newly parsed package.
      *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
      */
-    @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
+    @GuardedBy("mPm.mInstallLock")
     private AndroidPackage scanSystemPackageLI(File scanFile, int parseFlags, int scanFlags,
             UserHandle user) throws PackageManagerException {
         if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
@@ -3682,7 +3643,7 @@
      * structures and the package is made available to the rest of the system.
      * <p>NOTE: The return value should be removed. It's the passed in package object.
      */
-    @GuardedBy({"mPm.mLock", "mPm.mInstallLock"})
+    @GuardedBy("mPm.mInstallLock")
     private AndroidPackage addForInitLI(ParsedPackage parsedPackage,
             @ParsingPackageUtils.ParseFlags int parseFlags,
             @PackageManagerService.ScanFlags int scanFlags,
@@ -3764,11 +3725,13 @@
         // iff we've acquired an app ID for a new package setting, remove it so that it can be
         // acquired by another request.
         if (result.mPkgSetting.getAppId() > 0) {
-            mPm.mSettings.removeAppIdLPw(result.mPkgSetting.getAppId());
+            synchronized (mPm.mLock) {
+                mPm.mSettings.removeAppIdLPw(result.mPkgSetting.getAppId());
+            }
         }
     }
 
-    @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
+    @GuardedBy("mPm.mInstallLock")
     private ScanResult scanPackageTracedLI(ParsedPackage parsedPackage,
             final @ParsingPackageUtils.ParseFlags int parseFlags,
             @PackageManagerService.ScanFlags int scanFlags, long currentTime,
@@ -3813,8 +3776,9 @@
                     parsedPackage.getPackageName());
 
             boolean ignoreSharedUserId = false;
-            if (installedPkgSetting == null) {
-                // We can directly ignore sharedUserSetting for new installs
+            if (installedPkgSetting == null || !installedPkgSetting.hasSharedUser()) {
+                // Directly ignore sharedUserSetting for new installs, or if the app has
+                // already left shared UID
                 ignoreSharedUserId = parsedPackage.isLeavingSharedUid();
             }
 
@@ -3849,7 +3813,7 @@
                 realPkgName, parseFlags, scanFlags, isPlatformPackage, user, cpuAbiOverride);
     }
 
-    @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
+    @GuardedBy("mPm.mInstallLock")
     private ScanResult scanPackageNewLI(@NonNull ParsedPackage parsedPackage,
             final @ParsingPackageUtils.ParseFlags int parseFlags,
             @PackageManagerService.ScanFlags int scanFlags, long currentTime,
@@ -3886,6 +3850,7 @@
         }
     }
 
+    @GuardedBy("mPm.mInstallLock")
     private Pair<ScanResult, Boolean> scanSystemPackageLI(ParsedPackage parsedPackage,
             @ParsingPackageUtils.ParseFlags int parseFlags,
             @PackageManagerService.ScanFlags int scanFlags,
@@ -3968,10 +3933,10 @@
                             + "; " + pkgSetting.getPathString()
                             + " --> " + parsedPackage.getPath());
 
-            final InstallArgs args = new FileInstallArgs(
+            final InstallArgs args = new InstallArgs(
                     pkgSetting.getPathString(), getAppDexInstructionSets(
                     pkgSetting.getPrimaryCpuAbi(), pkgSetting.getSecondaryCpuAbi()), mPm);
-            args.cleanUpResourcesLI();
+            mRemovePackageHelper.cleanUpResources(args);
             synchronized (mPm.mLock) {
                 mPm.mSettings.enableSystemPackageLPw(pkgSetting.getPackageName());
             }
@@ -4053,13 +4018,11 @@
                                 + parsedPackage.getLongVersionCode()
                                 + "; " + pkgSetting.getPathString() + " --> "
                                 + parsedPackage.getPath());
-                InstallArgs args = new FileInstallArgs(
+                InstallArgs args = new InstallArgs(
                         pkgSetting.getPathString(), getAppDexInstructionSets(
                         pkgSetting.getPrimaryCpuAbi(), pkgSetting.getSecondaryCpuAbi()),
                         mPm);
-                synchronized (mPm.mInstallLock) {
-                    args.cleanUpResourcesLI();
-                }
+                mRemovePackageHelper.cleanUpResources(args);
             } else {
                 // The application on /system is older than the application on /data. Hide
                 // the application on /system and the version on /data will be scanned later
@@ -4084,7 +4047,6 @@
      * Returns if forced apk verification can be skipped for the whole package, including splits.
      */
     private boolean canSkipForcedPackageVerification(AndroidPackage pkg) {
-        final String packageName = pkg.getPackageName();
         if (!VerityUtils.hasFsverity(pkg.getBaseApkPath())) {
             return false;
         }
@@ -4391,8 +4353,10 @@
             // signed with the platform certificate. Check this in increasing order of
             // computational cost.
             if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.Q) {
-                final PackageSetting platformPkgSetting =
-                        mPm.mSettings.getPackageLPr("android");
+                final PackageSetting platformPkgSetting;
+                synchronized (mPm.mLock) {
+                    platformPkgSetting = mPm.mSettings.getPackageLPr("android");
+                }
                 if (!comparePackageSignatures(platformPkgSetting,
                         pkg.getSigningDetails().getSignatures())) {
                     throw new PackageManagerException("Overlay "
@@ -4410,8 +4374,10 @@
             // SystemConfig is set, check this here to augment the last line of defense
             // which is OMS.
             if (pkg.getOverlayTargetOverlayableName() == null) {
-                final PackageSetting targetPkgSetting =
-                        mPm.mSettings.getPackageLPr(pkg.getOverlayTarget());
+                final PackageSetting targetPkgSetting;
+                synchronized (mPm.mLock) {
+                    targetPkgSetting = mPm.mSettings.getPackageLPr(pkg.getOverlayTarget());
+                }
                 if (targetPkgSetting != null) {
                     if (!comparePackageSignatures(targetPkgSetting,
                             pkg.getSigningDetails().getSignatures())) {
@@ -4423,9 +4389,11 @@
                                     + " different certificates, and the overlay lacks"
                                     + " <overlay android:targetName>");
                         }
-                        final PackageSetting refPkgSetting =
-                                mPm.mSettings.getPackageLPr(
-                                        mPm.mOverlayConfigSignaturePackage);
+                        final PackageSetting refPkgSetting;
+                        synchronized (mPm.mLock) {
+                            refPkgSetting = mPm.mSettings.getPackageLPr(
+                                    mPm.mOverlayConfigSignaturePackage);
+                        }
                         if (!comparePackageSignatures(refPkgSetting,
                                 pkg.getSigningDetails().getSignatures())) {
                             throw new PackageManagerException("Overlay "
@@ -4445,13 +4413,18 @@
         if (!pkg.isPrivileged() && (pkg.getSharedUserId() != null)) {
             SharedUserSetting sharedUserSetting = null;
             try {
-                sharedUserSetting = mPm.mSettings.getSharedUserLPw(pkg.getSharedUserId(),
-                        0, 0, false);
+                synchronized (mPm.mLock) {
+                    sharedUserSetting = mPm.mSettings.getSharedUserLPw(pkg.getSharedUserId(),
+                            0, 0, false);
+                }
             } catch (PackageManagerException ignore) {
             }
             if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
                 // Exempt SharedUsers signed with the platform key.
-                PackageSetting platformPkgSetting = mPm.mSettings.getPackageLPr("android");
+                final PackageSetting platformPkgSetting;
+                synchronized (mPm.mLock) {
+                    platformPkgSetting = mPm.mSettings.getPackageLPr("android");
+                }
                 if (!comparePackageSignatures(platformPkgSetting,
                         pkg.getSigningDetails().getSignatures())) {
                     throw new PackageManagerException("Apps that share a user with a "
diff --git a/services/core/java/com/android/server/pm/InstallingSession.java b/services/core/java/com/android/server/pm/InstallingSession.java
index b3e039e..0630ccd 100644
--- a/services/core/java/com/android/server/pm/InstallingSession.java
+++ b/services/core/java/com/android/server/pm/InstallingSession.java
@@ -17,17 +17,21 @@
 package com.android.server.pm;
 
 import static android.app.AppOpsManager.MODE_DEFAULT;
+import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
 import static android.content.pm.PackageManager.INSTALL_STAGED;
 import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
+import static android.os.incremental.IncrementalManager.isIncrementalPath;
 
+import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
 import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
 import static com.android.server.pm.PackageManagerService.DEBUG_INSTANT;
 import static com.android.server.pm.PackageManagerService.TAG;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.apex.ApexInfo;
 import android.content.pm.DataLoaderType;
 import android.content.pm.IPackageInstallObserver2;
 import android.content.pm.PackageInfoLite;
@@ -35,19 +39,28 @@
 import android.content.pm.PackageManager;
 import android.content.pm.SigningDetails;
 import android.content.pm.parsing.PackageLite;
+import android.os.Environment;
 import android.os.Trace;
 import android.os.UserHandle;
+import android.util.ArrayMap;
 import android.util.Pair;
 import android.util.Slog;
 
 import com.android.internal.content.F2fsUtils;
 import com.android.internal.content.InstallLocationUtils;
+import com.android.internal.content.NativeLibraryHelper;
 import com.android.internal.util.Preconditions;
+import com.android.server.pm.parsing.PackageParser2;
 import com.android.server.pm.parsing.pkg.AndroidPackage;
 
+import libcore.io.IoUtils;
+
 import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 class InstallingSession {
     final OriginInfo mOriginInfo;
@@ -79,6 +92,7 @@
     @NonNull
     final PackageManagerService mPm;
     final InstallPackageHelper mInstallPackageHelper;
+    final RemovePackageHelper mRemovePackageHelper;
 
     InstallingSession(OriginInfo originInfo, MoveInfo moveInfo, IPackageInstallObserver2 observer,
             int installFlags, InstallSource installSource, String volumeUuid,
@@ -87,6 +101,7 @@
         mPm = pm;
         mUser = user;
         mInstallPackageHelper = new InstallPackageHelper(mPm);
+        mRemovePackageHelper = new RemovePackageHelper(mPm);
         mOriginInfo = originInfo;
         mMoveInfo = moveInfo;
         mObserver = observer;
@@ -115,6 +130,7 @@
         mPm = pm;
         mUser = user;
         mInstallPackageHelper = new InstallPackageHelper(mPm);
+        mRemovePackageHelper = new RemovePackageHelper(mPm);
         mOriginInfo = OriginInfo.fromStagedFile(stagedDir);
         mMoveInfo = null;
         mInstallReason = fixUpInstallReason(
@@ -195,7 +211,7 @@
      * policy if needed and then create install arguments based
      * on the install location.
      */
-    public void handleStartCopy() {
+    private void handleStartCopy() {
         if ((mInstallFlags & PackageManager.INSTALL_APEX) != 0) {
             mRet = INSTALL_SUCCEEDED;
             return;
@@ -232,14 +248,14 @@
                 pkgLite.installLocation);
     }
 
-    void handleReturnCode() {
+    private void handleReturnCode() {
         processPendingInstall();
     }
 
     private void processPendingInstall() {
-        InstallArgs args = createInstallArgs(this);
+        InstallArgs args = new InstallArgs(this);
         if (mRet == PackageManager.INSTALL_SUCCEEDED) {
-            mRet = args.copyApk();
+            mRet = copyApk(args);
         }
         if (mRet == PackageManager.INSTALL_SUCCEEDED) {
             F2fsUtils.releaseCompressedBlocks(
@@ -250,20 +266,91 @@
         } else {
             PackageInstalledInfo res = new PackageInstalledInfo(mRet);
             // Queue up an async operation since the package installation may take a little while.
-            mPm.mHandler.post(() -> mInstallPackageHelper.processInstallRequests(
+            mPm.mHandler.post(() -> processInstallRequests(
                     res.mReturnCode == PackageManager.INSTALL_SUCCEEDED /* success */,
                     Collections.singletonList(new InstallRequest(args, res))));
         }
     }
 
-    private InstallArgs createInstallArgs(InstallingSession installingSession) {
-        if (installingSession.mMoveInfo != null) {
-            return new MoveInstallArgs(installingSession);
+    private int copyApk(InstallArgs args) {
+        if (mMoveInfo == null) {
+            return copyApkForFileInstall(args);
         } else {
-            return new FileInstallArgs(installingSession);
+            return copyApkForMoveInstall(args);
         }
     }
 
+    private int copyApkForFileInstall(InstallArgs args) {
+        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
+        try {
+            if (mOriginInfo.mStaged) {
+                if (DEBUG_INSTALL) {
+                    Slog.d(TAG, mOriginInfo.mFile + " already staged; skipping copy");
+                }
+                args.mCodeFile = mOriginInfo.mFile;
+                return PackageManager.INSTALL_SUCCEEDED;
+            }
+
+            try {
+                final boolean isEphemeral =
+                        (mInstallFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
+                args.mCodeFile =
+                        mPm.mInstallerService.allocateStageDirLegacy(mVolumeUuid, isEphemeral);
+            } catch (IOException e) {
+                Slog.w(TAG, "Failed to create copy file: " + e);
+                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
+            }
+
+            int ret = PackageManagerServiceUtils.copyPackage(
+                    mOriginInfo.mFile.getAbsolutePath(), args.mCodeFile);
+            if (ret != PackageManager.INSTALL_SUCCEEDED) {
+                Slog.e(TAG, "Failed to copy package");
+                return ret;
+            }
+
+            final boolean isIncremental = isIncrementalPath(args.mCodeFile.getAbsolutePath());
+            final File libraryRoot = new File(args.mCodeFile, LIB_DIR_NAME);
+            NativeLibraryHelper.Handle handle = null;
+            try {
+                handle = NativeLibraryHelper.Handle.create(args.mCodeFile);
+                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
+                        args.mAbiOverride, isIncremental);
+            } catch (IOException e) {
+                Slog.e(TAG, "Copying native libraries failed", e);
+                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+            } finally {
+                IoUtils.closeQuietly(handle);
+            }
+
+            return ret;
+        } finally {
+            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+        }
+    }
+
+    private int copyApkForMoveInstall(InstallArgs args) {
+        if (DEBUG_INSTALL) {
+            Slog.d(TAG, "Moving " + mMoveInfo.mPackageName + " from "
+                    + mMoveInfo.mFromUuid + " to " + mMoveInfo.mToUuid);
+        }
+        synchronized (mPm.mInstallLock) {
+            try {
+                mPm.mInstaller.moveCompleteApp(mMoveInfo.mFromUuid, mMoveInfo.mToUuid,
+                        mMoveInfo.mPackageName, mMoveInfo.mAppId, mMoveInfo.mSeInfo,
+                        mMoveInfo.mTargetSdkVersion, mMoveInfo.mFromCodePath);
+            } catch (Installer.InstallerException e) {
+                Slog.w(TAG, "Failed to move app", e);
+                return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+            }
+        }
+
+        final String toPathName = new File(mMoveInfo.mFromCodePath).getName();
+        args.mCodeFile = new File(Environment.getDataAppDirectory(mMoveInfo.mToUuid), toPathName);
+        if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + args.mCodeFile);
+
+        return PackageManager.INSTALL_SUCCEEDED;
+    }
+
     /**
      * Ensure that the install reason matches what we know about the package installer (e.g. whether
      * it is acting on behalf on an enterprise or the user).
@@ -368,4 +455,217 @@
     private void setTraceCookie(int traceCookie) {
         mTraceCookie = traceCookie;
     }
+
+    private void processInstallRequests(boolean success, List<InstallRequest> installRequests) {
+        List<InstallRequest> apexInstallRequests = new ArrayList<>();
+        List<InstallRequest> apkInstallRequests = new ArrayList<>();
+        for (InstallRequest request : installRequests) {
+            if ((request.mArgs.mInstallFlags & PackageManager.INSTALL_APEX) != 0) {
+                apexInstallRequests.add(request);
+            } else {
+                apkInstallRequests.add(request);
+            }
+        }
+        // Note: supporting multi package install of both APEXes and APKs might requir some
+        // thinking to ensure atomicity of the install.
+        if (!apexInstallRequests.isEmpty() && !apkInstallRequests.isEmpty()) {
+            // This should've been caught at the validation step, but for some reason wasn't.
+            throw new IllegalStateException(
+                    "Attempted to do a multi package install of both APEXes and APKs");
+        }
+        if (!apexInstallRequests.isEmpty()) {
+            if (success) {
+                // Since installApexPackages requires talking to external service (apexd), we
+                // schedule to run it async. Once it finishes, it will resume the install.
+                Thread t = new Thread(() -> installApexPackagesTraced(apexInstallRequests),
+                        "installApexPackages");
+                t.start();
+            } else {
+                // Non-staged APEX installation failed somewhere before
+                // processInstallRequestAsync. In that case just notify the observer about the
+                // failure.
+                InstallRequest request = apexInstallRequests.get(0);
+                mPm.notifyInstallObserver(request.mInstallResult, request.mArgs.mObserver);
+            }
+            return;
+        }
+
+        processApkInstallRequests(success, installRequests);
+    }
+
+    private void processApkInstallRequests(boolean success, List<InstallRequest> installRequests) {
+        if (success) {
+            for (InstallRequest request : installRequests) {
+                if (request.mInstallResult.mReturnCode != PackageManager.INSTALL_SUCCEEDED) {
+                    cleanUpForFailedInstall(request.mArgs);
+                }
+            }
+
+            mInstallPackageHelper.installPackagesTraced(installRequests);
+
+            for (InstallRequest request : installRequests) {
+                doPostInstall(request.mInstallResult.mReturnCode, request.mArgs);
+            }
+        }
+        for (InstallRequest request : installRequests) {
+            mInstallPackageHelper.restoreAndPostInstall(request.mArgs.mUser.getIdentifier(),
+                    request.mInstallResult,
+                    new PostInstallData(request.mArgs,
+                            request.mInstallResult, null));
+        }
+    }
+
+    private void doPostInstall(int status, InstallArgs args) {
+        if (mMoveInfo != null) {
+            if (status == PackageManager.INSTALL_SUCCEEDED) {
+                mRemovePackageHelper.cleanUpForMoveInstall(mMoveInfo.mFromUuid,
+                        mMoveInfo.mPackageName, mMoveInfo.mFromCodePath);
+            } else {
+                mRemovePackageHelper.cleanUpForMoveInstall(mMoveInfo.mToUuid,
+                        mMoveInfo.mPackageName, mMoveInfo.mFromCodePath);
+            }
+        } else {
+            if (status != PackageManager.INSTALL_SUCCEEDED) {
+                mRemovePackageHelper.removeCodePath(args.mCodeFile);
+            }
+        }
+    }
+
+    private void cleanUpForFailedInstall(InstallArgs args) {
+        if (args.mMoveInfo != null) {
+            mRemovePackageHelper.cleanUpForMoveInstall(args.mMoveInfo.mToUuid,
+                    args.mMoveInfo.mPackageName, args.mMoveInfo.mFromCodePath);
+        } else {
+            mRemovePackageHelper.removeCodePath(args.mCodeFile);
+        }
+    }
+
+    private void installApexPackagesTraced(List<InstallRequest> requests) {
+        try {
+            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installApexPackages");
+            installApexPackages(requests);
+        } finally {
+            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+        }
+    }
+
+    private void installApexPackages(List<InstallRequest> requests) {
+        if (requests.isEmpty()) {
+            return;
+        }
+        if (requests.size() != 1) {
+            throw new IllegalStateException(
+                    "Only a non-staged install of a single APEX is supported");
+        }
+        InstallRequest request = requests.get(0);
+        try {
+            // Should directory scanning logic be moved to ApexManager for better test coverage?
+            final File dir = request.mArgs.mOriginInfo.mResolvedFile;
+            final File[] apexes = dir.listFiles();
+            if (apexes == null) {
+                throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+                        dir.getAbsolutePath() + " is not a directory");
+            }
+            if (apexes.length != 1) {
+                throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+                        "Expected exactly one .apex file under " + dir.getAbsolutePath()
+                                + " got: " + apexes.length);
+            }
+            try (PackageParser2 packageParser = mPm.mInjector.getScanningPackageParser()) {
+                ApexInfo apexInfo = mPm.mApexManager.installPackage(apexes[0]);
+                if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
+                    // APEX has been handled successfully by apexd. Let's continue the install flow
+                    // so it will be scanned and registered with the system.
+                    // TODO(b/225756739): Improve atomicity of rebootless APEX install.
+                    // The newly installed APEX will not be reverted even if
+                    // processApkInstallRequests() fails. Need a way to keep info stored in apexd
+                    // and PMS in sync in the face of install failures.
+                    request.mInstallResult.mApexInfo = apexInfo;
+                    mPm.mHandler.post(() -> processApkInstallRequests(true, requests));
+                    return;
+                } else {
+                    mPm.mApexPackageInfo.notifyPackageInstalled(apexInfo, packageParser);
+                }
+            }
+        } catch (PackageManagerException e) {
+            request.mInstallResult.setError("APEX installation failed", e);
+        }
+        PackageManagerService.invalidatePackageInfoCache();
+        mPm.notifyInstallObserver(request.mInstallResult, request.mArgs.mObserver);
+    }
+
+    /**
+     * Container for a multi-package install which refers to all install sessions and args being
+     * committed together.
+     */
+    private class MultiPackageInstallingSession {
+        private final List<InstallingSession> mChildInstallingSessions;
+        private final Map<InstallArgs, Integer> mCurrentState;
+        @NonNull
+        final PackageManagerService mPm;
+        final UserHandle mUser;
+
+        MultiPackageInstallingSession(UserHandle user,
+                List<InstallingSession> childInstallingSessions,
+                PackageManagerService pm)
+                throws PackageManagerException {
+            if (childInstallingSessions.size() == 0) {
+                throw new PackageManagerException("No child sessions found!");
+            }
+            mPm = pm;
+            mUser = user;
+            mChildInstallingSessions = childInstallingSessions;
+            for (int i = 0; i < childInstallingSessions.size(); i++) {
+                final InstallingSession childInstallingSession = childInstallingSessions.get(i);
+                childInstallingSession.mParentInstallingSession = this;
+            }
+            this.mCurrentState = new ArrayMap<>(mChildInstallingSessions.size());
+        }
+
+        public void start() {
+            if (DEBUG_INSTALL) Slog.i(TAG, "start " + mUser + ": " + this);
+            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
+                    System.identityHashCode(this));
+            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "start");
+            for (InstallingSession childInstallingSession : mChildInstallingSessions) {
+                childInstallingSession.handleStartCopy();
+            }
+            for (InstallingSession childInstallingSession : mChildInstallingSessions) {
+                childInstallingSession.handleReturnCode();
+            }
+            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+        }
+
+        public void tryProcessInstallRequest(InstallArgs args, int currentStatus) {
+            mCurrentState.put(args, currentStatus);
+            if (mCurrentState.size() != mChildInstallingSessions.size()) {
+                return;
+            }
+            int completeStatus = PackageManager.INSTALL_SUCCEEDED;
+            for (Integer status : mCurrentState.values()) {
+                if (status == PackageManager.INSTALL_UNKNOWN) {
+                    return;
+                } else if (status != PackageManager.INSTALL_SUCCEEDED) {
+                    completeStatus = status;
+                    break;
+                }
+            }
+            final List<InstallRequest> installRequests = new ArrayList<>(mCurrentState.size());
+            for (Map.Entry<InstallArgs, Integer> entry : mCurrentState.entrySet()) {
+                installRequests.add(new InstallRequest(entry.getKey(),
+                        new PackageInstalledInfo(completeStatus)));
+            }
+            int finalCompleteStatus = completeStatus;
+            mPm.mHandler.post(() -> processInstallRequests(
+                    finalCompleteStatus == PackageManager.INSTALL_SUCCEEDED /* success */,
+                    installRequests));
+        }
+
+        @Override
+        public String toString() {
+            return "MultiPackageInstallingSession{" + Integer.toHexString(
+                    System.identityHashCode(this))
+                    + "}";
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/pm/InstantAppResolverConnection.java b/services/core/java/com/android/server/pm/InstantAppResolverConnection.java
index 4f75f04..b4c40e6 100644
--- a/services/core/java/com/android/server/pm/InstantAppResolverConnection.java
+++ b/services/core/java/com/android/server/pm/InstantAppResolverConnection.java
@@ -121,7 +121,7 @@
             public void sendResult(Bundle data) throws RemoteException {
                 final ArrayList<InstantAppResolveInfo> resolveList =
                         data.getParcelableArrayList(
-                                InstantAppResolverService.EXTRA_RESOLVE_INFO);
+                                InstantAppResolverService.EXTRA_RESOLVE_INFO, android.content.pm.InstantAppResolveInfo.class);
                 callbackHandler.post(() -> callback.onPhaseTwoResolved(resolveList, startTime));
             }
         };
@@ -343,7 +343,7 @@
                     public void sendResult(Bundle data) throws RemoteException {
                         final ArrayList<InstantAppResolveInfo> resolveList =
                                 data.getParcelableArrayList(
-                                        InstantAppResolverService.EXTRA_RESOLVE_INFO);
+                                        InstantAppResolverService.EXTRA_RESOLVE_INFO, android.content.pm.InstantAppResolveInfo.class);
                         int sequence =
                                 data.getInt(InstantAppResolverService.EXTRA_SEQUENCE, -1);
                         onRemoteMethodResult(resolveList, sequence);
diff --git a/services/core/java/com/android/server/pm/MoveInstallArgs.java b/services/core/java/com/android/server/pm/MoveInstallArgs.java
deleted file mode 100644
index 1f167ce..0000000
--- a/services/core/java/com/android/server/pm/MoveInstallArgs.java
+++ /dev/null
@@ -1,133 +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 com.android.server.pm;
-
-import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
-import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
-
-import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
-import static com.android.server.pm.PackageManagerService.TAG;
-
-import android.content.pm.PackageManager;
-import android.os.Environment;
-import android.util.Slog;
-
-import com.android.server.pm.parsing.pkg.ParsedPackage;
-
-import java.io.File;
-
-/**
- * Logic to handle movement of existing installed applications.
- */
-final class MoveInstallArgs extends InstallArgs {
-    private File mCodeFile;
-
-    /** New install */
-    MoveInstallArgs(InstallingSession params) {
-        super(params);
-    }
-
-    int copyApk() {
-        if (DEBUG_INSTALL) {
-            Slog.d(TAG, "Moving " + mMoveInfo.mPackageName + " from "
-                    + mMoveInfo.mFromUuid + " to " + mMoveInfo.mToUuid);
-        }
-        synchronized (mPm.mInstaller) {
-            try {
-                mPm.mInstaller.moveCompleteApp(mMoveInfo.mFromUuid, mMoveInfo.mToUuid,
-                        mMoveInfo.mPackageName, mMoveInfo.mAppId, mMoveInfo.mSeInfo,
-                        mMoveInfo.mTargetSdkVersion, mMoveInfo.mFromCodePath);
-            } catch (Installer.InstallerException e) {
-                Slog.w(TAG, "Failed to move app", e);
-                return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
-            }
-        }
-
-        final String toPathName = new File(mMoveInfo.mFromCodePath).getName();
-        mCodeFile = new File(Environment.getDataAppDirectory(mMoveInfo.mToUuid), toPathName);
-        if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + mCodeFile);
-
-        return PackageManager.INSTALL_SUCCEEDED;
-    }
-
-    int doPreInstall(int status) {
-        if (status != PackageManager.INSTALL_SUCCEEDED) {
-            cleanUp(mMoveInfo.mToUuid);
-        }
-        return status;
-    }
-
-    @Override
-    boolean doRename(int status, ParsedPackage parsedPackage) {
-        if (status != PackageManager.INSTALL_SUCCEEDED) {
-            cleanUp(mMoveInfo.mToUuid);
-            return false;
-        }
-
-        return true;
-    }
-
-    int doPostInstall(int status, int uid) {
-        if (status == PackageManager.INSTALL_SUCCEEDED) {
-            cleanUp(mMoveInfo.mFromUuid);
-        } else {
-            cleanUp(mMoveInfo.mToUuid);
-        }
-        return status;
-    }
-
-    @Override
-    String getCodePath() {
-        return (mCodeFile != null) ? mCodeFile.getAbsolutePath() : null;
-    }
-
-    private void cleanUp(String volumeUuid) {
-        final String toPathName = new File(mMoveInfo.mFromCodePath).getName();
-        final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
-                toPathName);
-        Slog.d(TAG, "Cleaning up " + mMoveInfo.mPackageName + " on " + volumeUuid);
-        final int[] userIds = mPm.mUserManager.getUserIds();
-        synchronized (mPm.mInstallLock) {
-            // Clean up both app data and code
-            // All package moves are frozen until finished
-
-            // We purposefully exclude FLAG_STORAGE_EXTERNAL here, since
-            // this task was only focused on moving data on internal storage.
-            // We don't want ART profiles cleared, because they don't move,
-            // so we would be deleting the only copy (b/149200535).
-            final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE
-                    | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES;
-            for (int userId : userIds) {
-                try {
-                    mPm.mInstaller.destroyAppData(volumeUuid, mMoveInfo.mPackageName, userId, flags,
-                            0);
-                } catch (Installer.InstallerException e) {
-                    Slog.w(TAG, String.valueOf(e));
-                }
-            }
-            mRemovePackageHelper.removeCodePathLI(codeFile);
-        }
-    }
-
-    void cleanUpResourcesLI() {
-        throw new UnsupportedOperationException();
-    }
-
-    boolean doPostDeleteLI(boolean delete) {
-        throw new UnsupportedOperationException();
-    }
-}
diff --git a/services/core/java/com/android/server/pm/MultiPackageInstallingSession.java b/services/core/java/com/android/server/pm/MultiPackageInstallingSession.java
deleted file mode 100644
index e5ed5d8..0000000
--- a/services/core/java/com/android/server/pm/MultiPackageInstallingSession.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.pm;
-
-import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
-
-import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
-import static com.android.server.pm.PackageManagerService.TAG;
-
-import android.annotation.NonNull;
-import android.content.pm.PackageManager;
-import android.os.Trace;
-import android.os.UserHandle;
-import android.util.ArrayMap;
-import android.util.Slog;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Container for a multi-package install which refers to all install sessions and args being
- * committed together.
- */
-final class MultiPackageInstallingSession {
-    private final List<InstallingSession> mChildInstallingSessions;
-    private final Map<InstallArgs, Integer> mCurrentState;
-    @NonNull
-    final PackageManagerService mPm;
-    final UserHandle mUser;
-
-    MultiPackageInstallingSession(UserHandle user, List<InstallingSession> childInstallingSessions,
-            PackageManagerService pm)
-            throws PackageManagerException {
-        if (childInstallingSessions.size() == 0) {
-            throw new PackageManagerException("No child sessions found!");
-        }
-        mPm = pm;
-        mUser = user;
-        mChildInstallingSessions = childInstallingSessions;
-        for (int i = 0; i < childInstallingSessions.size(); i++) {
-            final InstallingSession childInstallingSession = childInstallingSessions.get(i);
-            childInstallingSession.mParentInstallingSession = this;
-        }
-        this.mCurrentState = new ArrayMap<>(mChildInstallingSessions.size());
-    }
-
-    public void start() {
-        if (DEBUG_INSTALL) Slog.i(TAG, "start " + mUser + ": " + this);
-        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
-                System.identityHashCode(this));
-        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "start");
-        for (InstallingSession childInstallingSession : mChildInstallingSessions) {
-            childInstallingSession.handleStartCopy();
-        }
-        for (InstallingSession childInstallingSession : mChildInstallingSessions) {
-            childInstallingSession.handleReturnCode();
-        }
-        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-    }
-
-    public void tryProcessInstallRequest(InstallArgs args, int currentStatus) {
-        mCurrentState.put(args, currentStatus);
-        if (mCurrentState.size() != mChildInstallingSessions.size()) {
-            return;
-        }
-        int completeStatus = PackageManager.INSTALL_SUCCEEDED;
-        for (Integer status : mCurrentState.values()) {
-            if (status == PackageManager.INSTALL_UNKNOWN) {
-                return;
-            } else if (status != PackageManager.INSTALL_SUCCEEDED) {
-                completeStatus = status;
-                break;
-            }
-        }
-        final List<InstallRequest> installRequests = new ArrayList<>(mCurrentState.size());
-        for (Map.Entry<InstallArgs, Integer> entry : mCurrentState.entrySet()) {
-            installRequests.add(new InstallRequest(entry.getKey(),
-                    new PackageInstalledInfo(completeStatus)));
-        }
-        int finalCompleteStatus = completeStatus;
-        final InstallPackageHelper installPackageHelper = new InstallPackageHelper(mPm);
-        mPm.mHandler.post(() -> installPackageHelper.processInstallRequests(
-                finalCompleteStatus == PackageManager.INSTALL_SUCCEEDED /* success */,
-                installRequests));
-    }
-
-    @Override
-    public String toString() {
-        return "MultiPackageInstallingSession{" + Integer.toHexString(System.identityHashCode(this))
-                + "}";
-    }
-}
diff --git a/services/core/java/com/android/server/pm/PackageHandler.java b/services/core/java/com/android/server/pm/PackageHandler.java
index c950dcfc..d50e55e 100644
--- a/services/core/java/com/android/server/pm/PackageHandler.java
+++ b/services/core/java/com/android/server/pm/PackageHandler.java
@@ -62,11 +62,13 @@
 final class PackageHandler extends Handler {
     private final PackageManagerService mPm;
     private final InstallPackageHelper mInstallPackageHelper;
+    private final RemovePackageHelper mRemovePackageHelper;
 
     PackageHandler(Looper looper, PackageManagerService pm) {
         super(looper);
         mPm = pm;
         mInstallPackageHelper = new InstallPackageHelper(mPm);
+        mRemovePackageHelper = new RemovePackageHelper(mPm);
     }
 
     @Override
@@ -107,11 +109,9 @@
                 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
             } break;
             case DEFERRED_NO_KILL_POST_DELETE: {
-                synchronized (mPm.mInstallLock) {
-                    InstallArgs args = (InstallArgs) msg.obj;
-                    if (args != null) {
-                        args.doPostDeleteLI(true);
-                    }
+                InstallArgs args = (InstallArgs) msg.obj;
+                if (args != null) {
+                    mRemovePackageHelper.cleanUpResources(args);
                 }
             } break;
             case DEFERRED_NO_KILL_INSTALL_OBSERVER:
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index bb23d89d..6ee43a0 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -379,9 +379,7 @@
         // Clean up orphaned staging directories
         for (File stage : stagingDirsToRemove) {
             Slog.w(TAG, "Deleting orphan stage " + stage);
-            synchronized (mPm.mInstallLock) {
-                removePackageHelper.removeCodePathLI(stage);
-            }
+            removePackageHelper.removeCodePath(stage);
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a909977..3f052c0 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -201,7 +201,6 @@
 import com.android.server.pm.dex.ArtUtils;
 import com.android.server.pm.dex.DexManager;
 import com.android.server.pm.dex.ViewCompiler;
-import com.android.server.pm.parsing.PackageCacher;
 import com.android.server.pm.parsing.PackageInfoUtils;
 import com.android.server.pm.parsing.PackageParser2;
 import com.android.server.pm.parsing.pkg.AndroidPackage;
@@ -6175,26 +6174,6 @@
         }
 
         @Override
-        public void pruneCachedApksInApex(@NonNull List<String> apexPackageNames) {
-            if (mCacheDir == null) {
-                return;
-            }
-
-            final PackageCacher cacher = new PackageCacher(mCacheDir);
-            synchronized (mLock) {
-                final Computer snapshot = snapshot();
-                for (int i = 0, size = apexPackageNames.size(); i < size; i++) {
-                    final List<String> apkNames =
-                            mApexManager.getApksInApex(apexPackageNames.get(i));
-                    for (int j = 0, apksInApex = apkNames.size(); j < apksInApex; j++) {
-                        final AndroidPackage pkg = snapshot.getPackage(apkNames.get(j));
-                        cacher.cleanCachedResult(new File(pkg.getPath()));
-                    }
-                }
-            }
-        }
-
-        @Override
         public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
             if (policy != null) {
                 mExternalSourcesPolicy = policy;
diff --git a/services/core/java/com/android/server/pm/PackageSessionVerifier.java b/services/core/java/com/android/server/pm/PackageSessionVerifier.java
index 731a1a5..28a021b 100644
--- a/services/core/java/com/android/server/pm/PackageSessionVerifier.java
+++ b/services/core/java/com/android/server/pm/PackageSessionVerifier.java
@@ -25,7 +25,6 @@
 import android.content.pm.IPackageInstallObserver2;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
 import android.content.pm.SigningDetails;
 import android.content.pm.parsing.result.ParseResult;
 import android.content.pm.parsing.result.ParseTypeImpl;
@@ -325,10 +324,7 @@
         // APEX checks. For single-package sessions, check if they contain an APEX. For
         // multi-package sessions, find all the child sessions that contain an APEX.
         if (hasApex) {
-            final List<String> apexPackageNames = submitSessionToApexService(session, rollbackId);
-            final PackageManagerInternal packageManagerInternal =
-                    LocalServices.getService(PackageManagerInternal.class);
-            packageManagerInternal.pruneCachedApksInApex(apexPackageNames);
+            submitSessionToApexService(session, rollbackId);
         }
     }
 
@@ -372,7 +368,7 @@
         }
     }
 
-    private List<String> submitSessionToApexService(StagingManager.StagedSession session,
+    private void submitSessionToApexService(StagingManager.StagedSession session,
             int rollbackId) throws PackageManagerException {
         final IntArray childSessionIds = new IntArray();
         if (session.isMultiPackage()) {
@@ -412,7 +408,6 @@
         }
         Slog.d(TAG, "Session " + session.sessionId() + " has following APEX packages: "
                 + apexPackageNames);
-        return apexPackageNames;
     }
 
     private int retrieveRollbackIdForCommitSession(int sessionId) throws PackageManagerException {
diff --git a/services/core/java/com/android/server/pm/ReconciledPackage.java b/services/core/java/com/android/server/pm/ReconciledPackage.java
index bd63a1a..1bfe357 100644
--- a/services/core/java/com/android/server/pm/ReconciledPackage.java
+++ b/services/core/java/com/android/server/pm/ReconciledPackage.java
@@ -16,6 +16,7 @@
 
 package com.android.server.pm;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.pm.SharedLibraryInfo;
 import android.content.pm.SigningDetails;
@@ -75,7 +76,7 @@
      * with the package(s) currently being installed. The to-be installed packages take
      * precedence and may shadow already installed packages.
      */
-    Map<String, AndroidPackage> getCombinedAvailablePackages() {
+    @NonNull Map<String, AndroidPackage> getCombinedAvailablePackages() {
         final ArrayMap<String, AndroidPackage> combined =
                 new ArrayMap<>(mRequest.mAllPackages.size() + mRequest.mScannedPackages.size());
 
diff --git a/services/core/java/com/android/server/pm/RemovePackageHelper.java b/services/core/java/com/android/server/pm/RemovePackageHelper.java
index 65d3430..f083b67 100644
--- a/services/core/java/com/android/server/pm/RemovePackageHelper.java
+++ b/services/core/java/com/android/server/pm/RemovePackageHelper.java
@@ -23,6 +23,7 @@
 import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
 import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL;
 
+import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
 import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
 import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
 import static com.android.server.pm.PackageManagerService.RANDOM_DIR_PREFIX;
@@ -30,6 +31,11 @@
 
 import android.annotation.NonNull;
 import android.content.pm.PackageManager;
+import android.content.pm.parsing.ApkLiteParseUtils;
+import android.content.pm.parsing.PackageLite;
+import android.content.pm.parsing.result.ParseResult;
+import android.content.pm.parsing.result.ParseTypeImpl;
+import android.os.Environment;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.incremental.IncrementalManager;
@@ -78,8 +84,17 @@
         this(pm, new AppDataHelper(pm));
     }
 
+    public void removeCodePath(File codePath) {
+        synchronized (mPm.mInstallLock) {
+            removeCodePathLI(codePath);
+        }
+    }
+
     @GuardedBy("mPm.mInstallLock")
-    public void removeCodePathLI(File codePath) {
+    private void removeCodePathLI(File codePath) {
+        if (codePath == null || !codePath.exists()) {
+            return;
+        }
         if (codePath.isDirectory()) {
             final File codePathParent = codePath.getParentFile();
             final boolean needRemoveParent = codePathParent.getName().startsWith(RANDOM_DIR_PREFIX);
@@ -118,7 +133,14 @@
         cacher.cleanCachedResult(codePath);
     }
 
-    public void removePackageLI(AndroidPackage pkg, boolean chatty) {
+    public void removePackage(AndroidPackage pkg, boolean chatty) {
+        synchronized (mPm.mInstallLock) {
+            removePackageLI(pkg, chatty);
+        }
+    }
+
+    @GuardedBy("mPm.mInstallLock")
+    private void removePackageLI(AndroidPackage pkg, boolean chatty) {
         // Remove the parent package setting
         PackageStateInternal ps = mPm.snapshotComputer()
                 .getPackageStateInternal(pkg.getPackageName());
@@ -129,6 +151,7 @@
         }
     }
 
+    @GuardedBy("mPm.mInstallLock")
     private void removePackageLI(String packageName, boolean chatty) {
         if (DEBUG_INSTALL) {
             if (chatty) {
@@ -145,6 +168,7 @@
         }
     }
 
+    @GuardedBy("mPm.mLock")
     private void cleanPackageDataStructuresLILPw(AndroidPackage pkg, boolean chatty) {
         mPm.mComponentResolver.removeAllComponents(pkg, chatty);
         mPermissionManager.onPackageRemoved(pkg);
@@ -175,7 +199,7 @@
             final int libraryNamesSize = pkg.getLibraryNames().size();
             for (i = 0; i < libraryNamesSize; i++) {
                 String name = pkg.getLibraryNames().get(i);
-                if (mSharedLibraries.removeSharedLibraryLPw(name, 0)) {
+                if (mSharedLibraries.removeSharedLibrary(name, 0)) {
                     if (DEBUG_REMOVE && chatty) {
                         if (r == null) {
                             r = new StringBuilder(256);
@@ -192,7 +216,7 @@
 
         // Any package can hold SDK or static shared libraries.
         if (pkg.getSdkLibName() != null) {
-            if (mSharedLibraries.removeSharedLibraryLPw(
+            if (mSharedLibraries.removeSharedLibrary(
                     pkg.getSdkLibName(), pkg.getSdkLibVersionMajor())) {
                 if (DEBUG_REMOVE && chatty) {
                     if (r == null) {
@@ -205,7 +229,7 @@
             }
         }
         if (pkg.getStaticSharedLibName() != null) {
-            if (mSharedLibraries.removeSharedLibraryLPw(pkg.getStaticSharedLibName(),
+            if (mSharedLibraries.removeSharedLibrary(pkg.getStaticSharedLibName(),
                     pkg.getStaticSharedLibVersion())) {
                 if (DEBUG_REMOVE && chatty) {
                     if (r == null) {
@@ -223,12 +247,20 @@
         }
     }
 
+    public void removePackageData(final PackageSetting deletedPs, @NonNull int[] allUserHandles,
+            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
+        synchronized (mPm.mInstallLock) {
+            removePackageDataLIF(deletedPs, allUserHandles, outInfo, flags, writeSettings);
+        }
+    }
+
     /*
      * This method deletes the package from internal data structures. If the DELETE_KEEP_DATA
      * flag is not set, the data directory is removed as well.
      * make sure this flag is set for partially installed apps. If not its meaningless to
      * delete a partially installed application.
      */
+    @GuardedBy("mPm.mInstallLock")
     public void removePackageDataLIF(final PackageSetting deletedPs, @NonNull int[] allUserHandles,
             PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
         String packageName = deletedPs.getPackageName();
@@ -352,4 +384,74 @@
             });
         }
     }
+
+    void cleanUpResources(InstallArgs args) {
+        synchronized (mPm.mInstallLock) {
+            cleanUpResourcesLI(args);
+        }
+    }
+
+    // Need installer lock especially for dex file removal.
+    @GuardedBy("mPm.mInstallLock")
+    private void cleanUpResourcesLI(InstallArgs args) {
+        // Try enumerating all code paths before deleting
+        List<String> allCodePaths = Collections.EMPTY_LIST;
+        if (args.mCodeFile != null && args.mCodeFile.exists()) {
+            final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
+            final ParseResult<PackageLite> result = ApkLiteParseUtils.parsePackageLite(
+                    input.reset(), args.mCodeFile, /* flags */ 0);
+            if (result.isSuccess()) {
+                // Ignore error; we tried our best
+                allCodePaths = result.getResult().getAllApkPaths();
+            }
+        }
+
+        removeCodePathLI(args.mCodeFile);
+        removeDexFilesLI(allCodePaths, args.mInstructionSets);
+    }
+
+    @GuardedBy("mPm.mInstallLock")
+    private void removeDexFilesLI(List<String> allCodePaths, String[] instructionSets) {
+        if (!allCodePaths.isEmpty()) {
+            if (instructionSets == null) {
+                throw new IllegalStateException("instructionSet == null");
+            }
+            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
+            for (String codePath : allCodePaths) {
+                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
+                    try {
+                        mPm.mInstaller.rmdex(codePath, dexCodeInstructionSet);
+                    } catch (Installer.InstallerException ignored) {
+                    }
+                }
+            }
+        }
+    }
+
+    void cleanUpForMoveInstall(String volumeUuid, String packageName, String fromCodePath) {
+        final String toPathName = new File(fromCodePath).getName();
+        final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), toPathName);
+        Slog.d(TAG, "Cleaning up " + packageName + " on " + volumeUuid);
+        final int[] userIds = mPm.mUserManager.getUserIds();
+        synchronized (mPm.mInstallLock) {
+            // Clean up both app data and code
+            // All package moves are frozen until finished
+
+            // We purposefully exclude FLAG_STORAGE_EXTERNAL here, since
+            // this task was only focused on moving data on internal storage.
+            // We don't want ART profiles cleared, because they don't move,
+            // so we would be deleting the only copy (b/149200535).
+            final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE
+                    | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES;
+            for (int userId : userIds) {
+                try {
+                    mPm.mInstaller.destroyAppData(volumeUuid, packageName, userId, flags,
+                            0);
+                } catch (Installer.InstallerException e) {
+                    Slog.w(TAG, String.valueOf(e));
+                }
+            }
+            removeCodePathLI(codeFile);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/pm/ScanPackageUtils.java b/services/core/java/com/android/server/pm/ScanPackageUtils.java
index fe160e3..0e57c91 100644
--- a/services/core/java/com/android/server/pm/ScanPackageUtils.java
+++ b/services/core/java/com/android/server/pm/ScanPackageUtils.java
@@ -428,8 +428,7 @@
         pkgSetting.setLastModifiedTime(scanFileTime);
         // TODO(b/135203078): Remove, move to constructor
         pkgSetting.setPkg(parsedPackage)
-                .setFlags(PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting))
-                .setPrivateFlags(
+                .setPkgFlags(PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting),
                         PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting));
         if (parsedPackage.getLongVersionCode() != pkgSetting.getVersionCode()) {
             pkgSetting.setLongVersionCode(parsedPackage.getLongVersionCode());
diff --git a/services/core/java/com/android/server/pm/SettingBase.java b/services/core/java/com/android/server/pm/SettingBase.java
index b952f80..61a251e 100644
--- a/services/core/java/com/android/server/pm/SettingBase.java
+++ b/services/core/java/com/android/server/pm/SettingBase.java
@@ -146,6 +146,17 @@
         return this;
     }
 
+    /**
+     * Unconditionally set both mPkgFlags and mPkgPrivateFlags.
+     * Should not be used outside pkgSetting initialization or update.
+     */
+    SettingBase setPkgFlags(int flags, int privateFlags) {
+        this.mPkgFlags = flags;
+        this.mPkgPrivateFlags = privateFlags;
+        onChanged();
+        return this;
+    }
+
     public int getFlags() {
         return mPkgFlags;
     }
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 138915d..c064324 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -987,8 +987,7 @@
                     // Update new package state.
                     .setLastModifiedTime(codePath.lastModified())
                     .setDomainSetId(domainSetId);
-            pkgSetting.setFlags(pkgFlags)
-                    .setPrivateFlags(pkgPrivateFlags);
+            pkgSetting.setPkgFlags(pkgFlags, pkgPrivateFlags);
         } else {
             pkgSetting = new PackageSetting(pkgName, realPkgName, codePath,
                     legacyNativeLibraryPath, primaryCpuAbi, secondaryCpuAbi,
@@ -1175,15 +1174,15 @@
                     .setUsesStaticLibrariesVersions(null);
         }
 
-        // These two flags are preserved from the existing PackageSetting. Copied from prior code,
-        // unclear if this is actually necessary.
-        boolean wasExternalStorage = (pkgSetting.getFlags()
-                & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
-        if (wasExternalStorage) {
-            pkgFlags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
-        } else {
-            pkgFlags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE;
-        }
+        // If what we are scanning is a system (and possibly privileged) package,
+        // then make it so, regardless of whether it was previously installed only
+        // in the data partition. Reset first.
+        int newPkgFlags = pkgSetting.getFlags();
+        newPkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
+        newPkgFlags |= pkgFlags & ApplicationInfo.FLAG_SYSTEM;
+        // Only set pkgFlags.
+        pkgSetting.setPkgFlags(newPkgFlags, pkgSetting.getPrivateFlags());
+
         boolean wasRequiredForSystemUser = (pkgSetting.getPrivateFlags()
                 & ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER) != 0;
         if (wasRequiredForSystemUser) {
@@ -1191,9 +1190,7 @@
         } else {
             pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
         }
-
-        pkgSetting.setFlags(pkgFlags)
-                .setPrivateFlags(pkgPrivateFlags);
+        pkgSetting.setPrivateFlags(pkgPrivateFlags);
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/SharedLibrariesImpl.java b/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
index 479a404..7432b84 100644
--- a/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
+++ b/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
@@ -19,6 +19,7 @@
 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
 
 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
+import static com.android.server.pm.PackageManagerService.SCAN_BOOTING;
 import static com.android.server.pm.PackageManagerService.TAG;
 
 import android.annotation.NonNull;
@@ -258,11 +259,13 @@
      * Given the library name, returns a list of shared libraries on all versions.
      * TODO: Remove, this is used for live mutation outside of the defined commit path
      */
-    @GuardedBy("mPm.mLock")
+
     @Override
     public @NonNull WatchedLongSparseArray<SharedLibraryInfo> getSharedLibraryInfos(
             @NonNull String libName) {
-        return mSharedLibraries.get(libName);
+        synchronized (mPm.mLock) {
+            return mSharedLibraries.get(libName);
+        }
     }
 
     @VisibleForTesting
@@ -381,6 +384,11 @@
         return false;
     }
 
+    @Nullable SharedLibraryInfo getLatestStaticSharedLibraVersion(@NonNull AndroidPackage pkg) {
+        synchronized (mPm.mLock) {
+            return getLatestStaticSharedLibraVersionLPr(pkg);
+        }
+    }
     /**
      * Given a package of static shared library, returns its shared library info of
      * the latest version.
@@ -389,7 +397,8 @@
      * @return The latest version of shared library info.
      */
     @GuardedBy("mPm.mLock")
-    @Nullable SharedLibraryInfo getLatestStaticSharedLibraVersionLPr(@NonNull AndroidPackage pkg) {
+    @Nullable
+    private SharedLibraryInfo getLatestStaticSharedLibraVersionLPr(@NonNull AndroidPackage pkg) {
         WatchedLongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(
                 pkg.getStaticSharedLibName());
         if (versionedLib == null) {
@@ -524,15 +533,26 @@
      * @param changingLibSetting The updating library package setting.
      * @param availablePackages All installed packages and current being installed packages.
      */
-    @GuardedBy("mPm.mLock")
-    void updateSharedLibrariesLPw(@NonNull AndroidPackage pkg, @NonNull PackageSetting pkgSetting,
+    void updateSharedLibraries(@NonNull AndroidPackage pkg, @NonNull PackageSetting pkgSetting,
             @Nullable AndroidPackage changingLib, @Nullable PackageSetting changingLibSetting,
             @NonNull Map<String, AndroidPackage> availablePackages)
             throws PackageManagerException {
         final ArrayList<SharedLibraryInfo> sharedLibraryInfos = collectSharedLibraryInfos(
                 pkg, availablePackages, null /* newLibraries */);
-        executeSharedLibrariesUpdateLPw(pkg, pkgSetting, changingLib, changingLibSetting,
-                sharedLibraryInfos, mPm.mUserManager.getUserIds());
+        synchronized (mPm.mLock) {
+            executeSharedLibrariesUpdateLPw(pkg, pkgSetting, changingLib, changingLibSetting,
+                    sharedLibraryInfos, mPm.mUserManager.getUserIds());
+        }
+    }
+
+    void executeSharedLibrariesUpdate(AndroidPackage pkg,
+            @NonNull PackageSetting pkgSetting, @Nullable AndroidPackage changingLib,
+            @Nullable PackageSetting changingLibSetting,
+            ArrayList<SharedLibraryInfo> usesLibraryInfos, int[] allUsers) {
+        synchronized (mPm.mLock) {
+            executeSharedLibrariesUpdateLPw(pkg, pkgSetting, changingLib, changingLibSetting,
+                    usesLibraryInfos, allUsers);
+        }
     }
 
     /**
@@ -547,7 +567,7 @@
      * @param allUsers All user ids on the device.
      */
     @GuardedBy("mPm.mLock")
-    void executeSharedLibrariesUpdateLPw(AndroidPackage pkg,
+    private void executeSharedLibrariesUpdateLPw(AndroidPackage pkg,
             @NonNull PackageSetting pkgSetting, @Nullable AndroidPackage changingLib,
             @Nullable PackageSetting changingLibSetting,
             ArrayList<SharedLibraryInfo> usesLibraryInfos, int[] allUsers) {
@@ -610,6 +630,31 @@
         return false;
     }
 
+    ArrayList<AndroidPackage> commitSharedLibraryChanges(@NonNull AndroidPackage pkg,
+            @NonNull PackageSetting pkgSetting, List<SharedLibraryInfo> allowedSharedLibraryInfos,
+            @NonNull Map<String, AndroidPackage> combinedSigningDetails, int scanFlags) {
+        if (ArrayUtils.isEmpty(allowedSharedLibraryInfos)) {
+            return null;
+        }
+        synchronized (mPm.mLock) {
+            for (SharedLibraryInfo info : allowedSharedLibraryInfos) {
+                commitSharedLibraryInfoLPw(info);
+            }
+            try {
+                // Shared libraries for the package need to be updated.
+                updateSharedLibraries(pkg, pkgSetting, null, null, combinedSigningDetails);
+            } catch (PackageManagerException e) {
+                Slog.e(TAG, "updateSharedLibraries failed: ", e);
+            }
+            // Update all applications that use this library. Skip when booting
+            // since this will be done after all packages are scaned.
+            if ((scanFlags & SCAN_BOOTING) == 0) {
+                return updateAllSharedLibrariesLPw(pkg, pkgSetting, combinedSigningDetails);
+            }
+        }
+        return null;
+    }
+
     /**
      * Update shared library dependencies and code paths for applications that are using the
      * library {@code updatedPkg}. Update all applications if the {@code updatedPkg} is null.
@@ -666,7 +711,7 @@
                     }
                 }
                 try {
-                    updateSharedLibrariesLPw(pkg, pkgSetting, changingPkg,
+                    updateSharedLibraries(pkg, pkgSetting, changingPkg,
                             changingPkgSetting, availablePackages);
                 } catch (PackageManagerException e) {
                     // If a system app update or an app and a required lib missing we
@@ -677,9 +722,11 @@
                     if (!pkg.isSystem() || pkgSetting.getPkgState().isUpdatedSystemApp()) {
                         final int flags = pkgSetting.getPkgState().isUpdatedSystemApp()
                                 ? PackageManager.DELETE_KEEP_DATA : 0;
-                        mDeletePackageHelper.deletePackageLIF(pkg.getPackageName(), null, true,
-                                mPm.mUserManager.getUserIds(), flags, null,
-                                true);
+                        synchronized (mPm.mInstallLock) {
+                            mDeletePackageHelper.deletePackageLIF(pkg.getPackageName(), null, true,
+                                    mPm.mUserManager.getUserIds(), flags, null,
+                                    true);
+                        }
                     }
                     Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
                 }
@@ -711,6 +758,7 @@
      * Add a shared library info to the system. This is invoked when the package is being added or
      * scanned.
      */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
     @GuardedBy("mPm.mLock")
     void commitSharedLibraryInfoLPw(@NonNull SharedLibraryInfo libraryInfo) {
         final String name = libraryInfo.getName();
@@ -729,45 +777,46 @@
     /**
      * Remove a shared library from the system.
      */
-    @GuardedBy("mPm.mLock")
-    boolean removeSharedLibraryLPw(@NonNull String libName, long version) {
-        WatchedLongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(libName);
-        if (versionedLib == null) {
-            return false;
-        }
-        final int libIdx = versionedLib.indexOfKey(version);
-        if (libIdx < 0) {
-            return false;
-        }
-        SharedLibraryInfo libraryInfo = versionedLib.valueAt(libIdx);
-
-        final Computer snapshot = mPm.snapshotComputer();
-
-        // Remove the shared library overlays from its dependent packages.
-        for (int currentUserId : mPm.mUserManager.getUserIds()) {
-            final List<VersionedPackage> dependents = snapshot.getPackagesUsingSharedLibrary(
-                    libraryInfo, 0, Process.SYSTEM_UID, currentUserId);
-            if (dependents == null) {
-                continue;
+    boolean removeSharedLibrary(@NonNull String libName, long version) {
+        synchronized (mPm.mLock) {
+            WatchedLongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(libName);
+            if (versionedLib == null) {
+                return false;
             }
-            for (VersionedPackage dependentPackage : dependents) {
-                final PackageSetting ps = mPm.mSettings.getPackageLPr(
-                        dependentPackage.getPackageName());
-                if (ps != null) {
-                    ps.setOverlayPathsForLibrary(libraryInfo.getName(), null, currentUserId);
+            final int libIdx = versionedLib.indexOfKey(version);
+            if (libIdx < 0) {
+                return false;
+            }
+            SharedLibraryInfo libraryInfo = versionedLib.valueAt(libIdx);
+
+            final Computer snapshot = mPm.snapshotComputer();
+
+            // Remove the shared library overlays from its dependent packages.
+            for (int currentUserId : mPm.mUserManager.getUserIds()) {
+                final List<VersionedPackage> dependents = snapshot.getPackagesUsingSharedLibrary(
+                        libraryInfo, 0, Process.SYSTEM_UID, currentUserId);
+                if (dependents == null) {
+                    continue;
+                }
+                for (VersionedPackage dependentPackage : dependents) {
+                    final PackageSetting ps = mPm.mSettings.getPackageLPr(
+                            dependentPackage.getPackageName());
+                    if (ps != null) {
+                        ps.setOverlayPathsForLibrary(libraryInfo.getName(), null, currentUserId);
+                    }
                 }
             }
-        }
 
-        versionedLib.remove(version);
-        if (versionedLib.size() <= 0) {
-            mSharedLibraries.remove(libName);
-            if (libraryInfo.getType() == SharedLibraryInfo.TYPE_STATIC) {
-                mStaticLibsByDeclaringPackage.remove(libraryInfo.getDeclaringPackage()
-                        .getPackageName());
+            versionedLib.remove(version);
+            if (versionedLib.size() <= 0) {
+                mSharedLibraries.remove(libName);
+                if (libraryInfo.getType() == SharedLibraryInfo.TYPE_STATIC) {
+                    mStaticLibsByDeclaringPackage.remove(libraryInfo.getDeclaringPackage()
+                            .getPackageName());
+                }
             }
+            return true;
         }
-        return true;
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/StorageEventHelper.java b/services/core/java/com/android/server/pm/StorageEventHelper.java
index fe1c83b..f621d8b 100644
--- a/services/core/java/com/android/server/pm/StorageEventHelper.java
+++ b/services/core/java/com/android/server/pm/StorageEventHelper.java
@@ -346,9 +346,7 @@
             for (int i = 0; i < fileToDeleteCount; i++) {
                 File fileToDelete = filesToDelete.get(i);
                 logCriticalInfo(Log.WARN, "Destroying orphaned at " + fileToDelete);
-                synchronized (mPm.mInstallLock) {
-                    mRemovePackageHelper.removeCodePathLI(fileToDelete);
-                }
+                mRemovePackageHelper.removeCodePath(fileToDelete);
             }
         }
     }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 79e5dd2..b7a5f70 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -508,7 +508,7 @@
             if (!ACTION_DISABLE_QUIET_MODE_AFTER_UNLOCK.equals(intent.getAction())) {
                 return;
             }
-            final IntentSender target = intent.getParcelableExtra(Intent.EXTRA_INTENT);
+            final IntentSender target = intent.getParcelableExtra(Intent.EXTRA_INTENT, android.content.IntentSender.class);
             final int userId = intent.getIntExtra(Intent.EXTRA_USER_ID, UserHandle.USER_NULL);
             // Call setQuietModeEnabled on bg thread to avoid ANR
             BackgroundThread.getHandler().post(() ->
diff --git a/services/core/java/com/android/server/pm/VerifyingSession.java b/services/core/java/com/android/server/pm/VerifyingSession.java
index 726bfba..9bad4a8 100644
--- a/services/core/java/com/android/server/pm/VerifyingSession.java
+++ b/services/core/java/com/android/server/pm/VerifyingSession.java
@@ -65,6 +65,7 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.os.incremental.IncrementalManager;
 import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -426,10 +427,11 @@
 
         final String baseCodePath = mPackageLite.getBaseApkPath();
         final String[] splitCodePaths = mPackageLite.getSplitApkPaths();
-        final String rootHashString = PackageManagerServiceUtils.buildVerificationRootHashString(
-                baseCodePath, splitCodePaths);
 
-        if (rootHashString != null) {
+        if (IncrementalManager.isIncrementalPath(baseCodePath)) {
+            final String rootHashString =
+                    PackageManagerServiceUtils.buildVerificationRootHashString(
+                            baseCodePath, splitCodePaths);
             verification.putExtra(PackageManager.EXTRA_VERIFICATION_ROOT_HASH, rootHashString);
         }
 
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index df42639..3df412d 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -403,11 +403,9 @@
         }
     }
 
+    @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS)
     @Override
     public void stopOneTimePermissionSession(String packageName, @UserIdInt int userId) {
-        mContext.enforceCallingPermission(Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS,
-                "Must hold " + Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS
-                        + " to remove permissions as one time.");
         Objects.requireNonNull(packageName);
 
         final long token = Binder.clearCallingIdentity();
@@ -1114,16 +1112,21 @@
                     appOpsManager.finishProxyOp(AppOpsManager.opToPublicName(op),
                             resolvedAttributionSource, skipCurrentFinish);
                 }
-
-                if (next == null || next.getNext() == null) {
-                    return;
-                }
-
                 RegisteredAttribution registered =
                         sRunningAttributionSources.remove(current.getToken());
                 if (registered != null) {
                     registered.unregister();
                 }
+
+                if (next == null || next.getNext() == null) {
+                    if (next != null) {
+                        registered = sRunningAttributionSources.remove(next.getToken());
+                        if (registered != null) {
+                            registered.unregister();
+                        }
+                    }
+                    return;
+                }
                 current = next;
             }
         }
diff --git a/services/core/java/com/android/server/pm/pkg/component/ParsedPermissionUtils.java b/services/core/java/com/android/server/pm/pkg/component/ParsedPermissionUtils.java
index 10e8c47..c6d17753 100644
--- a/services/core/java/com/android/server/pm/pkg/component/ParsedPermissionUtils.java
+++ b/services/core/java/com/android/server/pm/pkg/component/ParsedPermissionUtils.java
@@ -316,8 +316,7 @@
                 final ParsedPermission perm = checkDuplicatePerm.get(name);
                 if (isMalformedDuplicate(parsedPermission, perm)) {
                     // Fix for b/213323615
-                    EventLog.writeEvent(0x534e4554, "213323615",
-                            "The package " + pkg.getPackageName() + " seems malicious");
+                    EventLog.writeEvent(0x534e4554, "213323615");
                     return true;
                 }
                 checkDuplicatePerm.put(name, parsedPermission);
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java
index 67d9aec..6a4513d 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java
@@ -1432,7 +1432,7 @@
         this.processes = in.readHashMap(ParsedProcess.class.getClassLoader());
         this.metaData = in.readBundle(boot);
         this.volumeUuid = sForInternedString.unparcel(in);
-        this.signingDetails = in.readParcelable(boot);
+        this.signingDetails = in.readParcelable(boot, android.content.pm.SigningDetails.class);
         this.mPath = in.readString();
         this.queriesIntents = in.createTypedArrayList(Intent.CREATOR);
         this.queriesPackages = sForInternedStringList.unparcel(in);
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
index 201ca9c..b60b9a0 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
@@ -3280,7 +3280,7 @@
 
             ArraySet<PublicKey> keys = new ArraySet<>(M);
             for (int j = 0; j < M; ++j) {
-                PublicKey pk = (PublicKey) in.readSerializable();
+                PublicKey pk = (PublicKey) in.readSerializable(java.security.PublicKey.class.getClassLoader(), java.security.PublicKey.class);
                 keys.add(pk);
             }
 
diff --git a/services/core/java/com/android/server/policy/GlobalKeyIntent.java b/services/core/java/com/android/server/policy/GlobalKeyIntent.java
index f8682be..3d34bee0 100644
--- a/services/core/java/com/android/server/policy/GlobalKeyIntent.java
+++ b/services/core/java/com/android/server/policy/GlobalKeyIntent.java
@@ -76,7 +76,7 @@
             return null;
         }
 
-        final KeyEvent event = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
+        final KeyEvent event = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT, android.view.KeyEvent.class);
         final boolean fromNonInteractive =
                 intent.getBooleanExtra(EXTRA_BEGAN_FROM_NON_INTERACTIVE, false);
         return new GlobalKeyIntent(intent.getComponent(), event, fromNonInteractive);
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index dd952f4..5816e98 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -947,6 +947,11 @@
     }
 
     private void powerPress(long eventTime, int count, boolean beganFromNonInteractive) {
+        // SideFPS still needs to know about suppressed power buttons, in case it needs to block
+        // an auth attempt.
+        if (count == 1) {
+            mSideFpsEventHandler.notifyPowerPressed();
+        }
         if (mDefaultDisplayPolicy.isScreenOnEarly() && !mDefaultDisplayPolicy.isScreenOnFully()) {
             Slog.i(TAG, "Suppressed redundant power key press while "
                     + "already in the process of turning the screen on.");
@@ -966,7 +971,7 @@
         } else if (count > 3 && count <= getMaxMultiPressPowerCount()) {
             Slog.d(TAG, "No behavior defined for power press count " + count);
         } else if (count == 1 && interactive && !beganFromNonInteractive) {
-            if (mSideFpsEventHandler.onSinglePressDetected(eventTime)) {
+            if (mSideFpsEventHandler.shouldConsumeSinglePress(eventTime)) {
                 Slog.i(TAG, "Suppressing power key because the user is interacting with the "
                         + "fingerprint sensor");
                 return;
@@ -4585,12 +4590,13 @@
             return false;
         }
 
-        final long sleepDuration = mPowerManagerInternal.getLastWakeup().sleepDuration;
+        final long sleepDurationRealtime =
+                mPowerManagerInternal.getLastWakeup().sleepDurationRealtime;
         if (DEBUG_WAKEUP) {
-            Log.i(TAG, "shouldWakeUpWithHomeIntent: sleepDuration= " + sleepDuration
+            Log.i(TAG, "shouldWakeUpWithHomeIntent: sleepDurationRealtime= " + sleepDurationRealtime
                     + " mWakeUpToLastStateTimeout= " + mWakeUpToLastStateTimeout);
         }
-        return sleepDuration > mWakeUpToLastStateTimeout;
+        return sleepDurationRealtime > mWakeUpToLastStateTimeout;
     }
 
     private void wakeUpFromPowerKey(long eventTime) {
diff --git a/services/core/java/com/android/server/policy/SideFpsEventHandler.java b/services/core/java/com/android/server/policy/SideFpsEventHandler.java
index 41d0272..af2b902 100644
--- a/services/core/java/com/android/server/policy/SideFpsEventHandler.java
+++ b/services/core/java/com/android/server/policy/SideFpsEventHandler.java
@@ -19,6 +19,7 @@
 import static android.hardware.biometrics.BiometricStateListener.STATE_BP_AUTH;
 import static android.hardware.biometrics.BiometricStateListener.STATE_ENROLLING;
 import static android.hardware.biometrics.BiometricStateListener.STATE_IDLE;
+import static android.hardware.biometrics.BiometricStateListener.STATE_KEYGUARD_AUTH;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -34,8 +35,12 @@
 import android.hardware.fingerprint.FingerprintManager;
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
 import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
+import android.os.Build;
 import android.os.Handler;
 import android.os.PowerManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Log;
 import android.view.WindowManager;
 
 import com.android.internal.R;
@@ -46,14 +51,26 @@
 import java.util.function.Supplier;
 
 /**
- * Defines behavior for handling interactions between power button events and
- * fingerprint-related operations, for devices where the fingerprint sensor (side fps)
- * lives on the power button.
+ * Defines behavior for handling interactions between power button events and fingerprint-related
+ * operations, for devices where the fingerprint sensor (side fps) lives on the power button.
  */
 public class SideFpsEventHandler {
 
     private static final int DEBOUNCE_DELAY_MILLIS = 500;
 
+    private int getTapWaitForPowerDuration(Context context) {
+        int tap = context.getResources().getInteger(
+                R.integer.config_sidefpsEnrollPowerPressWindow);
+        if (Build.isDebuggable()) {
+            tap = Settings.Secure.getIntForUser(context.getContentResolver(),
+                    Settings.Secure.FINGERPRINT_SIDE_FPS_ENROLL_TAP_WINDOW, tap,
+                    UserHandle.USER_CURRENT);
+        }
+        return tap;
+    }
+
+    private static final String TAG = "SideFpsEventHandler";
+
     @NonNull private final Context mContext;
     @NonNull private final Handler mHandler;
     @NonNull private final PowerManager mPowerManager;
@@ -61,20 +78,26 @@
     @NonNull private final AtomicBoolean mSideFpsEventHandlerReady;
 
     @Nullable private Dialog mDialog;
-    @NonNull private final DialogInterface.OnDismissListener mDialogDismissListener = (dialog) -> {
-        if (mDialog == dialog) {
-            mDialog = null;
-        }
-    };
+    private final Runnable mTurnOffDialog =
+            () -> {
+                dismissDialog("mTurnOffDialog");
+            };
+
+    @NonNull private final DialogInterface.OnDismissListener mDialogDismissListener;
 
     private @BiometricStateListener.State int mBiometricState;
+    private final int mTapWaitForPowerDuration;
+    private FingerprintManager mFingerprintManager;
 
     SideFpsEventHandler(Context context, Handler handler, PowerManager powerManager) {
         this(context, handler, powerManager, () -> new AlertDialog.Builder(context));
     }
 
     @VisibleForTesting
-    SideFpsEventHandler(Context context, Handler handler, PowerManager powerManager,
+    SideFpsEventHandler(
+            Context context,
+            Handler handler,
+            PowerManager powerManager,
             Supplier<AlertDialog.Builder> dialogSupplier) {
         mContext = context;
         mHandler = handler;
@@ -82,91 +105,131 @@
         mDialogSupplier = dialogSupplier;
         mBiometricState = STATE_IDLE;
         mSideFpsEventHandlerReady = new AtomicBoolean(false);
+        mDialogDismissListener =
+                (dialog) -> {
+                    if (mDialog == dialog) {
+                        if (mHandler != null) {
+                            mHandler.removeCallbacks(mTurnOffDialog);
+                        }
+                        mDialog = null;
+                    }
+                };
 
         // ensure dialog is dismissed if screen goes off for unrelated reasons
-        context.registerReceiver(new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                if (mDialog != null) {
-                    mDialog.dismiss();
-                    mDialog = null;
-                }
-            }
-        }, new IntentFilter(Intent.ACTION_SCREEN_OFF));
+        context.registerReceiver(
+                new BroadcastReceiver() {
+                    @Override
+                    public void onReceive(Context context, Intent intent) {
+                        if (mDialog != null) {
+                            mDialog.dismiss();
+                            mDialog = null;
+                        }
+                    }
+                },
+                new IntentFilter(Intent.ACTION_SCREEN_OFF));
+        mTapWaitForPowerDuration = getTapWaitForPowerDuration(context);
     }
 
     /**
-     * Called from {@link PhoneWindowManager} after the power button is pressed and displays a
-     * dialog confirming the user's intent to turn screen off if a fingerprint operation is
-     * active. The device goes to sleep if confirmed otherwise the dialog is dismissed.
+     * Called from {@link PhoneWindowManager} to notify FingerprintManager that a single tap power
+     * button has been pressed.
+     */
+    public void notifyPowerPressed() {
+        Log.i(TAG, "notifyPowerPressed");
+        if (mFingerprintManager == null) {
+            mFingerprintManager = mContext.getSystemService(FingerprintManager.class);
+        }
+        if (mFingerprintManager == null) {
+            return;
+        }
+        mFingerprintManager.onPowerPressed();
+    }
+
+    /**
+     * Called from {@link PhoneWindowManager} and will dictate if the SideFpsEventHandler should
+     * handle the power press.
      *
      * @param eventTime powerPress event time
      * @return true if powerPress was consumed, false otherwise
      */
-    public boolean onSinglePressDetected(long eventTime) {
+    public boolean shouldConsumeSinglePress(long eventTime) {
         if (!mSideFpsEventHandlerReady.get()) {
             return false;
         }
 
         switch (mBiometricState) {
             case STATE_ENROLLING:
-            case STATE_BP_AUTH:
-                mHandler.post(() -> {
-                    if (mDialog != null) {
-                        mDialog.dismiss();
-                    }
-                    mDialog = showConfirmDialog(mDialogSupplier.get(),
-                            mPowerManager, eventTime, mBiometricState, mDialogDismissListener);
-                });
+                mHandler.post(
+                        () -> {
+                            if (mHandler.hasCallbacks(mTurnOffDialog)) {
+                                Log.v(TAG, "Detected a tap to turn off dialog, ignoring");
+                                mHandler.removeCallbacks(mTurnOffDialog);
+                            }
+                        });
+                showDialog(eventTime, "Enroll Power Press");
                 return true;
+            case STATE_BP_AUTH:
+                return true;
+            case STATE_KEYGUARD_AUTH:
             default:
                 return false;
         }
     }
 
     @NonNull
-    private static Dialog showConfirmDialog(@NonNull AlertDialog.Builder dialogBuilder,
-            @NonNull PowerManager powerManager, long eventTime,
+    private static Dialog showConfirmDialog(
+            @NonNull AlertDialog.Builder dialogBuilder,
+            @NonNull PowerManager powerManager,
+            long eventTime,
             @BiometricStateListener.State int biometricState,
             @NonNull DialogInterface.OnDismissListener dismissListener) {
         final boolean enrolling = biometricState == STATE_ENROLLING;
-        final int title = enrolling ? R.string.fp_power_button_enrollment_title
-                : R.string.fp_power_button_bp_title;
-        final int message = enrolling ? R.string.fp_power_button_enrollment_message
-                : R.string.fp_power_button_bp_message;
-        final int positiveText = enrolling ? R.string.fp_power_button_enrollment_positive_button
-                : R.string.fp_power_button_bp_positive_button;
-        final int negativeText = enrolling ? R.string.fp_power_button_enrollment_negative_button
-                : R.string.fp_power_button_bp_negative_button;
+        final int title =
+                enrolling
+                        ? R.string.fp_power_button_enrollment_title
+                        : R.string.fp_power_button_bp_title;
+        final int message =
+                enrolling
+                        ? R.string.fp_power_button_enrollment_message
+                        : R.string.fp_power_button_bp_message;
+        final int positiveText =
+                enrolling
+                        ? R.string.fp_power_button_enrollment_positive_button
+                        : R.string.fp_power_button_bp_positive_button;
+        final int negativeText =
+                enrolling
+                        ? R.string.fp_power_button_enrollment_negative_button
+                        : R.string.fp_power_button_bp_negative_button;
 
-        final Dialog confirmScreenOffDialog = dialogBuilder
-                .setTitle(title)
-                .setMessage(message)
-                .setPositiveButton(positiveText,
-                        (dialog, which) -> {
-                            dialog.dismiss();
-                            powerManager.goToSleep(
-                                    eventTime,
-                                    PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
-                                    0 /* flags */
-                            );
-                        })
-                .setNegativeButton(negativeText, (dialog, which) -> dialog.dismiss())
-                .setOnDismissListener(dismissListener)
-                .setCancelable(false)
-                .create();
-        confirmScreenOffDialog.getWindow().setType(
-                WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL);
+        final Dialog confirmScreenOffDialog =
+                dialogBuilder
+                        .setTitle(title)
+                        .setMessage(message)
+                        .setPositiveButton(
+                                positiveText,
+                                (dialog, which) -> {
+                                    dialog.dismiss();
+                                    powerManager.goToSleep(
+                                            eventTime,
+                                            PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
+                                            0 /* flags */);
+                                })
+                        .setNegativeButton(negativeText, (dialog, which) -> dialog.dismiss())
+                        .setOnDismissListener(dismissListener)
+                        .setCancelable(false)
+                        .create();
+        confirmScreenOffDialog
+                .getWindow()
+                .setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL);
         confirmScreenOffDialog.show();
 
         return confirmScreenOffDialog;
     }
 
     /**
-     * Awaits notification from PhoneWindowManager that fingerprint service is ready
-     * to send updates about power button fps sensor state. Then configures a
-     * BiometricStateListener to receive and record updates to fps state, and
-     * registers the BiometricStateListener in FingerprintManager.
+     * Awaits notification from PhoneWindowManager that fingerprint service is ready to send updates
+     * about power button fps sensor state. Then configures a BiometricStateListener to receive and
+     * record updates to fps state, and registers the BiometricStateListener in FingerprintManager.
      */
     public void onFingerprintSensorReady() {
         final PackageManager pm = mContext.getPackageManager();
@@ -184,12 +247,12 @@
                         if (fingerprintManager.isPowerbuttonFps()) {
                             fingerprintManager.registerBiometricStateListener(
                                     new BiometricStateListener() {
-                                        @Nullable
-                                        private Runnable mStateRunnable = null;
+                                        @Nullable private Runnable mStateRunnable = null;
 
                                         @Override
                                         public void onStateChanged(
                                                 @BiometricStateListener.State int newState) {
+                                            Log.d(TAG, "onStateChanged : " + newState);
                                             if (mStateRunnable != null) {
                                                 mHandler.removeCallbacks(mStateRunnable);
                                                 mStateRunnable = null;
@@ -200,16 +263,58 @@
                                             // damper when moving to idle in case auth is first
                                             if (newState == STATE_IDLE) {
                                                 mStateRunnable = () -> mBiometricState = newState;
-                                                mHandler.postDelayed(mStateRunnable,
-                                                        DEBOUNCE_DELAY_MILLIS);
+                                                // This is also useful in the case of biometric
+                                                // prompt.
+                                                // If a user has recently succeeded/failed auth, we
+                                                // want to disable the power button for a short
+                                                // period of time (so ethey are able to view the
+                                                // prompt)
+                                                mHandler.postDelayed(
+                                                        mStateRunnable, DEBOUNCE_DELAY_MILLIS);
+                                                dismissDialog("STATE_IDLE");
                                             } else {
                                                 mBiometricState = newState;
                                             }
                                         }
+
+                                        @Override
+                                        public void onBiometricAction(
+                                                @BiometricStateListener.Action int action) {
+                                            Log.d(TAG, "onBiometricAction " + action);
+                                            switch (action) {
+                                                case BiometricStateListener.ACTION_SENSOR_TOUCH:
+                                                    mHandler.postDelayed(
+                                                            mTurnOffDialog,
+                                                            mTapWaitForPowerDuration);
+                                                    break;
+                                            }
+                                        }
                                     });
                             mSideFpsEventHandlerReady.set(true);
                         }
                     }
                 });
     }
+
+    private void dismissDialog(String reason) {
+        Log.d(TAG, "Dismissing dialog with reason: " + reason);
+        if (mDialog != null && mDialog.isShowing()) {
+            mDialog.dismiss();
+        }
+    }
+
+    private void showDialog(long time, String reason) {
+        Log.d(TAG, "Showing dialog with reason: " + reason);
+        if (mDialog != null && mDialog.isShowing()) {
+            Log.d(TAG, "Ignoring show dialog");
+            return;
+        }
+        mDialog =
+                showConfirmDialog(
+                        mDialogSupplier.get(),
+                        mPowerManager,
+                        time,
+                        mBiometricState,
+                        mDialogDismissListener);
+    }
 }
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 9bc0553..e8a3dcd 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -155,10 +155,6 @@
     int FINISH_LAYOUT_REDO_ANIM = 0x0008;
     /** Layer for the screen off animation */
     int COLOR_FADE_LAYER = 0x40000001;
-    /** Layer for Input overlays for capturing inputs for gesture detection, etc. */
-    int INPUT_DISPLAY_OVERLAY_LAYER = 0x7f000000;
-    /** Layer for Screen Decoration: The top most visible layer just below input overlay layers */
-    int SCREEN_DECOR_DISPLAY_OVERLAY_LAYER = INPUT_DISPLAY_OVERLAY_LAYER - 1;
 
     /**
      * Register shortcuts for window manager to dispatch.
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 70be8b8..988b4eb 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -376,6 +376,10 @@
     private long mLastGlobalWakeTime;
     private long mLastGlobalSleepTime;
 
+    // Timestamp (in the elapsed realtime timebase) of the last time was awoken or put to sleep.
+    private long mLastGlobalWakeTimeRealtime;
+    private long mLastGlobalSleepTimeRealtime;
+
     // Last reason the device went to sleep.
     private @WakeReason int mLastGlobalWakeReason;
     private @GoToSleepReason int mLastGlobalSleepReason;
@@ -927,6 +931,11 @@
          * Returns current time in milliseconds since boot, not counting time spent in deep sleep.
          */
         long uptimeMillis();
+
+        /**
+         * Returns milliseconds since boot, including time spent in sleep.
+         */
+        long elapsedRealtime();
     }
 
     @VisibleForTesting
@@ -1005,7 +1014,18 @@
         }
 
         Clock createClock() {
-            return SystemClock::uptimeMillis;
+            return new Clock() {
+                @Override
+                public long uptimeMillis() {
+                    return SystemClock.uptimeMillis();
+                }
+
+                @Override
+                public long elapsedRealtime() {
+                    return SystemClock.elapsedRealtime();
+                }
+            };
+
         }
 
         /**
@@ -1206,8 +1226,8 @@
                 millisUntilNormalTimeout =
                         powerGroup.getLastUserActivityTimeLocked() + screenOffTimeout - currentTime;
                 userActivityInternal(Display.DEFAULT_DISPLAY, currentTime,
-                        PowerManager.USER_ACTIVITY_EVENT_FACE_DOWN, /* flags= */0,
-                        Process.SYSTEM_UID);
+                        PowerManager.USER_ACTIVITY_EVENT_FACE_DOWN,
+                        PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS, Process.SYSTEM_UID);
             }
         }
         if (isFaceDown) {
@@ -2141,6 +2161,7 @@
                         + ")...");
                 mLastGlobalWakeTime = eventTime;
                 mLastGlobalWakeReason = reason;
+                mLastGlobalWakeTimeRealtime = mClock.elapsedRealtime();
                 break;
 
             case WAKEFULNESS_DREAMING:
@@ -2152,9 +2173,9 @@
                 traceMethodName = "goToSleep";
                 Slog.i(TAG, "Going to sleep due to " + PowerManager.sleepReasonToString(reason)
                         + " (uid " + uid + ")...");
-
                 mLastGlobalSleepTime = eventTime;
                 mLastGlobalSleepReason = reason;
+                mLastGlobalSleepTimeRealtime = mClock.elapsedRealtime();
                 mDozeStartInProgress = true;
                 break;
 
@@ -4404,6 +4425,10 @@
             pw.println("  mLastSleepTime=" + TimeUtils.formatUptime(mLastGlobalSleepTime));
             pw.println("  mLastSleepReason=" + PowerManager.sleepReasonToString(
                     mLastGlobalSleepReason));
+            pw.println("  mLastGlobalWakeTimeRealtime="
+                    + TimeUtils.formatUptime(mLastGlobalWakeTimeRealtime));
+            pw.println("  mLastGlobalSleepTimeRealtime="
+                    + TimeUtils.formatUptime(mLastGlobalSleepTimeRealtime));
             pw.println("  mLastInteractivePowerHintTime="
                     + TimeUtils.formatUptime(mLastInteractivePowerHintTime));
             pw.println("  mLastScreenBrightnessBoostTime="
@@ -4830,6 +4855,11 @@
                             .IS_STAY_ON_WHILE_PLUGGED_IN_WIRELESS,
                     ((mStayOnWhilePluggedInSetting & BatteryManager.BATTERY_PLUGGED_WIRELESS)
                             != 0));
+            proto.write(
+                    PowerServiceSettingsAndConfigurationDumpProto.StayOnWhilePluggedInProto
+                            .IS_STAY_ON_WHILE_PLUGGED_IN_DOCK,
+                    ((mStayOnWhilePluggedInSetting & BatteryManager.BATTERY_PLUGGED_DOCK)
+                            != 0));
             proto.end(stayOnWhilePluggedInToken);
 
             proto.write(
@@ -5886,7 +5916,7 @@
                 boolean isPersonalized) {
             // Get current time before acquiring the lock so that the calculated end time is as
             // accurate as possible.
-            final long nowElapsed = SystemClock.elapsedRealtime();
+            final long nowElapsed = mClock.elapsedRealtime();
             if (mContext.checkCallingOrSelfPermission(
                     android.Manifest.permission.BATTERY_PREDICTION)
                     != PackageManager.PERMISSION_GRANTED) {
@@ -5950,7 +5980,7 @@
                 synchronized (mEnhancedDischargeTimeLock) {
                     // Get current time after acquiring the lock so that the calculated duration
                     // is as accurate as possible.
-                    final long nowElapsed = SystemClock.elapsedRealtime();
+                    final long nowElapsed = mClock.elapsedRealtime();
                     if (isEnhancedDischargePredictionValidLocked(nowElapsed)) {
                         return new ParcelDuration(mEnhancedDischargeTimeElapsed - nowElapsed);
                     }
@@ -5969,7 +5999,7 @@
             final long ident = Binder.clearCallingIdentity();
             try {
                 synchronized (mEnhancedDischargeTimeLock) {
-                    return isEnhancedDischargePredictionValidLocked(SystemClock.elapsedRealtime())
+                    return isEnhancedDischargePredictionValidLocked(mClock.elapsedRealtime())
                             && mEnhancedDischargePredictionIsPersonalized;
                 }
             } finally {
@@ -6459,7 +6489,7 @@
     private PowerManager.WakeData getLastWakeupInternal() {
         synchronized (mLock) {
             return new PowerManager.WakeData(mLastGlobalWakeTime, mLastGlobalWakeReason,
-                    mLastGlobalWakeTime - mLastGlobalSleepTime);
+                    mLastGlobalWakeTimeRealtime - mLastGlobalSleepTimeRealtime);
         }
     }
 
diff --git a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
index c354f11..c79bc89 100644
--- a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
+++ b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
@@ -282,7 +282,7 @@
                 public void onReceive(Context context, Intent intent) {
                     setToggleSensorPrivacy(
                             ((UserHandle) intent.getParcelableExtra(
-                                    Intent.EXTRA_USER)).getIdentifier(), OTHER,
+                                    Intent.EXTRA_USER, android.os.UserHandle.class)).getIdentifier(), OTHER,
                             intent.getIntExtra(EXTRA_SENSOR, UNKNOWN), false);
                 }
             }, new IntentFilter(ACTION_DISABLE_TOGGLE_SENSOR_PRIVACY),
diff --git a/services/core/java/com/android/server/storage/CacheQuotaStrategy.java b/services/core/java/com/android/server/storage/CacheQuotaStrategy.java
index ff8b8d2..fc77ef1 100644
--- a/services/core/java/com/android/server/storage/CacheQuotaStrategy.java
+++ b/services/core/java/com/android/server/storage/CacheQuotaStrategy.java
@@ -207,7 +207,7 @@
     public void onResult(Bundle data) {
         final List<CacheQuotaHint> processedRequests =
                 data.getParcelableArrayList(
-                        CacheQuotaService.REQUEST_LIST_KEY);
+                        CacheQuotaService.REQUEST_LIST_KEY, android.app.usage.CacheQuotaHint.class);
         pushProcessedQuotas(processedRequests);
         writeXmlToFile(processedRequests);
     }
diff --git a/services/core/java/com/android/server/storage/StorageUserConnection.java b/services/core/java/com/android/server/storage/StorageUserConnection.java
index 0b11b0b..27ca83a 100644
--- a/services/core/java/com/android/server/storage/StorageUserConnection.java
+++ b/services/core/java/com/android/server/storage/StorageUserConnection.java
@@ -445,7 +445,7 @@
         }
 
         private void setResult(Bundle result, CompletableFuture<Void> future) {
-            ParcelableException ex = result.getParcelable(EXTRA_ERROR);
+            ParcelableException ex = result.getParcelable(EXTRA_ERROR, android.os.ParcelableException.class);
             if (ex != null) {
                 future.completeExceptionally(ex);
             } else {
diff --git a/services/core/java/com/android/server/trust/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
index 4b8c7c1..0b1f6b9 100644
--- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java
+++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
@@ -132,7 +132,7 @@
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            ComponentName component = intent.getParcelableExtra(EXTRA_COMPONENT_NAME);
+            ComponentName component = intent.getParcelableExtra(EXTRA_COMPONENT_NAME, android.content.ComponentName.class);
             if (TRUST_EXPIRED_ACTION.equals(intent.getAction())
                     && mName.equals(component)) {
                 mHandler.removeMessages(MSG_TRUST_TIMEOUT);
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 80ce70d..e00e029 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -1666,10 +1666,9 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.TRUST_LISTENER)
         @Override
         public boolean isTrustUsuallyManaged(int userId) {
-            mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
-                    "query trust state");
             return isTrustUsuallyManagedInternal(userId);
         }
 
diff --git a/services/core/java/com/android/server/vr/Vr2dDisplay.java b/services/core/java/com/android/server/vr/Vr2dDisplay.java
index 7697490..51c5a89 100644
--- a/services/core/java/com/android/server/vr/Vr2dDisplay.java
+++ b/services/core/java/com/android/server/vr/Vr2dDisplay.java
@@ -170,7 +170,7 @@
                     } else if (DEBUG_ACTION_SET_SURFACE.equals(action)) {
                         if (mVirtualDisplay != null) {
                             if (intent.hasExtra(DEBUG_EXTRA_SURFACE)) {
-                                setSurfaceLocked(intent.getParcelableExtra(DEBUG_EXTRA_SURFACE));
+                                setSurfaceLocked(intent.getParcelableExtra(DEBUG_EXTRA_SURFACE, android.view.Surface.class));
                             }
                         } else {
                             Log.w(TAG, "Cannot set the surface because the VD is null.");
diff --git a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
index 220e347..79ae662 100644
--- a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
+++ b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
@@ -16,8 +16,6 @@
 
 package com.android.server.wm;
 
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
-
 import static com.android.server.wm.utils.RegionUtils.forEachRect;
 
 import android.annotation.NonNull;
@@ -846,17 +844,8 @@
             windowInfo.token = window.mWindow.asBinder();
             windowInfo.hasFlagWatchOutsideTouch = (window.mInputConfig
                     & InputConfig.WATCH_OUTSIDE_TOUCH) != 0;
-            windowInfo.inPictureInPicture = false;
-
-            // There only are two windowless windows now, one is split window, and the other
-            // one is PIP.
-            if (windowInfo.type == TYPE_DOCK_DIVIDER) {
-                windowInfo.title = "Splitscreen Divider";
-            } else if (window.mIsPIPMenu) {
-                windowInfo.title = "Picture-in-Picture menu";
-                // Set it to true to be consistent with the legacy implementation.
-                windowInfo.inPictureInPicture = true;
-            }
+            // Set it to true to be consistent with the legacy implementation.
+            windowInfo.inPictureInPicture = window.mIsPIPMenu;
             return windowInfo;
         }
 
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index 1ccdaf7..d2a00af 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -577,6 +577,21 @@
         }
     }
 
+    /**
+     * Returns the windowing mode of the task that hosts the activity, or {@code -1} if task is not
+     * found.
+     */
+    @Override
+    public int getTaskWindowingMode(IBinder activityToken) {
+        synchronized (mGlobalLock) {
+            final ActivityRecord ar = ActivityRecord.isInAnyTask(activityToken);
+            if (ar == null) {
+                return -1;
+            }
+            return ar.getTask().getWindowingMode();
+        }
+    }
+
     @Override
     @Nullable
     public IBinder getActivityTokenBelow(IBinder activityToken) {
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index 270891f..a21919c 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -149,6 +149,12 @@
     private static final long UNKNOWN_VISIBILITY_CHECK_DELAY_MS = 3000;
 
     /**
+     * If the recents animation is finished before the delay since the window drawn, do not log the
+     * action because the duration is too small that may be just an accidentally touch.
+     */
+    private static final long LATENCY_TRACKER_RECENTS_DELAY_MS = 300;
+
+    /**
      * The flag for {@link #notifyActivityLaunching} to skip associating a new launch with an active
      * transition, in the case the launch is standalone (e.g. from recents).
      */
@@ -735,13 +741,10 @@
         info.mWindowsDrawnDelayMs = info.calculateDelay(timestampNs);
         info.mIsDrawn = true;
         final TransitionInfoSnapshot infoSnapshot = new TransitionInfoSnapshot(info);
-        if (info.mLoggedTransitionStarting) {
+        if (info.mLoggedTransitionStarting || (!r.mDisplayContent.mOpeningApps.contains(r)
+                && !r.mTransitionController.isCollecting(r))) {
             done(false /* abort */, info, "notifyWindowsDrawn", timestampNs);
         }
-        if (r.mWmService.isRecentsAnimationTarget(r)) {
-            r.mWmService.getRecentsAnimationController().logRecentsAnimationStartTime(
-                    info.mSourceEventDelayMs + info.mWindowsDrawnDelayMs);
-        }
         return infoSnapshot;
     }
 
@@ -786,12 +789,6 @@
             info.mReason = activityToReason.valueAt(index);
             info.mLoggedTransitionStarting = true;
             if (info.mIsDrawn) {
-                if (info.mReason == APP_TRANSITION_RECENTS_ANIM) {
-                    final LatencyTracker latencyTracker = r.mWmService.mLatencyTracker;
-                    final int duration = info.mSourceEventDelayMs + info.mCurrentTransitionDelayMs;
-                    mLoggerHandler.post(() -> latencyTracker.logAction(
-                            LatencyTracker.ACTION_START_RECENTS_ANIMATION, duration));
-                }
                 done(false /* abort */, info, "notifyTransitionStarting drawn", timestampNs);
             }
         }
@@ -959,6 +956,9 @@
                 launchObserverNotifyActivityLaunchFinished(info, timestampNs);
             }
             logAppTransitionFinished(info, isHibernating != null ? isHibernating : false);
+            if (info.mReason == APP_TRANSITION_RECENTS_ANIM) {
+                logRecentsAnimationLatency(info);
+            }
         }
         mTransitionInfoList.remove(info);
     }
@@ -1114,6 +1114,22 @@
         Log.i(TAG, sb.toString());
     }
 
+    private void logRecentsAnimationLatency(TransitionInfo info) {
+        final int duration = info.mSourceEventDelayMs + info.mWindowsDrawnDelayMs;
+        final ActivityRecord r = info.mLastLaunchedActivity;
+        final long lastTopLossTime = r.topResumedStateLossTime;
+        final WindowManagerService wm = mSupervisor.mService.mWindowManager;
+        final Object controller = wm.getRecentsAnimationController();
+        mLoggerHandler.postDelayed(() -> {
+            if (lastTopLossTime != r.topResumedStateLossTime
+                    || controller != wm.getRecentsAnimationController()) {
+                // Skip if the animation was finished in a short time.
+                return;
+            }
+            wm.mLatencyTracker.logAction(LatencyTracker.ACTION_START_RECENTS_ANIMATION, duration);
+        }, LATENCY_TRACKER_RECENTS_DELAY_MS);
+    }
+
     private static int getAppStartTransitionType(int tronType, boolean relaunched) {
         if (tronType == TYPE_TRANSITION_COLD_LAUNCH) {
             return FrameworkStatsLog.APP_START_OCCURRED__TYPE__COLD;
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 85f6f0c..047f65c 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -224,6 +224,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
+import static com.android.server.wm.WindowManagerService.sEnableShellTransitions;
 import static com.android.server.wm.WindowState.LEGACY_POLICY_VISIBILITY;
 import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN;
 
@@ -1992,6 +1993,9 @@
 
             if (options.getLaunchIntoPipParams() != null) {
                 pictureInPictureArgs = options.getLaunchIntoPipParams();
+                if (sourceRecord != null) {
+                    adjustPictureInPictureParamsIfNeeded(sourceRecord.getBounds());
+                }
             }
 
             mOverrideTaskTransition = options.getOverrideTaskTransition();
@@ -3149,15 +3153,10 @@
         mWillCloseOrEnterPip = willCloseOrEnterPip;
     }
 
-    /**
-     * Returns whether this {@link ActivityRecord} is considered closing. Conditions are either
-     * 1. Is this app animating and was requested to be hidden
-     * 2. App is delayed closing since it might enter PIP.
-     */
-    boolean isClosingOrEnteringPip() {
-        return (isAnimating(TRANSITION | PARENTS, ANIMATION_TYPE_APP_TRANSITION)
-                && !mVisibleRequested) || mWillCloseOrEnterPip;
+    boolean willCloseOrEnterPip() {
+        return mWillCloseOrEnterPip;
     }
+
     /**
      * @return Whether AppOps allows this package to enter picture-in-picture.
      */
@@ -3529,7 +3528,9 @@
         }
 
         final boolean isCurrentVisible = mVisibleRequested || isState(PAUSED, STARTED);
-        if (updateVisibility && isCurrentVisible) {
+        if (updateVisibility && isCurrentVisible
+                // Avoid intermediate lifecycle change when launching with clearing task.
+                && !task.isClearingToReuseTask()) {
             boolean ensureVisibility = false;
             if (occludesParent(true /* includingFinishing */)) {
                 // If the current activity is not opaque, we need to make sure the visibilities of
@@ -5272,12 +5273,19 @@
         }
 
         final int windowsCount = mChildren.size();
+        // With Shell-Transition, the activity will running a transition when it is visible.
+        // It won't be included when fromTransition is true means the call from finishTransition.
+        final boolean runningAnimation = sEnableShellTransitions ? visible
+                : isAnimating(PARENTS, ANIMATION_TYPE_APP_TRANSITION);
         for (int i = 0; i < windowsCount; i++) {
-            mChildren.get(i).onAppVisibilityChanged(visible, isAnimating(PARENTS,
-                    ANIMATION_TYPE_APP_TRANSITION));
+            mChildren.get(i).onAppVisibilityChanged(visible, runningAnimation);
         }
         setVisible(visible);
         setVisibleRequested(visible);
+        ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "commitVisibility: %s: visible=%b"
+                        + " visibleRequested=%b, isInTransition=%b, runningAnimation=%b, caller=%s",
+                this, isVisible(), mVisibleRequested, isInTransition(), runningAnimation,
+                Debug.getCallers(5));
         if (!visible) {
             stopFreezingScreen(true, true);
         } else {
@@ -5300,9 +5308,6 @@
             task.dispatchTaskInfoChangedIfNeeded(false /* force */);
             task = task.getParent().asTask();
         }
-        ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
-                "commitVisibility: %s: visible=%b mVisibleRequested=%b", this,
-                isVisible(), mVisibleRequested);
         final DisplayContent displayContent = getDisplayContent();
         displayContent.getInputMonitor().setUpdateInputWindowsNeededLw();
         if (performLayout) {
@@ -5338,11 +5343,7 @@
                 ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_WINDOW_ANIMATION
                         | ANIMATION_TYPE_RECENTS);
         if (!delayed) {
-            // We aren't delayed anything, but exiting windows rely on the animation finished
-            // callback being called in case the ActivityRecord was pretending to be delayed,
-            // which we might have done because we were in closing/opening apps list.
             if (!usingShellTransitions) {
-                onAnimationFinished(ANIMATION_TYPE_APP_TRANSITION, null /* AnimationAdapter */);
                 if (visible) {
                     // The token was made immediately visible, there will be no entrance animation.
                     // We need to inform the client the enter animation was finished.
@@ -7737,9 +7738,6 @@
         // relatively fixed.
         overrideConfig.colorMode = fullConfig.colorMode;
         overrideConfig.densityDpi = fullConfig.densityDpi;
-        // The smallest screen width is the short side of screen bounds. Because the bounds
-        // and density won't be changed, smallestScreenWidthDp is also fixed.
-        overrideConfig.smallestScreenWidthDp = fullConfig.smallestScreenWidthDp;
         if (info.isFixedOrientation()) {
             // lock rotation too. When in size-compat, onConfigurationChanged will watch for and
             // apply runtime rotation changes.
@@ -7836,7 +7834,7 @@
             // computed accordingly.
             if (!matchParentBounds()) {
                 getTaskFragment().computeConfigResourceOverrides(resolvedConfig,
-                        newParentConfiguration);
+                        newParentConfiguration, areBoundsLetterboxed());
             }
         // If activity in fullscreen mode is letterboxed because of fixed orientation then bounds
         // are already calculated in resolveFixedOrientationConfiguration.
@@ -8007,7 +8005,8 @@
         }
 
         // Since bounds has changed, the configuration needs to be computed accordingly.
-        getTaskFragment().computeConfigResourceOverrides(resolvedConfig, newParentConfiguration);
+        getTaskFragment().computeConfigResourceOverrides(resolvedConfig, newParentConfiguration,
+                areBoundsLetterboxed());
     }
 
     void recomputeConfiguration() {
@@ -8223,7 +8222,7 @@
         // Calculate app bounds using fixed orientation bounds because they will be needed later
         // for comparison with size compat app bounds in {@link resolveSizeCompatModeConfiguration}.
         getTaskFragment().computeConfigResourceOverrides(getResolvedOverrideConfiguration(),
-                newParentConfig);
+                newParentConfig, mCompatDisplayInsets, areBoundsLetterboxed());
         mLetterboxBoundsForFixedOrientationAndAspectRatio = new Rect(resolvedBounds);
     }
 
@@ -8251,7 +8250,7 @@
             // Compute the configuration based on the resolved bounds. If aspect ratio doesn't
             // restrict, the bounds should be the requested override bounds.
             getTaskFragment().computeConfigResourceOverrides(resolvedConfig, newParentConfiguration,
-                    getFixedRotationTransformDisplayInfo());
+                    getFixedRotationTransformDisplayInfo(), areBoundsLetterboxed());
         }
     }
 
@@ -8315,7 +8314,7 @@
         // are calculated in compat container space. The actual position on screen will be applied
         // later, so the calculation is simpler that doesn't need to involve offset from parent.
         getTaskFragment().computeConfigResourceOverrides(resolvedConfig, newParentConfiguration,
-                mCompatDisplayInsets);
+                mCompatDisplayInsets,  areBoundsLetterboxed());
         // Use current screen layout as source because the size of app is independent to parent.
         resolvedConfig.screenLayout = TaskFragment.computeScreenLayoutOverride(
                 getConfiguration().screenLayout, resolvedConfig.screenWidthDp,
@@ -9770,6 +9769,7 @@
 
     void setPictureInPictureParams(PictureInPictureParams p) {
         pictureInPictureArgs.copyOnlySet(p);
+        adjustPictureInPictureParamsIfNeeded(getBounds());
         getTask().getRootTask().onPictureInPictureParamsChanged();
     }
 
@@ -9816,6 +9816,18 @@
         return new Point(windowLayout.minWidth, windowLayout.minHeight);
     }
 
+    /**
+     * Adjust the source rect hint in {@link #pictureInPictureArgs} by window bounds since
+     * it is relative to its root view (see also b/235599028).
+     * It is caller's responsibility to make sure this is called exactly once when we update
+     * {@link #pictureInPictureArgs} to avoid double offset.
+     */
+    private void adjustPictureInPictureParamsIfNeeded(Rect windowBounds) {
+        if (pictureInPictureArgs != null && pictureInPictureArgs.hasSourceBoundsHint()) {
+            pictureInPictureArgs.getSourceRectHint().offset(windowBounds.left, windowBounds.top);
+        }
+    }
+
     static class Builder {
         private final ActivityTaskManagerService mAtmService;
         private WindowProcessController mCallerApp;
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java
index 501d45f..77d6097 100644
--- a/services/core/java/com/android/server/wm/ActivityStartController.java
+++ b/services/core/java/com/android/server/wm/ActivityStartController.java
@@ -19,7 +19,9 @@
 import static android.app.ActivityManager.START_CANCELED;
 import static android.app.ActivityManager.START_SUCCESS;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
 
@@ -29,6 +31,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.IApplicationThread;
 import android.content.ComponentName;
@@ -46,6 +49,7 @@
 import android.util.Slog;
 import android.util.SparseArray;
 import android.view.RemoteAnimationAdapter;
+import android.view.WindowManager;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
@@ -536,6 +540,42 @@
                 .execute();
     }
 
+    boolean startExistingRecentsIfPossible(Intent intent, ActivityOptions options) {
+        final int activityType = mService.getRecentTasks().getRecentsComponent()
+                .equals(intent.getComponent()) ? ACTIVITY_TYPE_RECENTS : ACTIVITY_TYPE_HOME;
+        final Task rootTask = mService.mRootWindowContainer.getDefaultTaskDisplayArea()
+                .getRootTask(WINDOWING_MODE_UNDEFINED, activityType);
+        if (rootTask == null) return false;
+        final ActivityRecord r = rootTask.topRunningActivity();
+        if (r == null || r.mVisibleRequested || !r.attachedToProcess()
+                || !r.mActivityComponent.equals(intent.getComponent())
+                // Recents keeps invisible while device is locked.
+                || r.mDisplayContent.isKeyguardLocked()) {
+            return false;
+        }
+        mService.mRootWindowContainer.startPowerModeLaunchIfNeeded(true /* forceSend */, r);
+        final ActivityMetricsLogger.LaunchingState launchingState =
+                mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
+        final Task task = r.getTask();
+        mService.deferWindowLayout();
+        try {
+            task.mTransitionController.requestTransitionIfNeeded(WindowManager.TRANSIT_TO_FRONT,
+                    0 /* flags */, task, task /* readyGroupRef */,
+                    options.getRemoteTransition(), null /* displayChange */);
+            r.mTransitionController.setTransientLaunch(r,
+                    TaskDisplayArea.getRootTaskAbove(rootTask));
+            task.moveToFront("startExistingRecents");
+            task.mInResumeTopActivity = true;
+            task.resumeTopActivity(null /* prev */, options, true /* deferPause */);
+            mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState,
+                    ActivityManager.START_TASK_TO_FRONT, false, r, options);
+        } finally {
+            task.mInResumeTopActivity = false;
+            mService.continueWindowLayout();
+        }
+        return true;
+    }
+
     void registerRemoteAnimationForNextActivityStart(String packageName,
             RemoteAnimationAdapter adapter, @Nullable IBinder launchCookie) {
         mPendingRemoteAnimationRegistry.addPendingAnimation(packageName, adapter, launchCookie);
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 9b1c6bb..f5c5a13 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -201,8 +201,6 @@
     @VisibleForTesting
     boolean mAddingToTask;
 
-    private ActivityInfo mNewTaskInfo;
-    private Intent mNewTaskIntent;
     private Task mSourceRootTask;
     private Task mTargetRootTask;
     // The task that the last activity was started into. We currently reset the actual start
@@ -613,8 +611,6 @@
         mInTaskFragment = starter.mInTaskFragment;
         mAddingToTask = starter.mAddingToTask;
 
-        mNewTaskInfo = starter.mNewTaskInfo;
-        mNewTaskIntent = starter.mNewTaskIntent;
         mSourceRootTask = starter.mSourceRootTask;
 
         mTargetTask = starter.mTargetTask;
@@ -728,13 +724,15 @@
                 // used here because it may be cleared in setTargetRootTaskIfNeeded.
                 final ActivityOptions originalOptions = mRequest.activityOptions != null
                         ? mRequest.activityOptions.getOriginalOptions() : null;
+                // Only track the launch time of activity that will be resumed.
+                final ActivityRecord launchingRecord = mDoResume ? mLastStartActivityRecord : null;
                 // If the new record is the one that started, a new activity has created.
-                final boolean newActivityCreated = mStartActivity == mLastStartActivityRecord;
+                final boolean newActivityCreated = mStartActivity == launchingRecord;
                 // Notify ActivityMetricsLogger that the activity has launched.
                 // ActivityMetricsLogger will then wait for the windows to be drawn and populate
                 // WaitResult.
                 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
-                        newActivityCreated, mLastStartActivityRecord, originalOptions);
+                        newActivityCreated, launchingRecord, originalOptions);
                 if (mRequest.waitResult != null) {
                     mRequest.waitResult.result = res;
                     res = waitResultIfNeeded(mRequest.waitResult, mLastStartActivityRecord,
@@ -1218,7 +1216,7 @@
         }
 
         mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
-                request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
+                request.voiceInteractor, startFlags, checkedOptions,
                 inTask, inTaskFragment, restrictedBgActivity, intentGrants);
 
         if (request.outActivity != null) {
@@ -1644,7 +1642,7 @@
      */
     private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
-            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
+            int startFlags, ActivityOptions options, Task inTask,
             TaskFragment inTaskFragment, boolean restrictedBgActivity,
             NeededUriGrants intentGrants) {
         int result = START_CANCELED;
@@ -1668,7 +1666,7 @@
             try {
                 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
                 result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
-                        startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,
+                        startFlags, options, inTask, inTaskFragment, restrictedBgActivity,
                         intentGrants);
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
@@ -1812,16 +1810,13 @@
     @VisibleForTesting
     int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
-            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
+            int startFlags, ActivityOptions options, Task inTask,
             TaskFragment inTaskFragment, boolean restrictedBgActivity,
             NeededUriGrants intentGrants) {
-        setInitialState(r, options, inTask, inTaskFragment, doResume, startFlags, sourceRecord,
+        setInitialState(r, options, inTask, inTaskFragment, startFlags, sourceRecord,
                 voiceSession, voiceInteractor, restrictedBgActivity);
 
         computeLaunchingTaskFlags();
-
-        computeSourceRootTask();
-
         mIntent.setFlags(mLaunchFlags);
 
         boolean dreamStopping = false;
@@ -2413,8 +2408,6 @@
         mInTaskFragment = null;
         mAddingToTask = false;
 
-        mNewTaskInfo = null;
-        mNewTaskIntent = null;
         mSourceRootTask = null;
 
         mTargetRootTask = null;
@@ -2438,7 +2431,7 @@
     }
 
     private void setInitialState(ActivityRecord r, ActivityOptions options, Task inTask,
-            TaskFragment inTaskFragment, boolean doResume, int startFlags,
+            TaskFragment inTaskFragment, int startFlags,
             ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession,
             IVoiceInteractor voiceInteractor, boolean restrictedBgActivity) {
         reset(false /* clearRequest */);
@@ -2448,6 +2441,7 @@
         mOptions = options;
         mCallingUid = r.launchedFromUid;
         mSourceRecord = sourceRecord;
+        mSourceRootTask = mSourceRecord != null ? mSourceRecord.getRootTask() : null;
         mVoiceSession = voiceSession;
         mVoiceInteractor = voiceInteractor;
         mRestrictedBgActivity = restrictedBgActivity;
@@ -2502,10 +2496,11 @@
         // If the caller has asked not to resume at this point, we make note
         // of this in the record so that we can skip it when trying to find
         // the top running activity.
-        mDoResume = doResume;
-        if (!doResume || !r.showToCurrentUser() || mLaunchTaskBehind) {
+        if (!r.showToCurrentUser() || mLaunchTaskBehind) {
             r.delayedResume = true;
             mDoResume = false;
+        } else {
+            mDoResume = true;
         }
 
         if (mOptions != null) {
@@ -2565,7 +2560,6 @@
             mInTask = null;
         }
         mInTaskFragment = inTaskFragment;
-        sendNewTaskFragmentResultRequestIfNeeded();
 
         mStartFlags = startFlags;
         // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
@@ -2608,18 +2602,6 @@
         }
     }
 
-    private void sendNewTaskFragmentResultRequestIfNeeded() {
-        if (mStartActivity.resultTo != null && mInTaskFragment != null
-                && mInTaskFragment != mStartActivity.resultTo.getTaskFragment()) {
-            Slog.w(TAG,
-                    "Activity is launching as a new TaskFragment, so cancelling activity result.");
-            mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
-                    mStartActivity.requestCode, RESULT_CANCELED,
-                    null /* data */, null /* dataGrants */);
-            mStartActivity.resultTo = null;
-        }
-    }
-
     private void computeLaunchingTaskFlags() {
         // If the caller is not coming from another activity, but has given us an explicit task into
         // which they would like us to launch the new activity, then let's see about doing that.
@@ -2708,39 +2690,6 @@
         }
     }
 
-    private void computeSourceRootTask() {
-        if (mSourceRecord == null) {
-            mSourceRootTask = null;
-            return;
-        }
-        if (!mSourceRecord.finishing) {
-            mSourceRootTask = mSourceRecord.getRootTask();
-            return;
-        }
-
-        // If the source is finishing, we can't further count it as our source. This is because the
-        // task it is associated with may now be empty and on its way out, so we don't want to
-        // blindly throw it in to that task.  Instead we will take the NEW_TASK flow and try to find
-        // a task for it. But save the task information so it can be used when creating the new task.
-        if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
-            Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
-                    + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
-            mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
-
-            // It is not guaranteed that the source record will have a task associated with it.
-            // For example, if this method is being called for processing a pending activity
-            // launch, it is possible that the activity has been removed from the task after the
-            // launch was enqueued.
-            final Task sourceTask = mSourceRecord.getTask();
-            if (sourceTask == null || sourceTask.getTopNonFinishingActivity() == null) {
-                mNewTaskInfo = mSourceRecord.info;
-                mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
-            }
-        }
-        mSourceRecord = null;
-        mSourceRootTask = null;
-    }
-
     /**
      * Decide whether the new activity should be inserted into an existing task. Returns null
      * if not or an ActivityRecord with the task into which the new activity should be added.
@@ -2934,8 +2883,7 @@
     private void setNewTask(Task taskToAffiliate) {
         final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront;
         final Task task = mTargetRootTask.reuseOrCreateTask(
-                mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
-                mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
+                mStartActivity.info, mIntent, mVoiceSession,
                 mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);
         task.mTransitionController.collectExistenceChange(task);
         addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask");
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 6de1b95..35e65a5 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -1231,6 +1231,28 @@
             @Nullable String callingFeatureId, Intent intent, String resolvedType,
             IBinder resultTo, String resultWho, int requestCode, int startFlags,
             ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
+
+        final SafeActivityOptions opts = SafeActivityOptions.fromBundle(bOptions);
+        // A quick path (skip general intent/task resolving) to start recents animation if the
+        // recents (or home) activity is available in background.
+        if (opts != null && opts.getOriginalOptions().getTransientLaunch()
+                && isCallerRecents(Binder.getCallingUid())) {
+            final long origId = Binder.clearCallingIdentity();
+            try {
+                synchronized (mGlobalLock) {
+                    Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "startExistingRecents");
+                    if (mActivityStartController.startExistingRecentsIfPossible(
+                            intent, opts.getOriginalOptions())) {
+                        return ActivityManager.START_TASK_TO_FRONT;
+                    }
+                    // Else follow the standard launch procedure.
+                }
+            } finally {
+                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+                Binder.restoreCallingIdentity(origId);
+            }
+        }
+
         assertPackageMatchesCallingUid(callingPackage);
         enforceNotIsolatedCaller("startActivityAsUser");
         if (Process.isSdkSandboxUid(Binder.getCallingUid())) {
@@ -1257,7 +1279,7 @@
                 .setRequestCode(requestCode)
                 .setStartFlags(startFlags)
                 .setProfilerInfo(profilerInfo)
-                .setActivityOptions(bOptions)
+                .setActivityOptions(opts)
                 .setUserId(userId)
                 .execute();
 
@@ -3521,10 +3543,9 @@
                 mRootWindowContainer.moveActivityToPinnedRootTask(r,
                         null /* launchIntoPipHostActivity */, "enterPictureInPictureMode",
                         transition);
-                final Task task = r.getTask();
                 // Continue the pausing process after entering pip.
-                if (task.getPausingActivity() == r) {
-                    task.schedulePauseActivity(r, false /* userLeaving */,
+                if (r.isState(PAUSING)) {
+                    r.getTask().schedulePauseActivity(r, false /* userLeaving */,
                             false /* pauseImmediately */, "auto-pip");
                 }
             }
diff --git a/services/core/java/com/android/server/wm/AsyncRotationController.java b/services/core/java/com/android/server/wm/AsyncRotationController.java
index 2e1d3b1..0af0462 100644
--- a/services/core/java/com/android/server/wm/AsyncRotationController.java
+++ b/services/core/java/com/android/server/wm/AsyncRotationController.java
@@ -120,7 +120,7 @@
             } else {
                 mTransitionOp = OP_CHANGE;
             }
-        } else if (transitionType != WindowManager.TRANSIT_NONE) {
+        } else if (displayContent.mTransitionController.isShellTransitionsEnabled()) {
             mTransitionOp = OP_APP_SWITCH;
         } else {
             mTransitionOp = OP_LEGACY;
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index d07cc68..9295c18 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -112,6 +112,7 @@
         RemoteAnimationTarget topAppTarget = null;
         int prevTaskId;
         int prevUserId;
+        boolean prepareAnimation;
 
         BackNavigationInfo.Builder infoBuilder = new BackNavigationInfo.Builder();
         synchronized (wmService.mGlobalLock) {
@@ -257,7 +258,8 @@
                     BackNavigationInfo.typeToString(backType));
 
             // For now, we only animate when going home.
-            boolean prepareAnimation = backType == BackNavigationInfo.TYPE_RETURN_TO_HOME
+            prepareAnimation = backType == BackNavigationInfo.TYPE_RETURN_TO_HOME
+                    && requestAnimation
                     // Only create a new leash if no leash has been created.
                     // Otherwise return null for animation target to avoid conflict.
                     && !removedWindowContainer.hasCommittedReparentToAnimationLeash();
@@ -292,7 +294,7 @@
             }
 
             // Special handling for back to home animation
-            if (backType == BackNavigationInfo.TYPE_RETURN_TO_HOME && requestAnimation
+            if (backType == BackNavigationInfo.TYPE_RETURN_TO_HOME && prepareAnimation
                     && prevTask != null) {
                 currentTask.mBackGestureStarted = true;
                 // Make launcher show from behind by marking its top activity as visible and
@@ -347,7 +349,7 @@
             Task finalTask = currentTask;
             RemoteCallback onBackNavigationDone = new RemoteCallback(result -> onBackNavigationDone(
                     result, finalRemovedWindowContainer, finalBackType, finalTask,
-                    finalprevActivity, requestAnimation));
+                    finalprevActivity, prepareAnimation));
             infoBuilder.setOnBackNavigationDone(onBackNavigationDone);
         }
 
@@ -381,14 +383,14 @@
 
     private void onBackNavigationDone(
             Bundle result, WindowContainer<?> windowContainer, int backType,
-            Task task, ActivityRecord prevActivity, boolean requestAnimation) {
+            Task task, ActivityRecord prevActivity, boolean prepareAnimation) {
         SurfaceControl surfaceControl = windowContainer.getSurfaceControl();
         boolean triggerBack = result != null && result.getBoolean(
                 BackNavigationInfo.KEY_TRIGGER_BACK);
         ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "onBackNavigationDone backType=%s, "
                 + "task=%s, prevActivity=%s", backType, task, prevActivity);
 
-        if (backType == BackNavigationInfo.TYPE_RETURN_TO_HOME && requestAnimation) {
+        if (backType == BackNavigationInfo.TYPE_RETURN_TO_HOME && prepareAnimation) {
             if (triggerBack) {
                 if (surfaceControl != null && surfaceControl.isValid()) {
                     // When going back to home, hide the task surface before it is re-parented to
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 6619f98..409e0ed 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -161,6 +161,7 @@
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ActivityInfo.ScreenOrientation;
@@ -1363,7 +1364,7 @@
 
     void setInsetProvider(@InternalInsetsType int type, WindowContainer win,
             @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider) {
-        setInsetProvider(type, win, frameProvider, null /* imeFrameProvider */);
+        setInsetProvider(type, win, frameProvider, null /* overrideFrameProviders */);
     }
 
     /**
@@ -1372,15 +1373,18 @@
      * @param type The type of inset this window provides.
      * @param win The window.
      * @param frameProvider Function to compute the frame, or {@code null} if the just the frame of
-     *                      the window should be taken.
-     * @param imeFrameProvider Function to compute the frame when dispatching insets to the IME, or
-     *                         {@code null} if the normal frame should be taken.
+     *                      the window should be taken. Only for non-WindowState providers, nav bar
+     *                      and status bar.
+     * @param overrideFrameProviders Functions to compute the frame when dispatching insets to the
+     *                               given window types, or {@code null} if the normal frame should
+     *                               be taken.
      */
     void setInsetProvider(@InternalInsetsType int type, WindowContainer win,
             @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider,
-            @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider) {
+            @Nullable SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>>
+                    overrideFrameProviders) {
         mInsetsStateController.getSourceProvider(type).setWindowContainer(win, frameProvider,
-                imeFrameProvider);
+                overrideFrameProviders);
     }
 
     InsetsStateController getInsetsStateController() {
@@ -1685,7 +1689,7 @@
                     return false;
                 }
             }
-            if (r.isState(RESUMED) && !r.getRootTask().mInResumeTopActivity) {
+            if (r.isState(RESUMED) && !r.getTask().mInResumeTopActivity) {
                 // If the activity is executing or has done the lifecycle callback, use normal
                 // rotation animation so the display info can be updated immediately (see
                 // updateDisplayAndOrientation). This prevents a compatibility issue such as
@@ -3866,7 +3870,7 @@
             mAtmService.onImeWindowSetOnDisplayArea(imePid, mImeWindowsContainer);
         }
         mInsetsStateController.getSourceProvider(ITYPE_IME).setWindowContainer(win,
-                mDisplayPolicy.getImeSourceFrameProvider(), null /* imeFrameProvider */);
+                mDisplayPolicy.getImeSourceFrameProvider(), null);
         computeImeTarget(true /* updateImeTarget */);
         updateImeControlTarget();
     }
@@ -4811,16 +4815,8 @@
         final Bitmap bitmap = screenshotBuffer == null ? null : screenshotBuffer.asBitmap();
         if (bitmap == null) {
             Slog.w(TAG_WM, "Failed to take screenshot");
-            return null;
         }
-
-        // Create a copy of the screenshot that is immutable and backed in ashmem.
-        // This greatly reduces the overhead of passing the bitmap between processes.
-        final Bitmap ret = bitmap.asShared();
-        if (ret != bitmap) {
-            bitmap.recycle();
-        }
-        return ret;
+        return bitmap;
     }
 
     @Override
@@ -5681,7 +5677,16 @@
     void getKeepClearAreas(Set<Rect> outRestricted, Set<Rect> outUnrestricted) {
         final Matrix tmpMatrix = new Matrix();
         final float[] tmpFloat9 = new float[9];
+        final RecentsAnimationController recentsAnimationController =
+                mWmService.getRecentsAnimationController();
         forAllWindows(w -> {
+            // Skip the window if it is part of Recents animation
+            final boolean ignoreRecentsAnimationTarget = recentsAnimationController != null
+                    && recentsAnimationController.shouldApplyInputConsumer(w.getActivityRecord());
+            if (ignoreRecentsAnimationTarget) {
+                return false;  // continue traversal
+            }
+
             if (w.isVisible() && !w.inPinnedWindowingMode()) {
                 w.getKeepClearAreas(outRestricted, outUnrestricted, tmpMatrix, tmpFloat9);
 
@@ -6509,12 +6514,13 @@
         /**
          * Notifies the remote insets controller that the top focused window has changed.
          *
-         * @param packageName The name of the package that is open in the top focused window.
+         * @param component The application component that is open in the top focussed window.
          * @param requestedVisibilities The insets visibilities requested by the focussed window.
          */
-        void topFocusedWindowChanged(String packageName, InsetsVisibilities requestedVisibilities) {
+        void topFocusedWindowChanged(ComponentName component,
+                InsetsVisibilities requestedVisibilities) {
             try {
-                mRemoteInsetsController.topFocusedWindowChanged(packageName, requestedVisibilities);
+                mRemoteInsetsController.topFocusedWindowChanged(component, requestedVisibilities);
             } catch (RemoteException e) {
                 Slog.w(TAG, "Failed to deliver package in top focused window change", e);
             }
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 2b359ca..98a51a9 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -48,6 +48,7 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
@@ -1155,7 +1156,7 @@
                 break;
             case TYPE_NAVIGATION_BAR:
                 mNavigationBar = win;
-                mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, win,
+                final TriConsumer<DisplayFrames, WindowContainer, Rect> navFrameProvider =
                         (displayFrames, windowContainer, inOutFrame) -> {
                             if (!mNavButtonForcedVisible) {
                                 final LayoutParams lp =
@@ -1165,18 +1166,22 @@
                                         if (provider.type != ITYPE_NAVIGATION_BAR) {
                                             continue;
                                         }
-                                        calculateInsetsFrame(displayFrames, win, inOutFrame,
-                                                provider.source, provider.insetsSize
-                                        );
+                                        InsetsFrameProvider.calculateInsetsFrame(
+                                                displayFrames.mUnrestricted,
+                                                win.getBounds(), displayFrames.mDisplayCutoutSafe,
+                                                inOutFrame, provider.source,
+                                                provider.insetsSize, lp.privateFlags);
                                     }
                                 }
                                 inOutFrame.inset(win.mGivenContentInsets);
                             }
-                        },
-
-                        (displayFrames, windowContainer, inOutFrame) -> {
-                            // For IME, we don't modify the frame.
-                        });
+                        };
+                final SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>> imeOverride =
+                        new SparseArray<>();
+                // For IME, we don't modify the frame.
+                imeOverride.put(TYPE_INPUT_METHOD, null);
+                mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, win,
+                        navFrameProvider, imeOverride);
 
                 mDisplayContent.setInsetProvider(ITYPE_BOTTOM_MANDATORY_GESTURES, win,
                         (displayFrames, windowContainer, inOutFrame) -> {
@@ -1241,24 +1246,51 @@
                                 provider.insetsSize != null
                                         ? (displayFrames, windowContainer, inOutFrame) -> {
                                             inOutFrame.inset(win.mGivenContentInsets);
+                                            final LayoutParams lp =
+                                                    win.mAttrs.forRotation(displayFrames.mRotation);
                                             final InsetsFrameProvider ifp =
                                                     win.mAttrs.forRotation(displayFrames.mRotation)
                                                             .providedInsets[index];
-                                            calculateInsetsFrame(displayFrames, windowContainer,
-                                                    inOutFrame, ifp.source, ifp.insetsSize);
+                                            InsetsFrameProvider.calculateInsetsFrame(
+                                                    displayFrames.mUnrestricted,
+                                                    windowContainer.getBounds(),
+                                                    displayFrames.mDisplayCutoutSafe,
+                                                    inOutFrame, ifp.source,
+                                                    ifp.insetsSize, lp.privateFlags);
                                         } : null;
-                        final TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider =
-                                provider.imeInsetsSize != null
-                                        ? (displayFrames, windowContainer, inOutFrame) -> {
-                                            inOutFrame.inset(win.mGivenContentInsets);
-                                            final InsetsFrameProvider ifp =
-                                                    win.mAttrs.forRotation(displayFrames.mRotation)
-                                                            .providedInsets[index];
-                                            calculateInsetsFrame(displayFrames, windowContainer,
-                                                    inOutFrame, ifp.source, ifp.imeInsetsSize);
-                                        } : null;
+                        final InsetsFrameProvider.InsetsSizeOverride[] overrides =
+                                provider.insetsSizeOverrides;
+                        final SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>>
+                                overrideProviders;
+                        if (overrides != null) {
+                            overrideProviders = new SparseArray<>();
+                            for (int j = overrides.length - 1; j >= 0; j--) {
+                                final int overrideIndex = j;
+                                final TriConsumer<DisplayFrames, WindowContainer, Rect>
+                                        overrideFrameProvider =
+                                                (displayFrames, windowContainer, inOutFrame) -> {
+                                                    final LayoutParams lp =
+                                                            win.mAttrs.forRotation(
+                                                                    displayFrames.mRotation);
+                                                    final InsetsFrameProvider ifp =
+                                                            win.mAttrs.providedInsets[index];
+                                                    InsetsFrameProvider.calculateInsetsFrame(
+                                                            displayFrames.mUnrestricted,
+                                                            windowContainer.getBounds(),
+                                                            displayFrames.mDisplayCutoutSafe,
+                                                            inOutFrame, ifp.source,
+                                                            ifp.insetsSizeOverrides[
+                                                                    overrideIndex].insetsSize,
+                                                            lp.privateFlags);
+                                                };
+                                overrideProviders.put(overrides[j].windowType,
+                                        overrideFrameProvider);
+                            }
+                        } else {
+                            overrideProviders = null;
+                        }
                         mDisplayContent.setInsetProvider(provider.type, win, frameProvider,
-                                imeFrameProvider);
+                                overrideProviders);
                         mInsetsSourceWindowsExceptIme.add(win);
                     }
                 }
@@ -1266,31 +1298,6 @@
         }
     }
 
-    private void calculateInsetsFrame(DisplayFrames df, WindowContainer container, Rect inOutFrame,
-            int source, Insets insetsSize) {
-        if (source == InsetsFrameProvider.SOURCE_DISPLAY) {
-            inOutFrame.set(df.mUnrestricted);
-        } else if (source == InsetsFrameProvider.SOURCE_CONTAINER_BOUNDS) {
-            inOutFrame.set(container.getBounds());
-        }
-        if (insetsSize == null) {
-            return;
-        }
-        // Only one side of the provider shall be applied. Check in the order of left - top -
-        // right - bottom, only the first non-zero value will be applied.
-        if (insetsSize.left != 0) {
-            inOutFrame.right = inOutFrame.left + insetsSize.left;
-        } else if (insetsSize.top != 0) {
-            inOutFrame.bottom = inOutFrame.top + insetsSize.top;
-        } else if (insetsSize.right != 0) {
-            inOutFrame.left = inOutFrame.right - insetsSize.right;
-        } else if (insetsSize.bottom != 0) {
-            inOutFrame.top = inOutFrame.bottom - insetsSize.bottom;
-        } else {
-            inOutFrame.setEmpty();
-        }
-    }
-
     @WindowManagerPolicy.AltBarPosition
     private int getAltBarPosition(WindowManager.LayoutParams params) {
         switch (params.gravity) {
diff --git a/services/core/java/com/android/server/wm/EventLogTags.logtags b/services/core/java/com/android/server/wm/EventLogTags.logtags
index 6d63331..1e5a219 100644
--- a/services/core/java/com/android/server/wm/EventLogTags.logtags
+++ b/services/core/java/com/android/server/wm/EventLogTags.logtags
@@ -66,4 +66,4 @@
 31007 wm_boot_animation_done (time|2|3)
 
 # Request surface flinger to show / hide the wallpaper surface.
-33001 wm_wallpaper_surface (Display Id|1|5),(visible|1)
+33001 wm_wallpaper_surface (Display Id|1|5),(Visible|1),(Target|3)
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 0d4cfa3..3e6e06a 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -234,7 +234,7 @@
     //
     private static boolean isImeLayeringTarget(@NonNull InsetsControlTarget target,
             @NonNull InsetsControlTarget dcTarget) {
-        return !dcTarget.getWindow().isClosing() && target == dcTarget;
+        return !isImeTargetWindowClosing(dcTarget.getWindow()) && target == dcTarget;
     }
 
     private static boolean isAboveImeLayeringTarget(@NonNull InsetsControlTarget target,
@@ -256,7 +256,14 @@
         final InsetsControlTarget target = mDisplayContent.getImeTarget(IME_TARGET_CONTROL);
         return target == mImeRequester
                 && (mImeRequester.getWindow() == null
-                || !mImeRequester.getWindow().isClosing());
+                || !isImeTargetWindowClosing(mImeRequester.getWindow()));
+    }
+
+    private static boolean isImeTargetWindowClosing(@NonNull WindowState win) {
+        return win.mAnimatingExit || win.mActivityRecord != null
+                && (win.mActivityRecord.isInTransition()
+                    && !win.mActivityRecord.isVisibleRequested()
+                    || win.mActivityRecord.willCloseOrEnterPip());
     }
 
     private boolean isTargetChangedWithinActivity(InsetsControlTarget target) {
diff --git a/services/core/java/com/android/server/wm/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java
index b7ddbd0..33cdd2e 100644
--- a/services/core/java/com/android/server/wm/InputManagerCallback.java
+++ b/services/core/java/com/android/server/wm/InputManagerCallback.java
@@ -265,7 +265,7 @@
                     .setContainerLayer()
                     .setName(name)
                     .setCallsite("createSurfaceForGestureMonitor")
-                    .setParent(dc.getOverlayLayer())
+                    .setParent(dc.getSurfaceControl())
                     .build();
         }
     }
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 4ff4a9a..ce0627c 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -63,7 +63,10 @@
 import android.view.WindowManager;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.inputmethod.SoftInputShowHideReason;
 import com.android.internal.protolog.common.ProtoLog;
+import com.android.server.LocalServices;
+import com.android.server.inputmethod.InputMethodManagerInternal;
 
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
@@ -403,8 +406,28 @@
                     // Shell transitions doesn't use RecentsAnimationController
                     || getWeak(mActiveRecentsActivity) != null && focus.inTransition();
             if (shouldApplyRecentsInputConsumer) {
-                requestFocus(recentsAnimationInputConsumer.mWindowHandle.token,
-                        recentsAnimationInputConsumer.mName);
+                if (mInputFocus != recentsAnimationInputConsumer.mWindowHandle.token) {
+                    requestFocus(recentsAnimationInputConsumer.mWindowHandle.token,
+                            recentsAnimationInputConsumer.mName);
+                    // Hiding IME/IME icon when recents input consumer gain focus.
+                    if (!mDisplayContent.isImeAttachedToApp()) {
+                        // Hiding IME if IME window is not attached to app since it's not proper to
+                        // snapshot Task with IME window to animate together in this case.
+                        final InputMethodManagerInternal inputMethodManagerInternal =
+                                LocalServices.getService(InputMethodManagerInternal.class);
+                        if (inputMethodManagerInternal != null) {
+                            inputMethodManagerInternal.hideCurrentInputMethod(
+                                    SoftInputShowHideReason.HIDE_RECENTS_ANIMATION);
+                        }
+                    } else {
+                        // Disable IME icon explicitly when IME attached to the app in case
+                        // IME icon might flickering while swiping to the next app task still
+                        // in animating before the next app window focused, or IME icon
+                        // persists on the bottom when swiping the task to recents.
+                        InputMethodManagerInternal.get().updateImeWindowStatus(
+                                true /* disableImeIcon */);
+                    }
+                }
                 return;
             }
         }
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index db2ee2d..3e2d7c9 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -46,6 +46,7 @@
 import android.app.ActivityTaskManager;
 import android.app.StatusBarManager;
 import android.app.WindowConfiguration;
+import android.content.ComponentName;
 import android.content.res.Resources;
 import android.graphics.Rect;
 import android.util.ArrayMap;
@@ -265,7 +266,7 @@
             state = originalState;
         }
         state = adjustVisibilityForIme(target, state, state == originalState);
-        return adjustInsetsForRoundedCorners(target, state, state == originalState);
+        return adjustInsetsForRoundedCorners(target.mToken, state, state == originalState);
     }
 
     InsetsState adjustInsetsForWindow(WindowState target, InsetsState originalState) {
@@ -289,8 +290,9 @@
         // contains all insets types.
         final InsetsState originalState = mDisplayContent.getInsetsPolicy()
                 .enforceInsetsPolicyForTarget(type, WINDOWING_MODE_FULLSCREEN, alwaysOnTop,
-                        mStateController.getRawInsetsState());
-        return adjustVisibilityForTransientTypes(originalState);
+                        attrs.type, mStateController.getRawInsetsState());
+        InsetsState state = adjustVisibilityForTransientTypes(originalState);
+        return adjustInsetsForRoundedCorners(token, state, state == originalState);
     }
 
     /**
@@ -350,12 +352,13 @@
      * @param type the inset type provided by the target
      * @param windowingMode the windowing mode of the target
      * @param isAlwaysOnTop is the target always on top
+     * @param windowType the type of the target
      * @param state the input inset state containing all the sources
      * @return The state stripped of the necessary information.
      */
     InsetsState enforceInsetsPolicyForTarget(@InternalInsetsType int type,
             @WindowConfiguration.WindowingMode int windowingMode, boolean isAlwaysOnTop,
-            InsetsState state) {
+            int windowType, InsetsState state) {
         boolean stateCopied = false;
 
         if (type != ITYPE_INVALID) {
@@ -376,21 +379,20 @@
             if (type == ITYPE_STATUS_BAR || type == ITYPE_CLIMATE_BAR) {
                 state.removeSource(ITYPE_CAPTION_BAR);
             }
-
-            // IME needs different frames for certain cases (e.g. navigation bar in gesture nav).
-            if (type == ITYPE_IME) {
-                ArrayMap<Integer, WindowContainerInsetsSourceProvider> providers = mStateController
-                        .getSourceProviders();
-                for (int i = providers.size() - 1; i >= 0; i--) {
-                    WindowContainerInsetsSourceProvider otherProvider = providers.valueAt(i);
-                    if (otherProvider.overridesImeFrame()) {
-                        InsetsSource override =
-                                new InsetsSource(
-                                        state.getSource(otherProvider.getSource().getType()));
-                        override.setFrame(otherProvider.getImeOverrideFrame());
-                        state.addSource(override);
-                    }
+        }
+        ArrayMap<Integer, WindowContainerInsetsSourceProvider> providers = mStateController
+                .getSourceProviders();
+        for (int i = providers.size() - 1; i >= 0; i--) {
+            WindowContainerInsetsSourceProvider otherProvider = providers.valueAt(i);
+            if (otherProvider.overridesFrame(windowType)) {
+                if (!stateCopied) {
+                    state = new InsetsState(state);
+                    stateCopied = true;
                 }
+                InsetsSource override =
+                        new InsetsSource(state.getSource(otherProvider.getSource().getType()));
+                override.setFrame(otherProvider.getOverriddenFrame(windowType));
+                state.addSource(override);
             }
         }
 
@@ -465,15 +467,19 @@
         return originalState;
     }
 
-    private InsetsState adjustInsetsForRoundedCorners(WindowState w, InsetsState originalState,
+    private InsetsState adjustInsetsForRoundedCorners(WindowToken token, InsetsState originalState,
             boolean copyState) {
-        final Task task = w.getTask();
-        if (task != null && !task.getWindowConfiguration().tasksAreFloating()) {
-            // Use task bounds to calculating rounded corners if the task is not floating.
-            final Rect roundedCornerFrame = new Rect(task.getBounds());
-            final InsetsState state = copyState ? new InsetsState(originalState) : originalState;
-            state.setRoundedCornerFrame(roundedCornerFrame);
-            return state;
+        if (token != null) {
+            final ActivityRecord activityRecord = token.asActivityRecord();
+            final Task task = activityRecord != null ? activityRecord.getTask() : null;
+            if (task != null && !task.getWindowConfiguration().tasksAreFloating()) {
+                // Use task bounds to calculating rounded corners if the task is not floating.
+                final Rect roundedCornerFrame = new Rect(task.getBounds());
+                final InsetsState state = copyState ? new InsetsState(originalState)
+                        : originalState;
+                state.setRoundedCornerFrame(roundedCornerFrame);
+                return state;
+            }
         }
         return originalState;
     }
@@ -543,8 +549,10 @@
             return focusedWin;
         }
         if (remoteInsetsControllerControlsSystemBars(focusedWin)) {
+            ComponentName component = focusedWin.mActivityRecord != null
+                    ? focusedWin.mActivityRecord.mActivityComponent : null;
             mDisplayContent.mRemoteInsetsControlTarget.topFocusedWindowChanged(
-                    focusedWin.mAttrs.packageName, focusedWin.getRequestedVisibilities());
+                    component, focusedWin.getRequestedVisibilities());
             return mDisplayContent.mRemoteInsetsControlTarget;
         }
         if (mPolicy.areSystemBarsForcedShownLw()) {
@@ -601,8 +609,10 @@
             return null;
         }
         if (remoteInsetsControllerControlsSystemBars(focusedWin)) {
+            ComponentName component = focusedWin.mActivityRecord != null
+                    ? focusedWin.mActivityRecord.mActivityComponent : null;
             mDisplayContent.mRemoteInsetsControlTarget.topFocusedWindowChanged(
-                    focusedWin.mAttrs.packageName, focusedWin.getRequestedVisibilities());
+                    component, focusedWin.getRequestedVisibilities());
             return mDisplayContent.mRemoteInsetsControlTarget;
         }
         if (mPolicy.areSystemBarsForcedShownLw()) {
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 610bf05..86a73c9 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -27,7 +27,6 @@
 import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL;
 import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL_TARGET;
 import static com.android.server.wm.InsetsSourceProviderProto.FRAME;
-import static com.android.server.wm.InsetsSourceProviderProto.IME_OVERRIDDEN_FRAME;
 import static com.android.server.wm.InsetsSourceProviderProto.IS_LEASH_READY_FOR_DISPATCHING;
 import static com.android.server.wm.InsetsSourceProviderProto.PENDING_CONTROL_TARGET;
 import static com.android.server.wm.InsetsSourceProviderProto.SEAMLESS_ROTATING;
@@ -41,6 +40,7 @@
 import android.graphics.Insets;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.util.SparseArray;
 import android.util.proto.ProtoOutputStream;
 import android.view.InsetsFrameProvider;
 import android.view.InsetsSource;
@@ -78,8 +78,8 @@
 
     private @Nullable ControlAdapter mAdapter;
     private TriConsumer<DisplayFrames, WindowContainer, Rect> mFrameProvider;
-    private TriConsumer<DisplayFrames, WindowContainer, Rect> mImeFrameProvider;
-    private final Rect mImeOverrideFrame = new Rect();
+    private SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>> mOverrideFrameProviders;
+    private final SparseArray<Rect> mOverrideFrames = new SparseArray<Rect>();
     private boolean mIsLeashReadyForDispatching;
     private final Rect mSourceFrame = new Rect();
     private final Rect mLastSourceFrame = new Rect();
@@ -146,12 +146,15 @@
      * @param windowContainer The window container that links to this source.
      * @param frameProvider Based on display frame state and the window, calculates the resulting
      *                      frame that should be reported to clients.
-     * @param imeFrameProvider Based on display frame state and the window, calculates the resulting
-     *                         frame that should be reported to IME.
+     *                      This will only be used when the window container providing the insets is
+     *                      not a WindowState.
+     * @param overrideFrameProviders Based on display frame state and the window, calculates the
+     *                               resulting frame that should be reported to given window type.
      */
     void setWindowContainer(@Nullable WindowContainer windowContainer,
             @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider,
-            @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider) {
+            @Nullable SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>>
+                    overrideFrameProviders) {
         if (mWindowContainer != null) {
             if (mControllable) {
                 mWindowContainer.setControllableInsetProvider(null);
@@ -167,8 +170,9 @@
         ProtoLog.d(WM_DEBUG_WINDOW_INSETS, "InsetsSource setWin %s for type %s",
                 windowContainer, InsetsState.typeToString(mSource.getType()));
         mWindowContainer = windowContainer;
+        // TODO: remove the frame provider for non-WindowState container.
         mFrameProvider = frameProvider;
-        mImeFrameProvider = imeFrameProvider;
+        mOverrideFrameProviders = overrideFrameProviders;
         if (windowContainer == null) {
             setServerVisible(false);
             mSource.setVisibleFrame(null);
@@ -228,10 +232,25 @@
         }
         updateSourceFrameForServerVisibility();
 
-        if (mImeFrameProvider != null) {
-            mImeOverrideFrame.set(frame);
-            mImeFrameProvider.accept(mWindowContainer.getDisplayContent().mDisplayFrames,
-                    mWindowContainer, mImeOverrideFrame);
+        if (mOverrideFrameProviders != null) {
+            for (int i = mOverrideFrameProviders.size() - 1; i >= 0; i--) {
+                final int windowType = mOverrideFrameProviders.keyAt(i);
+                final Rect overrideFrame;
+                if (mOverrideFrames.contains(windowType)) {
+                    overrideFrame = mOverrideFrames.get(windowType);
+                    overrideFrame.set(frame);
+                } else {
+                    overrideFrame = new Rect(frame);
+                }
+                final TriConsumer<DisplayFrames, WindowContainer, Rect> provider =
+                        mOverrideFrameProviders.get(windowType);
+                if (provider != null) {
+                    mOverrideFrameProviders.get(windowType).accept(
+                            mWindowContainer.getDisplayContent().mDisplayFrames, mWindowContainer,
+                            overrideFrame);
+                }
+                mOverrideFrames.put(windowType, overrideFrame);
+            }
         }
 
         if (win.mGivenVisibleInsets.left != 0 || win.mGivenVisibleInsets.top != 0
@@ -552,32 +571,30 @@
         return mClientVisible;
     }
 
-    /**
-     * @return Whether this provider uses a different frame to dispatch to the IME.
-     */
-    boolean overridesImeFrame() {
-        return mImeFrameProvider != null;
+    boolean overridesFrame(int windowType) {
+        return mOverrideFrames.contains(windowType);
     }
 
-    /**
-     * @return Rect to dispatch to the IME as frame. Only valid if {@link #overridesImeFrame()}
-     *         returns {@code true}.
-     */
-    Rect getImeOverrideFrame() {
-        return mImeOverrideFrame;
+    Rect getOverriddenFrame(int windowType) {
+        return mOverrideFrames.get(windowType);
     }
 
     public void dump(PrintWriter pw, String prefix) {
         pw.println(prefix + getClass().getSimpleName());
         prefix = prefix + "  ";
         pw.print(prefix + "mSource="); mSource.dump("", pw);
+        pw.print(prefix + "mSourceFrame=");
+        pw.println(mSourceFrame);
+        if (mOverrideFrames.size() > 0) {
+            pw.print(prefix + "mOverrideFrames=");
+            pw.println(mOverrideFrames);
+        }
         if (mControl != null) {
             pw.print(prefix + "mControl=");
             mControl.dump("", pw);
         }
         pw.print(prefix);
         pw.print("mIsLeashReadyForDispatching="); pw.print(mIsLeashReadyForDispatching);
-        pw.print(" mImeOverrideFrame="); pw.print(mImeOverrideFrame.toShortString());
         pw.println();
         if (mWindowContainer != null) {
             pw.print(prefix + "mWindowContainer=");
@@ -621,7 +638,6 @@
         if (mAdapter != null && mAdapter.mCapturedLeash != null) {
             mAdapter.mCapturedLeash.dumpDebug(proto, CAPTURED_LEASH);
         }
-        mImeOverrideFrame.dumpDebug(proto, IME_OVERRIDDEN_FRAME);
         proto.write(IS_LEASH_READY_FOR_DISPATCHING, mIsLeashReadyForDispatching);
         proto.write(CLIENT_VISIBLE, mClientVisible);
         proto.write(SERVER_VISIBLE, mServerVisible);
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index ca4376e..d76f6be 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -170,11 +170,12 @@
 
         final KeyguardDisplayState state = getDisplayState(displayId);
         final boolean aodChanged = aodShowing != state.mAodShowing;
+        final boolean aodRemoved = state.mAodShowing && !aodShowing;
         // If keyguard is going away, but SystemUI aborted the transition, need to reset state.
-        // Do not reset keyguardChanged status if this is aodChanged.
+        // Do not reset keyguardChanged status when only AOD is removed.
         final boolean keyguardChanged = (keyguardShowing != state.mKeyguardShowing)
-                || (state.mKeyguardGoingAway && keyguardShowing && !aodChanged);
-        if (aodChanged && !aodShowing) {
+                || (state.mKeyguardGoingAway && keyguardShowing && !aodRemoved);
+        if (aodRemoved) {
             updateDeferWakeTransition(false /* waiting */);
         }
         if (!keyguardChanged && !aodChanged) {
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index d2ce048..53f1fe6 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -70,10 +70,7 @@
 import android.window.TaskSnapshot;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.inputmethod.SoftInputShowHideReason;
-import com.android.internal.os.BackgroundThread;
 import com.android.internal.protolog.common.ProtoLog;
-import com.android.internal.util.LatencyTracker;
 import com.android.internal.util.function.pooled.PooledConsumer;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.LocalServices;
@@ -99,11 +96,6 @@
 public class RecentsAnimationController implements DeathRecipient {
     private static final String TAG = RecentsAnimationController.class.getSimpleName();
     private static final long FAILSAFE_DELAY = 1000;
-    /**
-     * If the recents animation is canceled before the delay since the window drawn, do not log the
-     * action because the duration is too small that may be just a mistouch.
-     */
-    private static final long LATENCY_TRACKER_LOG_DELAY_MS = 300;
 
     // Constant for a yet-to-be-calculated {@link RemoteAnimationTarget#Mode} state
     private static final int MODE_UNKNOWN = -1;
@@ -144,7 +136,7 @@
     private boolean mPendingStart = true;
 
     // Set when the animation has been canceled
-    private volatile boolean mCanceled;
+    private boolean mCanceled;
 
     // Whether or not the input consumer is enabled. The input consumer must be both registered and
     // enabled for it to start intercepting touch events.
@@ -333,26 +325,6 @@
                         }
                     }
                     InputMethodManagerInternal.get().maybeFinishStylusHandwriting();
-                    if (!behindSystemBars) {
-                        // Hiding IME if IME window is not attached to app.
-                        // Since some windowing mode is not proper to snapshot Task with IME window
-                        // while the app transitioning to the next task (e.g. split-screen mode)
-                        if (!mDisplayContent.isImeAttachedToApp()) {
-                            final InputMethodManagerInternal inputMethodManagerInternal =
-                                    LocalServices.getService(InputMethodManagerInternal.class);
-                            if (inputMethodManagerInternal != null) {
-                                inputMethodManagerInternal.hideCurrentInputMethod(
-                                        SoftInputShowHideReason.HIDE_RECENTS_ANIMATION);
-                            }
-                        } else {
-                            // Disable IME icon explicitly when IME attached to the app in case
-                            // IME icon might flickering while swiping to the next app task still
-                            // in animating before the next app window focused, or IME icon
-                            // persists on the bottom when swiping the task to recents.
-                            InputMethodManagerInternal.get().updateImeWindowStatus(
-                                    true /* disableImeIcon */);
-                        }
-                    }
                     mService.mWindowPlacerLocked.requestTraversal();
                 }
             } finally {
@@ -380,10 +352,6 @@
             }
         }
 
-        // TODO(b/166736352): Remove this method without the need to expose to launcher.
-        @Override
-        public void hideCurrentInputMethod() { }
-
         @Override
         public void setDeferCancelUntilNextTransition(boolean defer, boolean screenshot) {
             synchronized (mService.mGlobalLock) {
@@ -785,15 +753,6 @@
         }, false /* traverseTopToBottom */);
     }
 
-    void logRecentsAnimationStartTime(int durationMs) {
-        BackgroundThread.getHandler().postDelayed(() -> {
-            if (!mCanceled) {
-                mService.mLatencyTracker.logAction(LatencyTracker.ACTION_START_RECENTS_ANIMATION,
-                        durationMs);
-            }
-        }, LATENCY_TRACKER_LOG_DELAY_MS);
-    }
-
     private boolean removeTaskInternal(int taskId) {
         boolean result = false;
         for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index ac1a2b1..8db5289 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -71,6 +71,7 @@
     final ArrayList<NonAppWindowAnimationAdapter> mPendingNonAppAnimations = new ArrayList<>();
     private final Handler mHandler;
     private final Runnable mTimeoutRunnable = () -> cancelAnimation("timeoutRunnable");
+    private boolean mIsFinishing;
 
     private FinishedCallback mFinishedCallback;
     private final boolean mIsActivityEmbedding;
@@ -275,6 +276,7 @@
                 mPendingAnimations.size());
         mHandler.removeCallbacks(mTimeoutRunnable);
         synchronized (mService.mGlobalLock) {
+            mIsFinishing = true;
             unlinkToDeathOfRunner();
             releaseFinishedCallback();
             mService.openSurfaceTransaction();
@@ -319,6 +321,7 @@
                 throw e;
             } finally {
                 mService.closeSurfaceTransaction("RemoteAnimationController#finished");
+                mIsFinishing = false;
             }
         }
         // Reset input for all activities when the remote animation is finished.
@@ -558,6 +561,9 @@
 
         @Override
         public void onAnimationCancelled(SurfaceControl animationLeash) {
+            if (mIsFinishing) {
+                return;
+            }
             if (mRecord.mAdapter == this) {
                 mRecord.mAdapter = null;
             } else {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index da3e56e..5a9058b 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2116,7 +2116,7 @@
                 // entering content-pip animation.
                 mWindowManager.mTaskSnapshotController.recordTaskSnapshot(
                         task, false /* allowSnapshotHome */);
-                rootTask.setBounds(r.getOptions().getLaunchBounds());
+                rootTask.setBounds(r.pictureInPictureArgs.getSourceRectHint());
             }
             rootTask.setDeferTaskAppear(false);
 
diff --git a/services/core/java/com/android/server/wm/SafeActivityOptions.java b/services/core/java/com/android/server/wm/SafeActivityOptions.java
index 927604e..d92a1f4 100644
--- a/services/core/java/com/android/server/wm/SafeActivityOptions.java
+++ b/services/core/java/com/android/server/wm/SafeActivityOptions.java
@@ -18,6 +18,7 @@
 
 import static android.Manifest.permission.CONTROL_KEYGUARD;
 import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
+import static android.Manifest.permission.MANAGE_ACTIVITY_TASKS;
 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
 import static android.Manifest.permission.STATUS_BAR_SERVICE;
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
@@ -249,6 +250,14 @@
                 throw new SecurityException(msg);
             }
         }
+        if (options.getTransientLaunch() && !supervisor.mRecentTasks.isCallerRecents(callingUid)
+                && ActivityTaskManagerService.checkPermission(
+                        MANAGE_ACTIVITY_TASKS, callingPid, callingUid) == PERMISSION_DENIED) {
+            final String msg = "Permission Denial: starting transient launch from " + callerApp
+                    + ", pid=" + callingPid + ", uid=" + callingUid;
+            Slog.w(TAG, msg);
+            throw new SecurityException(msg);
+        }
         // Check if the caller is allowed to launch on the specified display area.
         final WindowContainerToken daToken = options.getLaunchTaskDisplayArea();
         TaskDisplayArea taskDisplayArea = daToken != null
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index f80e732..8cad165 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -173,11 +173,6 @@
 
             if (isSizeChanged) {
                 mRoundedCornerOverlay = displayContent.findRoundedCornerOverlays();
-            } else {
-                // Exclude rounded corner overlay from screenshot buffer. Rounded
-                // corner overlay windows are un-rotated during rotation animation
-                // for a seamless transition.
-                builder.setExcludeLayers(displayContent.findRoundedCornerOverlays());
             }
 
             SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
@@ -600,7 +595,7 @@
         }
 
         private SurfaceAnimator startDisplayRotation() {
-            return startAnimation(initializeBuilder()
+            SurfaceAnimator animator = startAnimation(initializeBuilder()
                             .setAnimationLeashParent(mDisplayContent.getSurfaceControl())
                             .setSurfaceControl(mDisplayContent.getWindowingLayer())
                             .setParentSurfaceControl(mDisplayContent.getSurfaceControl())
@@ -609,6 +604,13 @@
                             .build(),
                     createWindowAnimationSpec(mRotateEnterAnimation),
                     this::onAnimationEnd);
+
+            // Crop the animation leash to avoid extended wallpaper from showing over
+            // mBackColorSurface
+            Rect displayBounds = mDisplayContent.getBounds();
+            mDisplayContent.getPendingTransaction()
+                    .setWindowCrop(animator.mLeash, displayBounds.width(), displayBounds.height());
+            return animator;
         }
 
         private SurfaceAnimator startScreenshotAlphaAnimation() {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 1525fb3..e65f0bb 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -738,8 +738,9 @@
                     "removeTask:" + reason + " deferring removing taskId=" + mTaskId);
             return;
         }
+        final boolean isLeafTask = isLeafTask();
         removeImmediately(reason);
-        if (isLeafTask()) {
+        if (isLeafTask) {
             mAtmService.getTaskChangeNotificationController().notifyTaskRemoved(mTaskId);
 
             final TaskDisplayArea taskDisplayArea = getDisplayArea();
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 3e6546e..23adee6 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -1957,29 +1957,37 @@
     void computeConfigResourceOverrides(@NonNull Configuration inOutConfig,
             @NonNull Configuration parentConfig) {
         computeConfigResourceOverrides(inOutConfig, parentConfig, null /* overrideDisplayInfo */,
-                null /* compatInsets */);
+                null /* compatInsets */, false /* areBoundsLetterboxed */);
     }
 
     void computeConfigResourceOverrides(@NonNull Configuration inOutConfig,
-            @NonNull Configuration parentConfig, @Nullable DisplayInfo overrideDisplayInfo) {
+            @NonNull Configuration parentConfig, boolean areBoundsLetterboxed) {
+        computeConfigResourceOverrides(inOutConfig, parentConfig, null /* overrideDisplayInfo */,
+                null /* compatInsets */, areBoundsLetterboxed);
+    }
+
+    void computeConfigResourceOverrides(@NonNull Configuration inOutConfig,
+            @NonNull Configuration parentConfig, @Nullable DisplayInfo overrideDisplayInfo,
+            boolean areBoundsLetterboxed) {
         if (overrideDisplayInfo != null) {
             // Make sure the screen related configs can be computed by the provided display info.
             inOutConfig.screenLayout = Configuration.SCREENLAYOUT_UNDEFINED;
             invalidateAppBoundsConfig(inOutConfig);
         }
         computeConfigResourceOverrides(inOutConfig, parentConfig, overrideDisplayInfo,
-                null /* compatInsets */);
+                null /* compatInsets */, areBoundsLetterboxed);
     }
 
     void computeConfigResourceOverrides(@NonNull Configuration inOutConfig,
             @NonNull Configuration parentConfig,
-            @Nullable ActivityRecord.CompatDisplayInsets compatInsets) {
+            @Nullable ActivityRecord.CompatDisplayInsets compatInsets,
+            boolean areBoundsLetterboxed) {
         if (compatInsets != null) {
             // Make sure the app bounds can be computed by the compat insets.
             invalidateAppBoundsConfig(inOutConfig);
         }
         computeConfigResourceOverrides(inOutConfig, parentConfig, null /* overrideDisplayInfo */,
-                compatInsets);
+                compatInsets, areBoundsLetterboxed);
     }
 
     /**
@@ -2006,7 +2014,8 @@
      **/
     void computeConfigResourceOverrides(@NonNull Configuration inOutConfig,
             @NonNull Configuration parentConfig, @Nullable DisplayInfo overrideDisplayInfo,
-            @Nullable ActivityRecord.CompatDisplayInsets compatInsets) {
+            @Nullable ActivityRecord.CompatDisplayInsets compatInsets,
+            boolean areBoundsLetterboxed) {
         int windowingMode = inOutConfig.windowConfiguration.getWindowingMode();
         if (windowingMode == WINDOWING_MODE_UNDEFINED) {
             windowingMode = parentConfig.windowConfiguration.getWindowingMode();
@@ -2113,6 +2122,7 @@
                         : overrideScreenHeightDp;
             }
 
+            // TODO(b/238331848): Consider simplifying logic that computes smallestScreenWidthDp.
             if (inOutConfig.smallestScreenWidthDp
                     == Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
                 // When entering to or exiting from Pip, the PipTaskOrganizer will set the
@@ -2128,9 +2138,10 @@
                     // task, because they should not be affected by insets.
                     inOutConfig.smallestScreenWidthDp = (int) (0.5f
                             + Math.min(mTmpFullBounds.width(), mTmpFullBounds.height()) / density);
-                } else if (isEmbedded()) {
-                    // For embedded TFs, the smallest width should be updated. Otherwise, inherit
-                    // from the parent task would result in applications loaded wrong resource.
+                } else if (isEmbedded() || areBoundsLetterboxed || customContainerPolicy) {
+                    // For embedded TFs and activities that are letteboxed or eligible for size
+                    // compat mode, the smallest width should be updated. Otherwise, inherit from
+                    // the parent task would result in applications loaded wrong resource.
                     inOutConfig.smallestScreenWidthDp =
                             Math.min(inOutConfig.screenWidthDp, inOutConfig.screenHeightDp);
                 }
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 27d181f..8b71a34 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -527,11 +527,12 @@
                 mService.mRootWindowContainer.forAllTasks((task) -> {
                     boolean returnTask = !task.mCreatedByOrganizer;
                     task.updateTaskOrganizerState(returnTask /* skipTaskAppeared */);
-                    if (returnTask) {
-                        SurfaceControl outSurfaceControl = state.addTaskWithoutCallback(task,
+                    // It is possible for the task to not yet have a surface control, so ensure that
+                    // the update succeeded in setting the organizer for the task before returning
+                    if (task.isOrganized() && returnTask) {
+                        SurfaceControl taskLeash = state.addTaskWithoutCallback(task,
                                 "TaskOrganizerController.registerTaskOrganizer");
-                        taskInfos.add(
-                                new TaskAppearedInfo(task.getTaskInfo(), outSurfaceControl));
+                        taskInfos.add(new TaskAppearedInfo(task.getTaskInfo(), taskLeash));
                     }
                 });
             };
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 09f6110..91f69a5 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -46,6 +46,7 @@
 import static android.view.WindowManager.transitTypeToString;
 import static android.window.TransitionInfo.FLAG_DISPLAY_HAS_ALERT_WINDOWS;
 import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
+import static android.window.TransitionInfo.FLAG_IS_EMBEDDED;
 import static android.window.TransitionInfo.FLAG_IS_INPUT_METHOD;
 import static android.window.TransitionInfo.FLAG_IS_VOICE_INTERACTION;
 import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
@@ -84,11 +85,9 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.graphics.ColorUtils;
-import com.android.internal.inputmethod.SoftInputShowHideReason;
 import com.android.internal.protolog.ProtoLogGroup;
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.util.function.pooled.PooledLambda;
-import com.android.server.LocalServices;
 import com.android.server.inputmethod.InputMethodManagerInternal;
 
 import java.lang.annotation.Retention;
@@ -533,9 +532,14 @@
         }
         // Need to update layers on involved displays since they were all paused while
         // the animation played. This puts the layers back into the correct order.
-        for (int i = displays.size() - 1; i >= 0; --i) {
-            if (displays.valueAt(i) == null) continue;
-            displays.valueAt(i).assignChildLayers(t);
+        mController.mBuildingFinishLayers = true;
+        try {
+            for (int i = displays.size() - 1; i >= 0; --i) {
+                if (displays.valueAt(i) == null) continue;
+                displays.valueAt(i).assignChildLayers(t);
+            }
+        } finally {
+            mController.mBuildingFinishLayers = false;
         }
         if (rootLeash.isValid()) {
             t.reparent(rootLeash, null);
@@ -953,26 +957,6 @@
             }
         }
 
-        // Hiding IME/IME icon when starting quick-step with resents animation.
-        if (!mTargetDisplays.get(mRecentsDisplayId).isImeAttachedToApp()) {
-            // Hiding IME if IME window is not attached to app.
-            // Since some windowing mode is not proper to snapshot Task with IME window
-            // while the app transitioning to the next task (e.g. split-screen mode)
-            final InputMethodManagerInternal inputMethodManagerInternal =
-                    LocalServices.getService(InputMethodManagerInternal.class);
-            if (inputMethodManagerInternal != null) {
-                inputMethodManagerInternal.hideCurrentInputMethod(
-                        SoftInputShowHideReason.HIDE_RECENTS_ANIMATION);
-            }
-        } else {
-            // Disable IME icon explicitly when IME attached to the app in case
-            // IME icon might flickering while swiping to the next app task still
-            // in animating before the next app window focused, or IME icon
-            // persists on the bottom when swiping the task to recents.
-            InputMethodManagerInternal.get().updateImeWindowStatus(
-                    true /* disableImeIcon */);
-        }
-
         // The rest of this function handles nav-bar reparenting
 
         if (!dc.getDisplayPolicy().shouldAttachNavBarToAppDuringTransition()
@@ -1756,6 +1740,9 @@
             if (occludesKeyguard(wc)) {
                 flags |= FLAG_OCCLUDES_KEYGUARD;
             }
+            if (wc.isEmbedded()) {
+                flags |= FLAG_IS_EMBEDDED;
+            }
             return flags;
         }
     }
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index dbc2c5f..88572a9 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -100,6 +100,14 @@
     // TODO(b/188595497): remove when not needed.
     final StatusBarManagerInternal mStatusBar;
 
+    /**
+     * `true` when building surface layer order for the finish transaction. We want to prevent
+     * wm from touching z-order of surfaces during transitions, but we still need to be able to
+     * calculate the layers for the finishTransaction. So, when assigning layers into the finish
+     * transaction, set this to true so that the {@link canAssignLayers} will allow it.
+     */
+    boolean mBuildingFinishLayers = false;
+
     TransitionController(ActivityTaskManagerService atm,
             TaskSnapshotController taskSnapshotController,
             TransitionTracer transitionTracer) {
@@ -309,6 +317,15 @@
         return false;
     }
 
+    /**
+     * Whether WM can assign layers to window surfaces at this time. This is usually false while
+     * playing, but can be "opened-up" for certain transition operations like calculating layers
+     * for finishTransaction.
+     */
+    boolean canAssignLayers() {
+        return mBuildingFinishLayers || !isPlaying();
+    }
+
     @WindowConfiguration.WindowingMode
     int getWindowingModeAtStart(@NonNull WindowContainer wc) {
         if (mCollectingTransition == null) return wc.getWindowingMode();
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 00ee94a..bce131b 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -429,6 +429,13 @@
         if (insetsTypes == null || insetsTypes.length == 0) {
             throw new IllegalArgumentException("Insets type not specified.");
         }
+        if (mDisplayContent == null) {
+            // This is possible this container is detached when WM shell is responding to a previous
+            // request. WM shell will be updated when this container is attached again and the
+            // insets need to be updated.
+            Slog.w(TAG, "Can't add local rect insets source provider when detached. " + this);
+            return;
+        }
         if (mLocalInsetsSourceProviders == null) {
             mLocalInsetsSourceProviders = new SparseArray<>();
         }
@@ -1014,6 +1021,9 @@
         if (dc != null && dc != this) {
             dc.getPendingTransaction().merge(mPendingTransaction);
         }
+        if (dc != this && mLocalInsetsSourceProviders != null) {
+            mLocalInsetsSourceProviders.clear();
+        }
         for (int i = mChildren.size() - 1; i >= 0; --i) {
             final WindowContainer child = mChildren.get(i);
             child.onDisplayChanged(dc);
@@ -2476,7 +2486,7 @@
     void assignLayer(Transaction t, int layer) {
         // Don't assign layers while a transition animation is playing
         // TODO(b/173528115): establish robust best-practices around z-order fighting.
-        if (mTransitionController.isPlaying()) return;
+        if (!mTransitionController.canAssignLayers()) return;
         final boolean changed = layer != mLastLayer || mLastRelativeToLayer != null;
         if (mSurfaceControl != null && changed) {
             setLayer(t, layer);
@@ -3212,6 +3222,10 @@
 
     void resetSurfacePositionForAnimationLeash(Transaction t) {
         t.setPosition(mSurfaceControl, 0, 0);
+        if (mSyncState != SYNC_STATE_NONE && t != mSyncTransaction) {
+            // Avoid restoring to old position if the sync transaction is applied later.
+            mSyncTransaction.setPosition(mSurfaceControl, 0, 0);
+        }
         mLastSurfacePosition.set(0, 0);
     }
 
@@ -3752,6 +3766,15 @@
      * hierarchy change implies a configuration change.
      */
     private void onSyncReparent(WindowContainer oldParent, WindowContainer newParent) {
+        // Check if this is changing displays. If so, mark the old display as "ready" for
+        // transitions. This is to work around the problem where setting readiness against this
+        // container will only set the new display as ready and leave the old display as unready.
+        if (mSyncState != SYNC_STATE_NONE && oldParent != null
+                && oldParent.getDisplayContent() != null && (newParent == null
+                        || oldParent.getDisplayContent() != newParent.getDisplayContent())) {
+            mTransitionController.setReady(oldParent.getDisplayContent());
+        }
+
         if (newParent == null || newParent.mSyncState == SYNC_STATE_NONE) {
             if (mSyncState == SYNC_STATE_NONE) {
                 return;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index bcf05a6f..00e8d8b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -46,7 +46,6 @@
 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
-import static android.provider.Settings.Global.DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR;
 import static android.provider.Settings.Global.DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH;
 import static android.view.ContentRecordingSession.RECORD_CONTENT_TASK;
 import static android.view.Display.DEFAULT_DISPLAY;
@@ -652,7 +651,7 @@
     // Whether the system should use BLAST for ViewRootImpl
     final boolean mUseBLAST;
     // Whether to enable BLASTSyncEngine Transaction passing.
-    final boolean mUseBLASTSync = true;
+    static final boolean USE_BLAST_SYNC = true;
 
     final BLASTSyncEngine mSyncEngine;
 
@@ -787,8 +786,6 @@
                 DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES);
         private final Uri mDevEnableNonResizableMultiWindowUri = Settings.Global.getUriFor(
                 DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW);
-        private final Uri mRenderShadowsInCompositorUri = Settings.Global.getUriFor(
-                DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR);
         private final Uri mDisplaySettingsPathUri = Settings.Global.getUriFor(
                 DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH);
         private final Uri mMaximumObscuringOpacityForTouchUri = Settings.Global.getUriFor(
@@ -1020,7 +1017,7 @@
     private int mExitAnimId, mEnterAnimId;
 
     /** The display that the rotation animation is applying to. */
-    private int mFrozenDisplayId;
+    private int mFrozenDisplayId = INVALID_DISPLAY;
 
     /** Skip repeated ActivityRecords initialization. Note that AppWindowsToken's version of this
      * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
@@ -1050,8 +1047,11 @@
     boolean mWindowsChanged = false;
 
     public interface WindowChangeListener {
-        public void windowsChanged();
-        public void focusChanged();
+        /** Notify on windows changed */
+        void windowsChanged();
+
+        /** Notify on focus changed */
+        void focusChanged();
     }
 
     final HighRefreshRateDenylist mHighRefreshRateDenylist;
@@ -1201,7 +1201,8 @@
                 com.android.internal.R.bool.config_hasPermanentDpad);
         mInTouchMode = context.getResources().getBoolean(
                 com.android.internal.R.bool.config_defaultInTouchMode);
-        inputManager.setInTouchMode(mInTouchMode, MY_PID, MY_UID, true /* hasPermission */);
+        inputManager.setInTouchMode(mInTouchMode, MY_PID, MY_UID, /* hasPermission= */ true,
+                DEFAULT_DISPLAY);
         mDrawLockTimeoutMillis = context.getResources().getInteger(
                 com.android.internal.R.integer.config_drawLockTimeoutMillis);
         mAllowAnimationsInLowPowerMode = context.getResources().getBoolean(
@@ -2128,7 +2129,6 @@
     }
 
     void clearTouchableRegion(Session session, IWindow client) {
-        int uid = Binder.getCallingUid();
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
@@ -2304,12 +2304,6 @@
                         || (flagChanges & FLAG_DISMISS_KEYGUARD) != 0)) {
                     win.mActivityRecord.checkKeyguardFlagsChanged();
                 }
-                if (((attrChanges & LayoutParams.ACCESSIBILITY_TITLE_CHANGED) != 0)
-                        && (mAccessibilityController.hasCallbacks())) {
-                    // No move or resize, but the controller checks for title changes as well
-                    mAccessibilityController.onSomeWindowResizedOrMovedWithCallingUid(
-                            uid, win.getDisplayContent().getDisplayId());
-                }
 
                 if ((privateFlagChanges & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) {
                     updateNonSystemOverlayWindowsVisibilityIfNeeded(
@@ -2546,7 +2540,7 @@
             }
             win.mInRelayout = false;
 
-            if (mUseBLASTSync && win.useBLASTSync() && viewVisibility != View.GONE
+            if (USE_BLAST_SYNC && win.useBLASTSync() && viewVisibility != View.GONE
                     && (win.mSyncSeqId > win.mLastSeqIdSentToRelayout)) {
                 win.markRedrawForSyncReported();
 
@@ -3824,7 +3818,9 @@
                                                       /* printlog= */ false);
             final long token = Binder.clearCallingIdentity();
             try {
-                if (mInputManager.setInTouchMode(mode, pid, uid, hasPermission)) {
+                // TODO(b/198499018): Add displayId parameter indicating the target display.
+                // For now, will just pass DEFAULT_DISPLAY for displayId.
+                if (mInputManager.setInTouchMode(mode, pid, uid, hasPermission, DEFAULT_DISPLAY)) {
                     mInTouchMode = mode;
                 }
             } finally {
@@ -4319,7 +4315,7 @@
                 mDisplayChangeController = controller;
             }
         } catch (RemoteException e) {
-            throw new RuntimeException("Unable to set rotation controller");
+            throw new RuntimeException("Unable to set rotation controller", e);
         }
     }
 
@@ -5638,7 +5634,7 @@
     }
 
     public boolean useBLASTSync() {
-        return mUseBLASTSync;
+        return USE_BLAST_SYNC;
     }
 
     @Override
@@ -5962,10 +5958,10 @@
     }
 
     void makeWindowFreezingScreenIfNeededLocked(WindowState w) {
-        // If the screen is currently frozen or off, then keep
-        // it frozen/off until this window draws at its new
-        // orientation.
-        if (!w.mToken.okToDisplay() && mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
+        // If the screen is currently frozen, then keep it frozen until this window draws at its
+        // new orientation.
+        if (mFrozenDisplayId != INVALID_DISPLAY && mFrozenDisplayId == w.getDisplayId()
+                && mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
             ProtoLog.v(WM_DEBUG_ORIENTATION, "Changing surface while display frozen: %s", w);
             w.setOrientationChanging(true);
             if (mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_NONE) {
@@ -6498,12 +6494,12 @@
         }
     }
 
-    private void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) {
+    private void dumpPolicyLocked(PrintWriter pw, String[] args) {
         pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
         mPolicy.dump("    ", pw, args);
     }
 
-    private void dumpAnimatorLocked(PrintWriter pw, String[] args, boolean dumpAll) {
+    private void dumpAnimatorLocked(PrintWriter pw, boolean dumpAll) {
         pw.println("WINDOW MANAGER ANIMATOR STATE (dumpsys window animator)");
         mAnimator.dumpLocked(pw, "    ", dumpAll);
     }
@@ -6529,7 +6525,7 @@
         pw.println(ProtoLogImpl.getSingleInstance().getStatus());
     }
 
-    private void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) {
+    private void dumpSessionsLocked(PrintWriter pw) {
         pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
         for (int i=0; i<mSessions.size(); i++) {
             Session s = mSessions.valueAt(i);
@@ -6594,7 +6590,7 @@
                 }
             }
         }
-        if (mForceRemoves != null && mForceRemoves.size() > 0) {
+        if (mForceRemoves != null && !mForceRemoves.isEmpty()) {
             pw.println();
             pw.println("  Windows force removing:");
             for (int i=mForceRemoves.size()-1; i>=0; i--) {
@@ -6609,7 +6605,7 @@
                 }
             }
         }
-        if (mDestroySurface.size() > 0) {
+        if (!mDestroySurface.isEmpty()) {
             pw.println();
             pw.println("  Windows waiting to destroy their surface:");
             for (int i=mDestroySurface.size()-1; i>=0; i--) {
@@ -6626,7 +6622,7 @@
                 }
             }
         }
-        if (mResizingWindows.size() > 0) {
+        if (!mResizingWindows.isEmpty()) {
             pw.println();
             pw.println("  Windows waiting to resize:");
             for (int i=mResizingWindows.size()-1; i>=0; i--) {
@@ -6733,8 +6729,7 @@
         }
     }
 
-    private boolean dumpWindows(PrintWriter pw, String name, String[] args, int opti,
-            boolean dumpAll) {
+    private boolean dumpWindows(PrintWriter pw, String name, boolean dumpAll) {
         final ArrayList<WindowState> windows = new ArrayList();
         if ("apps".equals(name) || "visible".equals(name) || "visible-apps".equals(name)) {
             final boolean appsOnly = name.contains("apps");
@@ -6757,7 +6752,7 @@
             }
         }
 
-        if (windows.size() <= 0) {
+        if (windows.isEmpty()) {
             return false;
         }
 
@@ -6888,17 +6883,17 @@
                 return;
             } else if ("policy".equals(cmd) || "p".equals(cmd)) {
                 synchronized (mGlobalLock) {
-                    dumpPolicyLocked(pw, args, true);
+                    dumpPolicyLocked(pw, args);
                 }
                 return;
             } else if ("animator".equals(cmd) || "a".equals(cmd)) {
                 synchronized (mGlobalLock) {
-                    dumpAnimatorLocked(pw, args, true);
+                    dumpAnimatorLocked(pw, true);
                 }
                 return;
             } else if ("sessions".equals(cmd) || "s".equals(cmd)) {
                 synchronized (mGlobalLock) {
-                    dumpSessionsLocked(pw, true);
+                    dumpSessionsLocked(pw);
                 }
                 return;
             } else if ("displays".equals(cmd) || "d".equals(cmd)) {
@@ -6945,7 +6940,7 @@
                 return;
             } else {
                 // Dumping a single name?
-                if (!dumpWindows(pw, cmd, args, opti, dumpAll)) {
+                if (!dumpWindows(pw, cmd, dumpAll)) {
                     pw.println("Bad window command, or no windows match: " + cmd);
                     pw.println("Use -h for help.");
                 }
@@ -6965,17 +6960,17 @@
             if (dumpAll) {
                 pw.println(separator);
             }
-            dumpPolicyLocked(pw, args, dumpAll);
+            dumpPolicyLocked(pw, args);
             pw.println();
             if (dumpAll) {
                 pw.println(separator);
             }
-            dumpAnimatorLocked(pw, args, dumpAll);
+            dumpAnimatorLocked(pw, dumpAll);
             pw.println();
             if (dumpAll) {
                 pw.println(separator);
             }
-            dumpSessionsLocked(pw, dumpAll);
+            dumpSessionsLocked(pw);
             pw.println();
             if (dumpAll) {
                 pw.println(separator);
@@ -8256,7 +8251,7 @@
                         .setContainerLayer()
                         .setName("IME Handwriting Surface")
                         .setCallsite("getHandwritingSurfaceForDisplay")
-                        .setParent(dc.getOverlayLayer())
+                        .setParent(dc.getSurfaceControl())
                         .build();
             }
         }
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 97dcb75..6bb5ece 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -817,7 +817,7 @@
                 }
                 if (parent.isAllowedToEmbedActivity(activity) != EMBEDDING_ALLOWED) {
                     final Throwable exception = new SecurityException(
-                            "The task fragment is not trusted to embed the given activity.");
+                            "The task fragment is not allowed to embed the given activity.");
                     sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
                     break;
                 }
@@ -827,11 +827,6 @@
                     sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
                     break;
                 }
-                if (parent.smallerThanMinDimension(activity)) {
-                    sendMinimumDimensionViolation(parent, activity.getMinDimensions(),
-                            errorCallbackToken, "reparentActivityToTask");
-                    break;
-                }
 
                 activity.reparent(parent, POSITION_TOP);
                 effects |= TRANSACT_EFFECTS_LIFECYCLE;
@@ -1240,8 +1235,12 @@
                         + " task=" + task);
                 return false;
             }
-            if (!ArrayUtils.contains(hop.getActivityTypes(), task.getActivityType())
-                    || !ArrayUtils.contains(hop.getWindowingModes(), task.getWindowingMode())) {
+            if (!ArrayUtils.isEmpty(hop.getActivityTypes())
+                    && !ArrayUtils.contains(hop.getActivityTypes(), task.getActivityType())) {
+                return false;
+            }
+            if (!ArrayUtils.isEmpty(hop.getWindowingModes())
+                    && !ArrayUtils.contains(hop.getWindowingModes(), task.getWindowingMode())) {
                 return false;
             }
             if (isLockTaskModeViolation(finalNewParent, task, isInLockTaskMode)) {
@@ -1673,10 +1672,10 @@
             // We are reparenting activities to a new embedded TaskFragment, this operation is only
             // allowed if the new parent is trusted by all reparent activities.
             final boolean isEmbeddingDisallowed = oldParent.forAllActivities(activity ->
-                    newParentTF.isAllowedToEmbedActivity(activity) == EMBEDDING_ALLOWED);
+                    newParentTF.isAllowedToEmbedActivity(activity) != EMBEDDING_ALLOWED);
             if (isEmbeddingDisallowed) {
                 final Throwable exception = new SecurityException(
-                        "The new parent is not trusted to embed the activities.");
+                        "The new parent is not allowed to embed the activities.");
                 sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
                 return;
             }
@@ -1693,14 +1692,6 @@
             sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
             return;
         }
-        final Point minDimensions = oldParent.calculateMinDimension();
-        final Rect newParentBounds = newParentTF.getBounds();
-        if (newParentBounds.width() < minDimensions.x
-                || newParentBounds.height() < minDimensions.y) {
-            sendMinimumDimensionViolation(newParentTF, minDimensions, errorCallbackToken,
-                    "reparentTaskFragment");
-            return;
-        }
         while (oldParent.hasChild()) {
             oldParent.getChildAt(0).reparent(newParentTF, POSITION_TOP);
         }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 46091d8..658b6ac 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -215,7 +215,6 @@
 import android.os.Trace;
 import android.os.WorkSource;
 import android.provider.Settings;
-import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.DisplayMetrics;
 import android.util.MergedConfiguration;
@@ -1703,7 +1702,7 @@
                 mFrozenInsetsState != null ? mFrozenInsetsState : getMergedInsetsState();
         final InsetsState insetsStateForWindow = insetsPolicy
                 .enforceInsetsPolicyForTarget(insetTypeProvidedByWindow,
-                        getWindowingMode(), isAlwaysOnTop(), rawInsetsState);
+                        getWindowingMode(), isAlwaysOnTop(), mAttrs.type, rawInsetsState);
         return insetsPolicy.adjustInsetsForWindow(this, insetsStateForWindow,
                 includeTransient);
     }
@@ -3461,10 +3460,6 @@
         return mClient.asBinder().isBinderAlive();
     }
 
-    boolean isClosing() {
-        return mAnimatingExit || (mActivityRecord != null && mActivityRecord.isClosingOrEnteringPip());
-    }
-
     void sendAppVisibilityToClients() {
         super.sendAppVisibilityToClients();
 
@@ -4703,19 +4698,6 @@
         if (mActivityRecord != null) {
             windowInfo.activityToken = mActivityRecord.token;
         }
-        windowInfo.title = mAttrs.accessibilityTitle;
-        // Panel windows have no public way to set the a11y title directly. Use the
-        // regular title as a fallback.
-        final boolean isPanelWindow = (mAttrs.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW)
-                && (mAttrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW);
-        // Accessibility overlays should have titles that work for accessibility, and can't set
-        // the a11y title themselves.
-        final boolean isAccessibilityOverlay =
-                windowInfo.type == WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
-        if (TextUtils.isEmpty(windowInfo.title) && (isPanelWindow || isAccessibilityOverlay)) {
-            final CharSequence title = mAttrs.getTitle();
-            windowInfo.title = TextUtils.isEmpty(title) ? null : title;
-        }
         windowInfo.accessibilityIdOfAnchor = mAttrs.accessibilityIdOfAnchor;
         windowInfo.focused = isFocused();
         Task task = getTask();
@@ -5489,17 +5471,19 @@
     }
 
     private void updateScaleIfNeeded() {
-        if (mIsChildWindow) {
-            // Child window follows parent's scale.
-            return;
-        }
         if (!isVisibleRequested() && !(mIsWallpaper && mToken.isVisible())) {
             // Skip if it is requested to be invisible, but if it is wallpaper, it may be in
             // transition that still needs to update the scale for zoom effect.
             return;
         }
-        float newHScale = mHScale * mGlobalScale * mWallpaperScale;
-        float newVScale = mVScale * mGlobalScale * mWallpaperScale;
+        float globalScale = mGlobalScale;
+        final WindowState parent = getParentWindow();
+        if (parent != null) {
+            // Undo parent's scale because the child surface has inherited scale from parent.
+            globalScale *= parent.mInvGlobalScale;
+        }
+        final float newHScale = mHScale * globalScale * mWallpaperScale;
+        final float newVScale = mVScale * globalScale * mWallpaperScale;
         if (mLastHScale != newHScale || mLastVScale != newVScale) {
             getSyncTransaction().setMatrix(mSurfaceControl, newHScale, 0, 0, newVScale);
             mLastHScale = newHScale;
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index fd379bf..4a5c473 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -126,8 +126,10 @@
         try {
             transaction.hide(mSurfaceControl);
             if (mAnimator.mIsWallpaper) {
+                final DisplayContent dc = mAnimator.mWin.getDisplayContent();
                 EventLog.writeEvent(EventLogTags.WM_WALLPAPER_SURFACE,
-                        mAnimator.mWin.getDisplayId(), 0 /* request hidden */);
+                        dc.mDisplayId, 0 /* request hidden */,
+                        String.valueOf(dc.mWallpaperController.getWallpaperTarget()));
             }
         } catch (RuntimeException e) {
             Slog.w(TAG, "Exception hiding surface in " + this);
@@ -266,8 +268,10 @@
         setShown(true);
         t.show(mSurfaceControl);
         if (mAnimator.mIsWallpaper) {
+            final DisplayContent dc = mAnimator.mWin.getDisplayContent();
             EventLog.writeEvent(EventLogTags.WM_WALLPAPER_SURFACE,
-                    mAnimator.mWin.getDisplayId(), 1 /* request shown */);
+                    dc.mDisplayId, 1 /* request shown */,
+                    String.valueOf(dc.mWallpaperController.getWallpaperTarget()));
         }
         return true;
     }
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 437c934..bbb21f8 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -362,7 +362,7 @@
     @Override
     void assignLayer(SurfaceControl.Transaction t, int layer) {
         if (mRoundedCornerOverlay) {
-            super.assignLayer(t, WindowManagerPolicy.SCREEN_DECOR_DISPLAY_OVERLAY_LAYER);
+            super.assignLayer(t, WindowManagerPolicy.COLOR_FADE_LAYER + 1);
         } else {
             super.assignLayer(t, layer);
         }
@@ -372,7 +372,7 @@
     SurfaceControl.Builder makeSurface() {
         final SurfaceControl.Builder builder = super.makeSurface();
         if (mRoundedCornerOverlay) {
-            builder.setParent(getDisplayContent().getOverlayLayer());
+            builder.setParent(null);
         }
         return builder;
     }
diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
index dbc1a00..af5718f 100644
--- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
+++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
@@ -113,7 +113,7 @@
 
     uint64_t bytesConsumed = 0;
     while (bytesConsumed < bytesToConsume) {
-        if (CC_UNLIKELY(batch.totalVmas > 0)) {
+        if (CC_UNLIKELY(batch.totalVmas == 0)) {
             // No more vmas to consume
             break;
         }
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 2cd6cf3..74ed3df 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -133,6 +133,7 @@
     jmethodID getContextForDisplay;
     jmethodID notifyDropWindow;
     jmethodID getParentSurfaceForPointers;
+    jmethodID isPerDisplayTouchModeEnabled;
 } gServiceClassInfo;
 
 static struct {
@@ -265,7 +266,7 @@
     virtual ~NativeInputManager();
 
 public:
-    NativeInputManager(jobject contextObj, jobject serviceObj, const sp<Looper>& looper);
+    NativeInputManager(jobject serviceObj, const sp<Looper>& looper);
 
     inline sp<InputManagerInterface> getInputManager() const { return mInputManager; }
 
@@ -355,6 +356,10 @@
     virtual PointerIconStyle getCustomPointerIconId();
     virtual void onPointerDisplayIdChanged(int32_t displayId, float xPos, float yPos);
 
+    /* --- If touch mode is enabled per display or global --- */
+
+    virtual bool isPerDisplayTouchModeEnabled();
+
 private:
     sp<InputManagerInterface> mInputManager;
 
@@ -398,23 +403,17 @@
     } mLocked GUARDED_BY(mLock);
 
     std::atomic<bool> mInteractive;
-
     void updateInactivityTimeoutLocked();
     void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
     void ensureSpriteControllerLocked();
     sp<SurfaceControl> getParentSurfaceForPointers(int displayId);
     static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
 
-    static inline JNIEnv* jniEnv() {
-        return AndroidRuntime::getJNIEnv();
-    }
+    static inline JNIEnv* jniEnv() { return AndroidRuntime::getJNIEnv(); }
 };
 
-
-
-NativeInputManager::NativeInputManager(jobject contextObj,
-        jobject serviceObj, const sp<Looper>& looper) :
-        mLooper(looper), mInteractive(true) {
+NativeInputManager::NativeInputManager(jobject serviceObj, const sp<Looper>& looper)
+      : mLooper(looper), mInteractive(true) {
     JNIEnv* env = jniEnv();
 
     mServiceObj = env->NewGlobalRef(serviceObj);
@@ -429,7 +428,6 @@
         mLocked.pointerDisplayId = ADISPLAY_ID_DEFAULT;
     }
     mInteractive = true;
-
     InputManager* im = new InputManager(this, this);
     mInputManager = im;
     defaultServiceManager()->addService(String16("inputflinger"), im);
@@ -1488,6 +1486,16 @@
     mInputManager->getClassifier().setMotionClassifierEnabled(enabled);
 }
 
+bool NativeInputManager::isPerDisplayTouchModeEnabled() {
+    JNIEnv* env = jniEnv();
+    jboolean enabled =
+            env->CallBooleanMethod(mServiceObj, gServiceClassInfo.isPerDisplayTouchModeEnabled);
+    if (checkAndClearExceptionFromCallback(env, "isPerDisplayTouchModeEnabled")) {
+        return false;
+    }
+    return static_cast<bool>(enabled);
+}
+
 // ----------------------------------------------------------------------------
 
 static NativeInputManager* getNativeInputManager(JNIEnv* env, jobject clazz) {
@@ -1495,16 +1503,15 @@
             env->GetLongField(clazz, gNativeInputManagerServiceImpl.mPtr));
 }
 
-static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
-        jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
+static jlong nativeInit(JNIEnv* env, jclass /* clazz */, jobject serviceObj,
+                        jobject messageQueueObj) {
     sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
     if (messageQueue == nullptr) {
         jniThrowRuntimeException(env, "MessageQueue is not initialized.");
         return 0;
     }
 
-    NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
-            messageQueue->getLooper());
+    NativeInputManager* im = new NativeInputManager(serviceObj, messageQueue->getLooper());
     im->incStrong(0);
     return reinterpret_cast<jlong>(im);
 }
@@ -1677,11 +1684,11 @@
 }
 
 static jboolean nativeSetInTouchMode(JNIEnv* env, jobject nativeImplObj, jboolean inTouchMode,
-                                     jint pid, jint uid, jboolean hasPermission) {
+                                     jint pid, jint uid, jboolean hasPermission, jint displayId) {
     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     return im->getInputManager()->getDispatcher().setInTouchMode(inTouchMode, pid, uid,
-                                                                 hasPermission);
+                                                                 hasPermission, displayId);
 }
 
 static void nativeSetMaximumObscuringOpacityForTouch(JNIEnv* env, jobject nativeImplObj,
@@ -2312,7 +2319,7 @@
 static const JNINativeMethod gInputManagerMethods[] = {
         /* name, signature, funcPtr */
         {"init",
-         "(Lcom/android/server/input/InputManagerService;Landroid/content/Context;Landroid/os/"
+         "(Lcom/android/server/input/InputManagerService;Landroid/os/"
          "MessageQueue;)J",
          (void*)nativeInit},
         {"start", "()V", (void*)nativeStart},
@@ -2330,7 +2337,7 @@
         {"removeInputChannel", "(Landroid/os/IBinder;)V", (void*)nativeRemoveInputChannel},
         {"pilferPointers", "(Landroid/os/IBinder;)V", (void*)nativePilferPointers},
         {"setInputFilterEnabled", "(Z)V", (void*)nativeSetInputFilterEnabled},
-        {"setInTouchMode", "(ZIIZ)Z", (void*)nativeSetInTouchMode},
+        {"setInTouchMode", "(ZIIZI)Z", (void*)nativeSetInTouchMode},
         {"setMaximumObscuringOpacityForTouch", "(F)V",
          (void*)nativeSetMaximumObscuringOpacityForTouch},
         {"injectInputEvent", "(Landroid/view/InputEvent;ZIIII)I", (void*)nativeInjectInputEvent},
@@ -2536,6 +2543,9 @@
     GET_METHOD_ID(gServiceClassInfo.getParentSurfaceForPointers, clazz,
                   "getParentSurfaceForPointers", "(I)J");
 
+    GET_METHOD_ID(gServiceClassInfo.isPerDisplayTouchModeEnabled, clazz,
+                  "isPerDisplayTouchModeEnabled", "()Z");
+
     // InputDevice
 
     FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index cbd5743..b4cade3 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -11608,34 +11608,32 @@
                 && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
                 || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_ENABLE_SYSTEM_APP)));
 
-        synchronized (getLockObject()) {
-            final boolean isDemo = isCurrentUserDemo();
-            int userId = caller.getUserId();
-            long id = mInjector.binderClearCallingIdentity();
-            try {
-                if (VERBOSE_LOG) {
-                    Slogf.v(LOG_TAG, "installing " + packageName + " for " + userId);
-                }
-
-                Preconditions.checkArgument(isDemo || isSystemApp(mIPackageManager, packageName,
-                        getProfileParentId(userId)), "Only system apps can be enabled this way");
-
-                // Install the app.
-                mIPackageManager.installExistingPackageAsUser(packageName, userId,
-                        PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
-                        PackageManager.INSTALL_REASON_POLICY, null);
-                if (isDemo) {
-                    // Ensure the app is also ENABLED for demo users.
-                    mIPackageManager.setApplicationEnabledSetting(packageName,
-                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
-                            PackageManager.DONT_KILL_APP, userId, "DevicePolicyManager");
-                }
-            } catch (RemoteException re) {
-                // shouldn't happen
-                Slogf.wtf(LOG_TAG, "Failed to install " + packageName, re);
-            } finally {
-                mInjector.binderRestoreCallingIdentity(id);
+        final boolean isDemo = isCurrentUserDemo();
+        int userId = caller.getUserId();
+        long id = mInjector.binderClearCallingIdentity();
+        try {
+            if (VERBOSE_LOG) {
+                Slogf.v(LOG_TAG, "installing " + packageName + " for " + userId);
             }
+
+            Preconditions.checkArgument(isDemo || isSystemApp(mIPackageManager, packageName,
+                    getProfileParentId(userId)), "Only system apps can be enabled this way");
+
+            // Install the app.
+            mIPackageManager.installExistingPackageAsUser(packageName, userId,
+                    PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
+                    PackageManager.INSTALL_REASON_POLICY, null);
+            if (isDemo) {
+                // Ensure the app is also ENABLED for demo users.
+                mIPackageManager.setApplicationEnabledSetting(packageName,
+                        PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+                        PackageManager.DONT_KILL_APP, userId, "DevicePolicyManager");
+            }
+        } catch (RemoteException re) {
+            // shouldn't happen
+            Slogf.wtf(LOG_TAG, "Failed to install " + packageName, re);
+        } finally {
+            mInjector.binderRestoreCallingIdentity(id);
         }
         DevicePolicyEventLogger
                 .createEvent(DevicePolicyEnums.ENABLE_SYSTEM_APP)
@@ -11653,45 +11651,43 @@
                 || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_ENABLE_SYSTEM_APP)));
 
         int numberOfAppsInstalled = 0;
-        synchronized (getLockObject()) {
-            long id = mInjector.binderClearCallingIdentity();
-            try {
-                final int parentUserId = getProfileParentId(caller.getUserId());
-                List<ResolveInfo> activitiesToEnable = mIPackageManager
-                        .queryIntentActivities(intent,
-                                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                                PackageManager.MATCH_DIRECT_BOOT_AWARE
-                                        | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
-                                parentUserId)
-                        .getList();
+        long id = mInjector.binderClearCallingIdentity();
+        try {
+            final int parentUserId = getProfileParentId(caller.getUserId());
+            List<ResolveInfo> activitiesToEnable = mIPackageManager
+                    .queryIntentActivities(intent,
+                            intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+                            PackageManager.MATCH_DIRECT_BOOT_AWARE
+                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
+                            parentUserId)
+                    .getList();
 
-                if (VERBOSE_LOG) {
-                    Slogf.d(LOG_TAG, "Enabling system activities: " + activitiesToEnable);
-                }
-                if (activitiesToEnable != null) {
-                    for (ResolveInfo info : activitiesToEnable) {
-                        if (info.activityInfo != null) {
-                            String packageName = info.activityInfo.packageName;
-                            if (isSystemApp(mIPackageManager, packageName, parentUserId)) {
-                                numberOfAppsInstalled++;
-                                mIPackageManager.installExistingPackageAsUser(packageName,
-                                        caller.getUserId(),
-                                        PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
-                                        PackageManager.INSTALL_REASON_POLICY, null);
-                            } else {
-                                Slogf.d(LOG_TAG, "Not enabling " + packageName + " since is not a"
-                                        + " system app");
-                            }
+            if (VERBOSE_LOG) {
+                Slogf.d(LOG_TAG, "Enabling system activities: " + activitiesToEnable);
+            }
+            if (activitiesToEnable != null) {
+                for (ResolveInfo info : activitiesToEnable) {
+                    if (info.activityInfo != null) {
+                        String packageName = info.activityInfo.packageName;
+                        if (isSystemApp(mIPackageManager, packageName, parentUserId)) {
+                            numberOfAppsInstalled++;
+                            mIPackageManager.installExistingPackageAsUser(packageName,
+                                    caller.getUserId(),
+                                    PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
+                                    PackageManager.INSTALL_REASON_POLICY, null);
+                        } else {
+                            Slogf.d(LOG_TAG, "Not enabling " + packageName + " since is not a"
+                                    + " system app");
                         }
                     }
                 }
-            } catch (RemoteException e) {
-                // shouldn't happen
-                Slogf.wtf(LOG_TAG, "Failed to resolve intent for: " + intent);
-                return 0;
-            } finally {
-                mInjector.binderRestoreCallingIdentity(id);
             }
+        } catch (RemoteException e) {
+            // shouldn't happen
+            Slogf.wtf(LOG_TAG, "Failed to resolve intent for: " + intent);
+            return 0;
+        } finally {
+            mInjector.binderRestoreCallingIdentity(id);
         }
         DevicePolicyEventLogger
                 .createEvent(DevicePolicyEnums.ENABLE_SYSTEM_APP_WITH_INTENT)
@@ -18000,7 +17996,7 @@
                 Slogf.i(LOG_TAG, "Account removed from the primary user.");
             } else {
                 // TODO(174768447): Revisit start activity logic.
-                final Intent removeIntent = result.getParcelable(AccountManager.KEY_INTENT);
+                final Intent removeIntent = result.getParcelable(AccountManager.KEY_INTENT, android.content.Intent.class);
                 removeIntent.addFlags(FLAG_ACTIVITY_NEW_TASK);
                 if (removeIntent != null) {
                     Slogf.i(LOG_TAG, "Starting activity to remove account");
@@ -18622,9 +18618,10 @@
         Objects.requireNonNull(strings, "strings must be provided.");
 
         mInjector.binderWithCleanCallingIdentity(() -> {
-            if (mDeviceManagementResourcesProvider.updateStrings(strings))
-            sendStringsUpdatedBroadcast(
-                    strings.stream().map(s -> s.getStringId()).collect(Collectors.toList()));
+            if (mDeviceManagementResourcesProvider.updateStrings(strings)) {
+                sendStringsUpdatedBroadcast(
+                        strings.stream().map(s -> s.getStringId()).collect(Collectors.toList()));
+            }
         });
     }
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
index 84e89a0..06cbe78 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
@@ -134,7 +134,7 @@
     public void handleMessage(Message msg) {
         switch (msg.what) {
             case LOG_NETWORK_EVENT_MSG: {
-                final NetworkEvent networkEvent = msg.getData().getParcelable(NETWORK_EVENT_KEY);
+                final NetworkEvent networkEvent = msg.getData().getParcelable(NETWORK_EVENT_KEY, android.app.admin.NetworkEvent.class);
                 if (networkEvent != null) {
                     Bundle notificationExtras = null;
                     synchronized (NetworkLoggingHandler.this) {
diff --git a/services/midi/java/com/android/server/midi/MidiService.java b/services/midi/java/com/android/server/midi/MidiService.java
index 994a767..b519a782 100644
--- a/services/midi/java/com/android/server/midi/MidiService.java
+++ b/services/midi/java/com/android/server/midi/MidiService.java
@@ -365,7 +365,7 @@
             mServiceInfo = serviceInfo;
             mUid = uid;
             mBluetoothDevice = (BluetoothDevice)deviceInfo.getProperties().getParcelable(
-                    MidiDeviceInfo.PROPERTY_BLUETOOTH_DEVICE);;
+                    MidiDeviceInfo.PROPERTY_BLUETOOTH_DEVICE, android.bluetooth.BluetoothDevice.class);;
             setDeviceServer(server);
         }
 
@@ -745,7 +745,7 @@
 
                     Log.d(TAG, "BLE Device");
                     BluetoothDevice btDevice =
-                            intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+                            intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, android.bluetooth.BluetoothDevice.class);
                     dumpUuids(btDevice);
 
                     // See if there are any service UUIDs and if so do any of them indicate a
@@ -764,7 +764,7 @@
                 {
                     Log.d(TAG, "ACTION_ACL_DISCONNECTED");
                     BluetoothDevice btDevice =
-                            intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+                            intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, android.bluetooth.BluetoothDevice.class);
                     // We DO know at this point if we are disconnecting a MIDI device, so
                     // don't bother if we are not.
                     if (isBLEMIDIDevice(btDevice)) {
@@ -793,7 +793,7 @@
                 {
                     Log.d(TAG, "ACTION_UUID");
                     BluetoothDevice btDevice =
-                            intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+                            intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, android.bluetooth.BluetoothDevice.class);
                     dumpUuids(btDevice);
                     if (isBLEMIDIDevice(btDevice)) {
                         Log.d(TAG, "BT MIDI DEVICE");
@@ -1165,7 +1165,7 @@
         BluetoothDevice bluetoothDevice = null;
         if (type == MidiDeviceInfo.TYPE_BLUETOOTH) {
             bluetoothDevice = (BluetoothDevice)properties.getParcelable(
-                    MidiDeviceInfo.PROPERTY_BLUETOOTH_DEVICE);
+                    MidiDeviceInfo.PROPERTY_BLUETOOTH_DEVICE, android.bluetooth.BluetoothDevice.class);
             device = mBluetoothDevices.get(bluetoothDevice);
             if (device != null) {
                 device.setDeviceInfo(deviceInfo);
diff --git a/services/net/Android.bp b/services/net/Android.bp
index 804ccc5..3d40f64 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -18,7 +18,6 @@
     name: "services.net",
     defaults: ["platform_service_defaults"],
     srcs: [
-        ":net-module-utils-srcs",
         ":services.net-sources",
     ],
     static_libs: [
diff --git a/services/net/java/android/net/ConnectivityModuleConnector.java b/services/net/java/android/net/ConnectivityModuleConnector.java
index c6b15c1..6bf6349 100644
--- a/services/net/java/android/net/ConnectivityModuleConnector.java
+++ b/services/net/java/android/net/ConnectivityModuleConnector.java
@@ -25,7 +25,6 @@
 import android.content.ServiceConnection;
 import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
-import android.net.util.SharedLog;
 import android.os.Build;
 import android.os.Environment;
 import android.os.IBinder;
@@ -35,13 +34,13 @@
 import android.provider.DeviceConfig;
 import android.text.format.DateUtils;
 import android.util.ArraySet;
+import android.util.Log;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.File;
-import java.io.PrintWriter;
 
 /**
  * Class used to communicate to the various networking mainline modules running in the network stack
@@ -73,8 +72,6 @@
     private static ConnectivityModuleConnector sInstance;
 
     private Context mContext;
-    @GuardedBy("mLog")
-    private final SharedLog mLog = new SharedLog(TAG);
     @GuardedBy("mHealthListeners")
     private final ArraySet<ConnectivityModuleHealthListener> mHealthListeners = new ArraySet<>();
     @NonNull
@@ -384,38 +381,19 @@
     }
 
     private void log(@NonNull String message) {
-        Slog.d(TAG, message);
-        synchronized (mLog) {
-            mLog.log(message);
-        }
+        Log.d(TAG, message);
     }
 
     private void logWtf(@NonNull String message, @Nullable Throwable e) {
         Slog.wtf(TAG, message, e);
-        synchronized (mLog) {
-            mLog.e(message);
-        }
+        Log.e(TAG, message, e);
     }
 
     private void loge(@NonNull String message, @Nullable Throwable e) {
-        Slog.e(TAG, message, e);
-        synchronized (mLog) {
-            mLog.e(message);
-        }
+        Log.e(TAG, message, e);
     }
 
     private void logi(@NonNull String message) {
-        Slog.i(TAG, message);
-        synchronized (mLog) {
-            mLog.i(message);
-        }
-    }
-
-    /**
-     * Dump ConnectivityModuleConnector logs to the specified {@link PrintWriter}.
-     */
-    public void dump(PrintWriter pw) {
-        // dump is thread-safe on SharedLog
-        mLog.dump(null, pw, null);
+        Log.i(TAG, message);
     }
 }
diff --git a/services/net/java/android/net/NetworkStackClient.java b/services/net/java/android/net/NetworkStackClient.java
index 865e3b8..b7eb5cd 100644
--- a/services/net/java/android/net/NetworkStackClient.java
+++ b/services/net/java/android/net/NetworkStackClient.java
@@ -25,19 +25,18 @@
 import android.net.dhcp.DhcpServingParamsParcel;
 import android.net.dhcp.IDhcpServerCallbacks;
 import android.net.ip.IIpClientCallbacks;
-import android.net.util.SharedLog;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.util.Log;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
-import java.io.PrintWriter;
 import java.util.ArrayList;
 
 /**
@@ -61,9 +60,6 @@
     @GuardedBy("mPendingNetStackRequests")
     private INetworkStackConnector mConnector;
 
-    @GuardedBy("mLog")
-    private final SharedLog mLog = new SharedLog(TAG);
-
     private volatile boolean mWasSystemServerInitialized = false;
 
     private interface NetworkStackCallback {
@@ -237,34 +233,23 @@
     }
 
     /**
-     * Log a message in the local log.
+     * Log a debug message.
      */
     private void log(@NonNull String message) {
-        synchronized (mLog) {
-            mLog.log(message);
-        }
+        Log.d(TAG, message);
     }
 
     private void logWtf(@NonNull String message, @Nullable Throwable e) {
         Slog.wtf(TAG, message);
-        synchronized (mLog) {
-            mLog.e(message, e);
-        }
+        Log.e(TAG, message, e);
     }
 
     private void loge(@NonNull String message, @Nullable Throwable e) {
-        synchronized (mLog) {
-            mLog.e(message, e);
-        }
+        Log.e(TAG, message, e);
     }
 
-    /**
-     * Log a message in the local and system logs.
-     */
     private void logi(@NonNull String message) {
-        synchronized (mLog) {
-            mLog.i(message);
-        }
+        Log.i(TAG, message);
     }
 
     /**
@@ -320,22 +305,4 @@
 
         request.onNetworkStackConnected(connector);
     }
-
-    /**
-     * Dump NetworkStackClient logs to the specified {@link PrintWriter}.
-     */
-    public void dump(PrintWriter pw) {
-        // dump is thread-safe on SharedLog
-        mLog.dump(null, pw, null);
-        // dump connectivity module connector logs.
-        ConnectivityModuleConnector.getInstance().dump(pw);
-
-        final int requestsQueueLength;
-        synchronized (mPendingNetStackRequests) {
-            requestsQueueLength = mPendingNetStackRequests.size();
-        }
-
-        pw.println();
-        pw.println("pendingNetStackRequests length: " + requestsQueueLength);
-    }
 }
diff --git a/services/people/java/com/android/server/people/prediction/ShareTargetPredictor.java b/services/people/java/com/android/server/people/prediction/ShareTargetPredictor.java
index 368b737..b620407 100644
--- a/services/people/java/com/android/server/people/prediction/ShareTargetPredictor.java
+++ b/services/people/java/com/android/server/people/prediction/ShareTargetPredictor.java
@@ -70,7 +70,7 @@
             @UserIdInt int callingUserId, @NonNull Context context) {
         super(predictionContext, updatePredictionsMethod, dataManager, callingUserId);
         mIntentFilter = predictionContext.getExtras().getParcelable(
-                ChooserActivity.APP_PREDICTION_INTENT_FILTER_KEY);
+                ChooserActivity.APP_PREDICTION_INTENT_FILTER_KEY, android.content.IntentFilter.class);
         if (DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
                 SystemUiDeviceConfigFlags.DARK_LAUNCH_REMOTE_PREDICTION_SERVICE_ENABLED,
                 false)) {
diff --git a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
index ca9ff6f..962a07a 100644
--- a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
@@ -43,23 +43,23 @@
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.intThat;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyLong;
+import static org.mockito.Mockito.argThat;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.intThat;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.when;
 import static org.robolectric.Shadows.shadowOf;
 import static org.robolectric.shadow.api.Shadow.extract;
@@ -2185,7 +2185,7 @@
         task.waitCancel();
         reset(transportMock.transport);
         taskFinished.block();
-        verifyZeroInteractions(transportMock.transport);
+        verifyNoInteractions(transportMock.transport);
     }
 
     @Test
diff --git a/services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java b/services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java
index dcffc9e..f041fbd 100644
--- a/services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java
+++ b/services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java
@@ -334,18 +334,7 @@
         @NonNull
         private final SmartspaceConfig mSmartspaceConfig;
         private final RemoteCallbackList<ISmartspaceCallback> mCallbacks =
-                new RemoteCallbackList<ISmartspaceCallback>() {
-                    @Override
-                    public void onCallbackDied(ISmartspaceCallback callback) {
-                        if (DEBUG) {
-                            Slog.d(TAG, "Binder died for session Id=" + mSessionId
-                                    + " and callback=" + callback.asBinder());
-                        }
-                        if (mCallbacks.getRegisteredCallbackCount() == 0) {
-                            destroy();
-                        }
-                    }
-                };
+                new RemoteCallbackList<>();
 
         SmartspaceSessionInfo(
                 @NonNull final SmartspaceSessionId id,
diff --git a/services/tests/apexsystemservices/Android.bp b/services/tests/apexsystemservices/Android.bp
index a6ed1ae..e724e804 100644
--- a/services/tests/apexsystemservices/Android.bp
+++ b/services/tests/apexsystemservices/Android.bp
@@ -39,6 +39,6 @@
     ],
     test_suites: [
         "device-tests",
-        "mts-core",
+        "mts-mainline-infra",
     ],
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index 4942464..c8c8707 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -73,9 +73,7 @@
 import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_QUOTA;
 import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION;
 import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_WINDOW;
-import static com.android.server.alarm.AlarmManagerService.Constants.KEY_CRASH_NON_CLOCK_APPS;
 import static com.android.server.alarm.AlarmManagerService.Constants.KEY_EXACT_ALARM_DENY_LIST;
-import static com.android.server.alarm.AlarmManagerService.Constants.KEY_LAZY_BATCHING;
 import static com.android.server.alarm.AlarmManagerService.Constants.KEY_LISTENER_TIMEOUT;
 import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MAX_DEVICE_IDLE_FUZZ;
 import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MAX_INTERVAL;
@@ -722,6 +720,25 @@
     }
 
     @Test
+    public void testAlarmBroadcastOption() throws Exception {
+        final long triggerTime = mNowElapsedTest + 5000;
+        final PendingIntent alarmPi = getNewMockPendingIntent();
+        setTestAlarm(ELAPSED_REALTIME_WAKEUP, triggerTime, alarmPi);
+
+        mNowElapsedTest = mTestTimer.getElapsed();
+        mTestTimer.expire();
+
+        final ArgumentCaptor<PendingIntent.OnFinished> onFinishedCaptor =
+                ArgumentCaptor.forClass(PendingIntent.OnFinished.class);
+        final ArgumentCaptor<Bundle> optionsCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(alarmPi).send(eq(mMockContext), eq(0), any(Intent.class),
+                onFinishedCaptor.capture(), any(Handler.class), isNull(),
+                optionsCaptor.capture());
+        assertTrue(optionsCaptor.getValue()
+                .getBoolean(BroadcastOptions.KEY_ALARM_BROADCAST, false));
+    }
+
+    @Test
     public void testUpdateConstants() {
         setDeviceConfigLong(KEY_MIN_FUTURITY, 5);
         setDeviceConfigLong(KEY_MIN_INTERVAL, 10);
@@ -2424,7 +2441,6 @@
 
     @Test
     public void alarmClockBinderCallWithoutPermission() throws RemoteException {
-        setDeviceConfigBoolean(KEY_CRASH_NON_CLOCK_APPS, true);
         mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
 
         mockScheduleExactAlarmState(true, false, MODE_ERRORED);
@@ -2593,7 +2609,6 @@
 
     @Test
     public void exactBinderCallsWithoutPermissionWithoutAllowlist() throws RemoteException {
-        setDeviceConfigBoolean(KEY_CRASH_NON_CLOCK_APPS, true);
         mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
 
         mockScheduleExactAlarmState(true, false, MODE_ERRORED);
@@ -3077,37 +3092,6 @@
         optionsSentOnExpiration(false, null);
     }
 
-    @Test
-    public void alarmStoreMigration() {
-        setDeviceConfigBoolean(KEY_LAZY_BATCHING, false);
-        final int numAlarms = 10;
-        final PendingIntent[] pis = new PendingIntent[numAlarms];
-        for (int i = 0; i < numAlarms; i++) {
-            pis[i] = getNewMockPendingIntent();
-            setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 1, pis[i]);
-        }
-
-        final ArrayList<Alarm> alarmsBefore = mService.mAlarmStore.asList();
-        assertEquals(numAlarms, alarmsBefore.size());
-        for (int i = 0; i < numAlarms; i++) {
-            final PendingIntent pi = pis[i];
-            assertTrue(i + "th PendingIntent missing: ",
-                    alarmsBefore.removeIf(a -> a.matches(pi, null)));
-        }
-        assertEquals(BatchingAlarmStore.TAG, mService.mAlarmStore.getName());
-
-        setDeviceConfigBoolean(KEY_LAZY_BATCHING, true);
-
-        final ArrayList<Alarm> alarmsAfter = mService.mAlarmStore.asList();
-        assertEquals(numAlarms, alarmsAfter.size());
-        for (int i = 0; i < numAlarms; i++) {
-            final PendingIntent pi = pis[i];
-            assertTrue(i + "th PendingIntent missing: ",
-                    alarmsAfter.removeIf(a -> a.matches(pi, null)));
-        }
-        assertEquals(LazyAlarmStore.TAG, mService.mAlarmStore.getName());
-    }
-
     private void registerAppIds(String[] packages, Integer[] ids) {
         assertEquals(packages.length, ids.length);
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java
index ba0e555..7dab1c8 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java
@@ -56,7 +56,6 @@
     public static Object[] stores() {
         return new AlarmStore[]{
                 new LazyAlarmStore(),
-                new BatchingAlarmStore(),
         };
     }
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java
new file mode 100644
index 0000000..c7ccef2
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.job.controllers;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.AlarmManager;
+import android.app.job.JobInfo;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManagerInternal;
+import android.os.Looper;
+import android.util.ArraySet;
+
+import com.android.server.LocalServices;
+import com.android.server.job.JobSchedulerService;
+import com.android.server.job.JobStore;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
+
+import java.time.Clock;
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.util.ArrayList;
+
+public class FlexibilityControllerTest {
+    private static final String SOURCE_PACKAGE = "com.android.frameworks.mockingservicestests";
+    private static final int SOURCE_USER_ID = 0;
+
+    private MockitoSession mMockingSession;
+    private FlexibilityController mFlexibilityController;
+    @Mock
+    private AlarmManager mAlarmManager;
+    @Mock
+    private Context mContext;
+    @Mock
+    private JobSchedulerService mJobSchedulerService;
+    private JobStore mJobStore;
+
+    @Before
+    public void setup() {
+        mMockingSession = mockitoSession()
+                .initMocks(this)
+                .strictness(Strictness.LENIENT)
+                .mockStatic(LocalServices.class)
+                .startMocking();
+        // Called in StateController constructor.
+        when(mJobSchedulerService.getTestableContext()).thenReturn(mContext);
+        when(mJobSchedulerService.getLock()).thenReturn(mJobSchedulerService);
+        when(mJobSchedulerService.getConstants()).thenReturn(
+                mock(JobSchedulerService.Constants.class));
+        // Called in FlexibilityController constructor.
+        when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
+        when(mContext.getSystemService(Context.ALARM_SERVICE)).thenReturn(mAlarmManager);
+        //used to get jobs by UID
+        mJobStore = JobStore.initAndGetForTesting(mContext, mContext.getFilesDir());
+        when(mJobSchedulerService.getJobStore()).thenReturn(mJobStore);
+        // Used in JobStatus.
+        doReturn(mock(PackageManagerInternal.class))
+                .when(() -> LocalServices.getService(PackageManagerInternal.class));
+        // Freeze the clocks at a moment in time
+        JobSchedulerService.sSystemClock =
+                Clock.fixed(Instant.ofEpochMilli(100L), ZoneOffset.UTC);
+        JobSchedulerService.sElapsedRealtimeClock =
+                Clock.fixed(Instant.ofEpochMilli(100L), ZoneOffset.UTC);
+        // Initialize real objects.
+        mFlexibilityController = new FlexibilityController(mJobSchedulerService);
+    }
+
+    @After
+    public void teardown() {
+        if (mMockingSession != null) {
+            mMockingSession.finishMocking();
+        }
+    }
+
+    private static JobInfo.Builder createJob(int id) {
+        return new JobInfo.Builder(id, new ComponentName("foo", "bar"));
+    }
+
+    private JobStatus createJobStatus(String testTag, JobInfo.Builder job) {
+        JobInfo jobInfo = job.build();
+        return JobStatus.createFromJobInfo(
+                jobInfo, 1000, SOURCE_PACKAGE, SOURCE_USER_ID, testTag);
+    }
+
+    @Test
+    public void testGetNextConstraintDropTimeElapsed() {
+        long nextTimeToDropNumConstraints;
+
+        // no delay, deadline
+        JobInfo.Builder jb = createJob(0).setOverrideDeadline(1000);
+        JobStatus js = createJobStatus("time", jb);
+        js.enqueueTime = 100L;
+
+        assertEquals(0, js.getEarliestRunTime());
+        assertEquals(1100L, js.getLatestRunTimeElapsed());
+        assertEquals(100L, js.enqueueTime);
+
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(600L, nextTimeToDropNumConstraints);
+        js.adjustNumRequiredFlexibleConstraints(-1);
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(700L, nextTimeToDropNumConstraints);
+        js.adjustNumRequiredFlexibleConstraints(-1);
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(800L, nextTimeToDropNumConstraints);
+
+        // delay, no deadline
+        jb = createJob(0).setMinimumLatency(800000L);
+        js = createJobStatus("time", jb);
+        js.enqueueTime = 100L;
+
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(130400100, nextTimeToDropNumConstraints);
+        js.adjustNumRequiredFlexibleConstraints(-1);
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(156320100L, nextTimeToDropNumConstraints);
+        js.adjustNumRequiredFlexibleConstraints(-1);
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(182240100L, nextTimeToDropNumConstraints);
+
+        // no delay, no deadline
+        jb = createJob(0);
+        js = createJobStatus("time", jb);
+        js.enqueueTime = 100L;
+
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(129600100, nextTimeToDropNumConstraints);
+        js.adjustNumRequiredFlexibleConstraints(-1);
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(155520100L, nextTimeToDropNumConstraints);
+        js.adjustNumRequiredFlexibleConstraints(-1);
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(181440100L, nextTimeToDropNumConstraints);
+
+        // delay, deadline
+        jb = createJob(0).setOverrideDeadline(1100).setMinimumLatency(100);
+        js = createJobStatus("time", jb);
+        js.enqueueTime = 100L;
+
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(700L, nextTimeToDropNumConstraints);
+        js.adjustNumRequiredFlexibleConstraints(-1);
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(800L, nextTimeToDropNumConstraints);
+        js.adjustNumRequiredFlexibleConstraints(-1);
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(900L, nextTimeToDropNumConstraints);
+    }
+
+    @Test
+    public void testWontStopJobFromRunning() {
+        JobStatus js = createJobStatus("testWontStopJobFromRunning", createJob(101));
+        // Stop satisfied constraints from causing a false positive.
+        js.adjustNumRequiredFlexibleConstraints(100);
+        synchronized (mFlexibilityController.mLock) {
+            when(mJobSchedulerService.isCurrentlyRunningLocked(js)).thenReturn(true);
+            assertTrue(mFlexibilityController.isFlexibilitySatisfiedLocked(js));
+        }
+    }
+
+    @Test
+    public void testFlexibilityTracker() {
+        FlexibilityController.FlexibilityTracker flexTracker =
+                mFlexibilityController.new
+                        FlexibilityTracker(FlexibilityController.FLEXIBLE_CONSTRAINTS);
+
+        JobStatus[] jobs = new JobStatus[4];
+        JobInfo.Builder jb;
+        for (int i = 0; i < jobs.length; i++) {
+            jb = createJob(i);
+            if (i > 0) {
+                jb.setRequiresDeviceIdle(true);
+            }
+            if (i > 1) {
+                jb.setRequiresBatteryNotLow(true);
+            }
+            if (i > 2) {
+                jb.setRequiresCharging(true);
+            }
+            jobs[i] = createJobStatus("", jb);
+            flexTracker.add(jobs[i]);
+
+        }
+
+        ArrayList<ArraySet<JobStatus>> trackedJobs = flexTracker.getArrayList();
+        assertEquals(1, trackedJobs.get(0).size());
+        assertEquals(1, trackedJobs.get(1).size());
+        assertEquals(1, trackedJobs.get(2).size());
+        assertEquals(0, trackedJobs.get(3).size());
+
+        flexTracker.adjustJobsRequiredConstraints(jobs[0], -1);
+        assertEquals(1, trackedJobs.get(0).size());
+        assertEquals(2, trackedJobs.get(1).size());
+        assertEquals(0, trackedJobs.get(2).size());
+        assertEquals(0, trackedJobs.get(3).size());
+
+        flexTracker.adjustJobsRequiredConstraints(jobs[0], -1);
+        assertEquals(2, trackedJobs.get(0).size());
+        assertEquals(1, trackedJobs.get(1).size());
+        assertEquals(0, trackedJobs.get(2).size());
+        assertEquals(0, trackedJobs.get(3).size());
+
+        flexTracker.adjustJobsRequiredConstraints(jobs[0], -1);
+        assertEquals(1, trackedJobs.get(0).size());
+        assertEquals(1, trackedJobs.get(1).size());
+        assertEquals(0, trackedJobs.get(2).size());
+        assertEquals(0, trackedJobs.get(3).size());
+
+        flexTracker.remove(jobs[1]);
+        assertEquals(1, trackedJobs.get(0).size());
+        assertEquals(0, trackedJobs.get(1).size());
+        assertEquals(0, trackedJobs.get(2).size());
+        assertEquals(0, trackedJobs.get(3).size());
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt
index b42a3b0..e59a404 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt
@@ -39,6 +39,10 @@
 import com.android.server.testutils.whenever
 import com.android.server.utils.WatchedLongSparseArray
 import com.google.common.truth.Truth.assertThat
+import java.io.File
+import kotlin.test.assertFailsWith
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
 import libcore.util.HexEncoding
 import org.junit.Before
 import org.junit.Rule
@@ -51,10 +55,6 @@
 import org.mockito.Mockito.doAnswer
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
-import java.io.File
-import kotlin.test.assertFailsWith
-import kotlin.test.assertFalse
-import kotlin.test.assertTrue
 
 @RunWith(JUnit4::class)
 class SharedLibrariesImplTest {
@@ -186,7 +186,7 @@
         val staticInfo = mSharedLibrariesImpl
             .getSharedLibraryInfo(STATIC_LIB_NAME, STATIC_LIB_VERSION)!!
 
-        mSharedLibrariesImpl.removeSharedLibraryLPw(STATIC_LIB_NAME, STATIC_LIB_VERSION)
+        mSharedLibrariesImpl.removeSharedLibrary(STATIC_LIB_NAME, STATIC_LIB_VERSION)
 
         assertThat(mSharedLibrariesImpl.getSharedLibraryInfos(STATIC_LIB_NAME)).isNull()
         assertThat(mSharedLibrariesImpl
@@ -208,7 +208,7 @@
             staticLibrary = STATIC_LIB_NAME, staticLibraryVersion = 10L)
 
         val latestInfo =
-            mSharedLibrariesImpl.getLatestStaticSharedLibraVersionLPr(pair.second)!!
+            mSharedLibrariesImpl.getLatestStaticSharedLibraVersion(pair.second)!!
 
         assertThat(latestInfo).isNotNull()
         assertThat(latestInfo.name).isEqualTo(STATIC_LIB_NAME)
@@ -237,7 +237,7 @@
         testPackageSetting.setPkgStateLibraryFiles(listOf())
         assertThat(testPackageSetting.usesLibraryFiles).isEmpty()
 
-        mSharedLibrariesImpl.updateSharedLibrariesLPw(testPackageSetting.pkg, testPackageSetting,
+        mSharedLibrariesImpl.updateSharedLibraries(testPackageSetting.pkg, testPackageSetting,
                 null /* changingLib */, null /* changingLibSetting */, mExistingPackages)
 
         assertThat(testPackageSetting.usesLibraryFiles).hasSize(1)
@@ -250,7 +250,7 @@
         testPackageSetting.setPkgStateLibraryFiles(listOf())
         assertThat(testPackageSetting.usesLibraryFiles).isEmpty()
 
-        mSharedLibrariesImpl.updateSharedLibrariesLPw(testPackageSetting.pkg, testPackageSetting,
+        mSharedLibrariesImpl.updateSharedLibraries(testPackageSetting.pkg, testPackageSetting,
                 null /* changingLib */, null /* changingLibSetting */, mExistingPackages)
 
         assertThat(testPackageSetting.usesLibraryFiles).hasSize(2)
@@ -264,7 +264,7 @@
         testPackageSetting.setPkgStateLibraryFiles(listOf())
         assertThat(testPackageSetting.usesLibraryFiles).isEmpty()
 
-        mSharedLibrariesImpl.updateSharedLibrariesLPw(testPackageSetting.pkg, testPackageSetting,
+        mSharedLibrariesImpl.updateSharedLibraries(testPackageSetting.pkg, testPackageSetting,
                 null /* changingLib */, null /* changingLibSetting */, mExistingPackages)
 
         assertThat(testPackageSetting.usesLibraryFiles).hasSize(3)
diff --git a/services/tests/mockingservicestests/src/com/android/server/power/PowerManagerServiceMockingTest.java b/services/tests/mockingservicestests/src/com/android/server/power/PowerManagerServiceMockingTest.java
index 5c4657f..0f2c27c 100644
--- a/services/tests/mockingservicestests/src/com/android/server/power/PowerManagerServiceMockingTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/power/PowerManagerServiceMockingTest.java
@@ -223,7 +223,17 @@
 
             @Override
             PowerManagerService.Clock createClock() {
-                return () -> mClock.now();
+                return new PowerManagerService.Clock() {
+                    @Override
+                    public long uptimeMillis() {
+                        return mClock.now();
+                    }
+
+                    @Override
+                    public long elapsedRealtime() {
+                        return mClock.now();
+                    }
+                };
             }
 
             @Override
diff --git a/services/tests/servicestests/AndroidTest.xml b/services/tests/servicestests/AndroidTest.xml
index 0ce87d7..9052f58 100644
--- a/services/tests/servicestests/AndroidTest.xml
+++ b/services/tests/servicestests/AndroidTest.xml
@@ -51,5 +51,6 @@
         <option name="package" value="com.android.frameworks.servicestests" />
         <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
         <option name="hidden-api-checks" value="false"/>
+        <option name="exclude-annotation" value="androidx.test.filters.FlakyTest" />
     </test>
 </configuration>
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
index 56c5150..51d78e1 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -57,7 +57,9 @@
 import android.view.Display;
 import android.view.DisplayAdjustments;
 import android.view.DisplayInfo;
+import android.view.WindowManager;
 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
+import android.view.accessibility.AccessibilityWindowAttributes;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
@@ -417,6 +419,20 @@
         verify(mMockSystemSupport).unbindImeLocked(mAccessibilityServiceConnection);
     }
 
+    @Test
+    public void testSetAccessibilityWindowAttributes_passThrough() {
+        final int displayId = Display.DEFAULT_DISPLAY;
+        final int userid = 10;
+        final int windowId = 100;
+        final AccessibilityWindowAttributes attributes = new AccessibilityWindowAttributes(
+                new WindowManager.LayoutParams());
+
+        mA11yms.setAccessibilityWindowAttributes(displayId, windowId, userid, attributes);
+
+        verify(mMockA11yWindowManager).setAccessibilityWindowAttributes(displayId, windowId, userid,
+                attributes);
+    }
+
     public static class FakeInputFilter extends AccessibilityInputFilter {
         FakeInputFilter(Context context,
                 AccessibilityManagerService service) {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
index 4f4be6c..c7757f7 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
@@ -34,6 +34,7 @@
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -42,12 +43,15 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.text.TextUtils;
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.IWindow;
 import android.view.WindowInfo;
+import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowAttributes;
 import android.view.accessibility.AccessibilityWindowInfo;
 import android.view.accessibility.IAccessibilityInteractionConnection;
 
@@ -136,6 +140,11 @@
         when(mMockA11ySecurityPolicy.resolveValidReportedPackageLocked(
                 anyString(), anyInt(), anyInt(), anyInt())).thenReturn(PACKAGE_NAME);
 
+        doAnswer((invocation) -> {
+            onWindowsForAccessibilityChanged(invocation.getArgument(0), false);
+            return null;
+        }).when(mMockWindowManagerInternal).computeWindowsForAccessibility(anyInt());
+
         mA11yWindowManager = new AccessibilityWindowManager(new Object(), mHandler,
                 mMockWindowManagerInternal,
                 mMockA11yEventSender,
@@ -835,6 +844,23 @@
         assertNull(token);
     }
 
+    @Test
+    public void setAccessibilityWindowAttributes_windowIsNotRegistered_titleIsChanged() {
+        final int windowId =
+                getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
+        final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
+        layoutParams.accessibilityTitle = "accessibility window title";
+        final AccessibilityWindowAttributes attributes = new AccessibilityWindowAttributes(
+                layoutParams);
+
+        mA11yWindowManager.setAccessibilityWindowAttributes(Display.DEFAULT_DISPLAY, windowId,
+                USER_SYSTEM_ID, attributes);
+
+        final AccessibilityWindowInfo a11yWindow = mA11yWindowManager.findA11yWindowInfoByIdLocked(
+                windowId);
+        assertTrue(TextUtils.equals(layoutParams.accessibilityTitle, a11yWindow.getTitle()));
+    }
+
     private void registerLeashedTokenAndWindowId() {
         mA11yWindowManager.registerIdLocked(mMockHostToken, HOST_WINDOW_ID);
         mA11yWindowManager.registerIdLocked(mMockEmbeddedToken, EMBEDDED_WINDOW_ID);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
index 1a49f8a..ea1e49d 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
@@ -43,8 +43,10 @@
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
 import android.hardware.fingerprint.ISidefpsController;
 import android.hardware.fingerprint.IUdfpsOverlayController;
+import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.test.TestLooper;
 import android.platform.test.annotations.Presubmit;
 import android.testing.TestableContext;
 
@@ -128,6 +130,8 @@
     @Captor
     private ArgumentCaptor<Consumer<OperationContext>> mContextInjector;
 
+    private TestLooper mLooper = new TestLooper();
+
     @Rule
     public final MockitoRule mockito = MockitoJUnit.rule();
 
@@ -233,6 +237,9 @@
         client.start(mCallback);
         client.onAuthenticated(new Fingerprint("name", 2 /* enrollmentId */, SENSOR_ID),
                 true /* authenticated */, new ArrayList<>());
+
+        mLooper.moveTimeForward(10);
+        mLooper.dispatchAll();
         verify(mLuxProbe).destroy();
 
         client.onAcquired(2, 0);
@@ -309,9 +316,58 @@
         client.onAuthenticated(new Fingerprint("friendly", 1 /* fingerId */, 2 /* deviceId */),
                 true /* authenticated */, new ArrayList<>());
 
+        mLooper.moveTimeForward(10);
+        mLooper.dispatchAll();
         verify(mCancellationSignal).cancel();
     }
 
+    @Test
+    public void fingerprintPowerIgnoresAuthInWindow() throws Exception {
+        when(mSensorProps.isAnySidefpsType()).thenReturn(true);
+
+        final FingerprintAuthenticationClient client = createClient(1);
+        client.start(mCallback);
+        client.onPowerPressed();
+        client.onAuthenticated(new Fingerprint("friendly", 1 /* fingerId */, 2 /* deviceId */),
+                true /* authenticated */, new ArrayList<>());
+        mLooper.moveTimeForward(1000);
+        mLooper.dispatchAll();
+
+        verify(mCallback).onClientFinished(any(), eq(false));
+    }
+
+    @Test
+    public void fingerprintAuthIgnoredWaitingForPower() throws Exception {
+        when(mSensorProps.isAnySidefpsType()).thenReturn(true);
+
+        final FingerprintAuthenticationClient client = createClient(1);
+        client.start(mCallback);
+        client.onAuthenticated(new Fingerprint("friendly", 3 /* fingerId */, 4 /* deviceId */),
+                true /* authenticated */, new ArrayList<>());
+        client.onPowerPressed();
+        mLooper.moveTimeForward(1000);
+        mLooper.dispatchAll();
+
+        verify(mCallback).onClientFinished(any(), eq(false));
+    }
+
+    @Test
+    public void fingerprintAuthSucceedsAfterPowerWindow() throws Exception {
+        when(mSensorProps.isAnySidefpsType()).thenReturn(true);
+
+        final FingerprintAuthenticationClient client = createClient(1);
+        client.start(mCallback);
+        client.onPowerPressed();
+        mLooper.moveTimeForward(1000);
+        mLooper.dispatchAll();
+        client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
+                true /* authenticated */, new ArrayList<>());
+        mLooper.moveTimeForward(1000);
+        mLooper.dispatchAll();
+
+        verify(mCallback).onClientFinished(any(), eq(true));
+    }
+
     private FingerprintAuthenticationClient createClient() throws RemoteException {
         return createClient(100 /* version */, true /* allowBackgroundAuthentication */);
     }
@@ -336,7 +392,8 @@
         9 /* sensorId */, mBiometricLogger, mBiometricContext,
         true /* isStrongBiometric */,
         null /* taskStackListener */, mLockoutCache,
-        mUdfpsOverlayController, mSideFpsController, allowBackgroundAuthentication, mSensorProps) {
+        mUdfpsOverlayController, mSideFpsController, allowBackgroundAuthentication, mSensorProps,
+                new Handler(mLooper.getLooper())) {
             @Override
             protected ActivityTaskManager getActivityTaskManager() {
                 return mActivityTaskManager;
diff --git a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java
index ece0a627..b0738fd 100644
--- a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java
@@ -17,7 +17,11 @@
 package com.android.server.display;
 
 import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.PropertyInvalidatedCache;
@@ -45,18 +49,21 @@
 
     private LogicalDisplay mLogicalDisplay;
     private DisplayDevice mDisplayDevice;
+    private final DisplayDeviceInfo mDisplayDeviceInfo = new DisplayDeviceInfo();
 
     @Before
     public void setUp() {
         // Share classloader to allow package private access.
         System.setProperty("dexmaker.share_classloader", "true");
         mDisplayDevice = mock(DisplayDevice.class);
-        DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo();
-        displayDeviceInfo.width = DISPLAY_WIDTH;
-        displayDeviceInfo.height = DISPLAY_HEIGHT;
-        displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
         mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice);
-        when(mDisplayDevice.getDisplayDeviceInfoLocked()).thenReturn(displayDeviceInfo);
+
+        mDisplayDeviceInfo.copyFrom(new DisplayDeviceInfo());
+        mDisplayDeviceInfo.width = DISPLAY_WIDTH;
+        mDisplayDeviceInfo.height = DISPLAY_HEIGHT;
+        mDisplayDeviceInfo.flags = DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
+        mDisplayDeviceInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL;
+        when(mDisplayDevice.getDisplayDeviceInfoLocked()).thenReturn(mDisplayDeviceInfo);
 
         // Disable binder caches in this process.
         PropertyInvalidatedCache.disableForTestMode();
@@ -103,4 +110,33 @@
         mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
         assertEquals(expectedPosition, mLogicalDisplay.getDisplayPosition());
     }
+
+    @Test
+    public void testDisplayInputFlags() {
+        SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
+        mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
+        verify(t).setDisplayFlags(any(), eq(SurfaceControl.DISPLAY_RECEIVES_INPUT));
+        reset(t);
+
+        mDisplayDeviceInfo.touch = DisplayDeviceInfo.TOUCH_NONE;
+        mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
+        verify(t).setDisplayFlags(any(), eq(0));
+        reset(t);
+
+        mDisplayDeviceInfo.touch = DisplayDeviceInfo.TOUCH_VIRTUAL;
+        mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
+        verify(t).setDisplayFlags(any(), eq(SurfaceControl.DISPLAY_RECEIVES_INPUT));
+        reset(t);
+
+        mLogicalDisplay.setPhase(LogicalDisplay.DISPLAY_PHASE_DISABLED);
+        mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
+        verify(t).setDisplayFlags(any(), eq(0));
+        reset(t);
+
+        mLogicalDisplay.setPhase(LogicalDisplay.DISPLAY_PHASE_ENABLED);
+        mDisplayDeviceInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
+        mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
+        verify(t).setDisplayFlags(any(), eq(SurfaceControl.DISPLAY_RECEIVES_INPUT));
+        reset(t);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
index cc6f2cc..0a4da8d 100644
--- a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
@@ -199,9 +199,6 @@
         final InputMethodSubtype nonAutoEnGB = createFakeInputMethodSubtype("en_GB",
                 SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
                 IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
-        final InputMethodSubtype nonAutoEnIN = createFakeInputMethodSubtype("en_IN",
-                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
-                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
         final InputMethodSubtype nonAutoFrCA = createFakeInputMethodSubtype("fr_CA",
                 SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
                 IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
@@ -656,9 +653,6 @@
         final InputMethodSubtype nonAutoEnUS = createFakeInputMethodSubtype("en_US",
                 SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
                 IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
-        final InputMethodSubtype nonAutoEnGB = createFakeInputMethodSubtype("en_GB",
-                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
-                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
         final InputMethodSubtype nonAutoFil = createFakeInputMethodSubtype("fil",
                 SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
                 IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java
index c30af4c..3f3b8d7 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java
@@ -32,7 +32,7 @@
 
 public class LockSettingsStorageTestable extends LockSettingsStorage {
 
-    public File mStorageDir;
+    public final File mStorageDir;
     public PersistentDataBlockManagerInternal mPersistentDataBlockManager;
     private byte[] mPersistentData;
 
@@ -64,25 +64,23 @@
     }
 
     @Override
-    String getChildProfileLockFile(int userId) {
-        return makeDirs(mStorageDir,
-                super.getChildProfileLockFile(userId)).getAbsolutePath();
+    File getChildProfileLockFile(int userId) {
+        return remapToStorageDir(super.getChildProfileLockFile(userId));
     }
 
     @Override
-    String getRebootEscrowServerBlob() {
-        return makeDirs(mStorageDir, super.getRebootEscrowServerBlob()).getAbsolutePath();
+    File getRebootEscrowServerBlobFile() {
+        return remapToStorageDir(super.getRebootEscrowServerBlobFile());
     }
 
     @Override
-    String getRebootEscrowFile(int userId) {
-        return makeDirs(mStorageDir, super.getRebootEscrowFile(userId)).getAbsolutePath();
+    File getRebootEscrowFile(int userId) {
+        return remapToStorageDir(super.getRebootEscrowFile(userId));
     }
 
     @Override
     protected File getSyntheticPasswordDirectoryForUser(int userId) {
-        return makeDirs(mStorageDir, super.getSyntheticPasswordDirectoryForUser(
-                userId).getAbsolutePath());
+        return remapToStorageDir(super.getSyntheticPasswordDirectoryForUser(userId));
     }
 
     @Override
@@ -90,14 +88,9 @@
         return mPersistentDataBlockManager;
     }
 
-    private File makeDirs(File baseDir, String filePath) {
-        File path = new File(filePath);
-        if (path.getParent() == null) {
-            return new File(baseDir, filePath);
-        } else {
-            File mappedDir = new File(baseDir, path.getParent());
-            mappedDir.mkdirs();
-            return new File(mappedDir, path.getName());
-        }
+    private File remapToStorageDir(File origPath) {
+        File mappedPath = new File(mStorageDir, origPath.toString());
+        mappedPath.getParentFile().mkdirs();
+        return mappedPath;
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
index 609c05c..a663858 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -60,7 +61,10 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.BrokenBarrierException;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * atest FrameworksServicesTests:LockSettingsStorageTests
@@ -137,12 +141,12 @@
     }
 
     @Test
-    public void testKeyValue_Concurrency() {
+    public void testKeyValue_ReadWriteConcurrency() {
         final CountDownLatch latch = new CountDownLatch(1);
         List<Thread> threads = new ArrayList<>();
         for (int i = 0; i < 100; i++) {
             final int threadId = i;
-            threads.add(new Thread("testKeyValue_Concurrency_" + i) {
+            threads.add(new Thread("testKeyValue_ReadWriteConcurrency_" + i) {
                 @Override
                 public void run() {
                     try {
@@ -164,7 +168,7 @@
             });
             threads.get(i).start();
         }
-        mStorage.writeKeyValue("key", "initalValue", 0);
+        mStorage.writeKeyValue("key", "initialValue", 0);
         latch.countDown();
         joinAll(threads, 10000);
         assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
@@ -172,6 +176,52 @@
         assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
     }
 
+    // Test that readKeyValue() doesn't pollute the cache when run concurrently with removeKey().
+    @Test
+    @SuppressWarnings("AssertionFailureIgnored") // intentional try-catch of AssertionError
+    public void testKeyValue_ReadRemoveConcurrency() {
+        final int numThreads = 2;
+        final int numIterations = 50;
+        final CyclicBarrier barrier = new CyclicBarrier(numThreads);
+        final List<Thread> threads = new ArrayList<>();
+        final AtomicReference<Throwable> failure = new AtomicReference<>();
+        for (int threadId = 0; threadId < numThreads; threadId++) {
+            final boolean isWriter = (threadId == 0);
+            threads.add(new Thread("testKeyValue_ReadRemoveConcurrency_" + threadId) {
+                @Override
+                public void run() {
+                    try {
+                        for (int iter = 0; iter < numIterations; iter++) {
+                            if (isWriter) {
+                                mStorage.writeKeyValue("key", "value", 0);
+                                mStorage.clearCache();
+                            }
+                            barrier.await();
+                            if (isWriter) {
+                                mStorage.removeKey("key", 0);
+                            } else {
+                                mStorage.readKeyValue("key", "default", 0);
+                            }
+                            barrier.await();
+                            try {
+                                assertEquals("default", mStorage.readKeyValue("key", "default", 0));
+                            } catch (AssertionError e) {
+                                failure.compareAndSet(null, e);
+                            }
+                            barrier.await();
+                        }
+                    } catch (InterruptedException | BrokenBarrierException e) {
+                        failure.compareAndSet(null, e);
+                        return;
+                    }
+                }
+            });
+            threads.get(threadId).start();
+        }
+        joinAll(threads, 60000);
+        assertNull(failure.get());
+    }
+
     @Test
     public void testKeyValue_CacheStarvedWriter() {
         final CountDownLatch latch = new CountDownLatch(1);
@@ -232,26 +282,37 @@
 
     @Test
     public void testPrefetch() {
-        mStorage.writeKeyValue("key", "toBeFetched", 0);
+        mStorage.writeKeyValue("key1", "value1", 0);
+        mStorage.writeKeyValue("key2", "value2", 0);
 
         mStorage.clearCache();
+
+        assertFalse(mStorage.isUserPrefetched(0));
+        assertFalse(mStorage.isKeyValueCached("key1", 0));
+        assertFalse(mStorage.isKeyValueCached("key2", 0));
+
         mStorage.prefetchUser(0);
 
-        assertEquals("toBeFetched", mStorage.readKeyValue("key", "default", 0));
+        assertTrue(mStorage.isUserPrefetched(0));
+        assertTrue(mStorage.isKeyValueCached("key1", 0));
+        assertTrue(mStorage.isKeyValueCached("key2", 0));
+        assertEquals("value1", mStorage.readKeyValue("key1", "default", 0));
+        assertEquals("value2", mStorage.readKeyValue("key2", "default", 0));
     }
 
     @Test
     public void testFileLocation_Owner() {
         LockSettingsStorage storage = new LockSettingsStorage(InstrumentationRegistry.getContext());
 
-        assertEquals("/data/system/gatekeeper.profile.key", storage.getChildProfileLockFile(0));
+        assertEquals(new File("/data/system/gatekeeper.profile.key"),
+                storage.getChildProfileLockFile(0));
     }
 
     @Test
     public void testFileLocation_SecondaryUser() {
         LockSettingsStorage storage = new LockSettingsStorage(InstrumentationRegistry.getContext());
 
-        assertEquals("/data/system/users/1/gatekeeper.profile.key",
+        assertEquals(new File("/data/system/users/1/gatekeeper.profile.key"),
                 storage.getChildProfileLockFile(1));
     }
 
@@ -259,7 +320,7 @@
     public void testFileLocation_ProfileToSecondary() {
         LockSettingsStorage storage = new LockSettingsStorage(InstrumentationRegistry.getContext());
 
-        assertEquals("/data/system/users/2/gatekeeper.profile.key",
+        assertEquals(new File("/data/system/users/2/gatekeeper.profile.key"),
                 storage.getChildProfileLockFile(2));
     }
 
@@ -267,7 +328,7 @@
     public void testFileLocation_ProfileToOwner() {
         LockSettingsStorage storage = new LockSettingsStorage(InstrumentationRegistry.getContext());
 
-        assertEquals("/data/system/users/3/gatekeeper.profile.key",
+        assertEquals(new File("/data/system/users/3/gatekeeper.profile.key"),
                 storage.getChildProfileLockFile(3));
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java
index 7d1cc3c..48c58bb 100644
--- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java
@@ -52,9 +52,13 @@
 import com.android.server.pm.parsing.pkg.ParsedPackage;
 import com.android.server.pm.pkg.component.ParsedActivity;
 import com.android.server.pm.pkg.component.ParsedActivityImpl;
+import com.android.server.pm.pkg.component.ParsedComponentImpl;
 import com.android.server.pm.pkg.component.ParsedInstrumentationImpl;
 import com.android.server.pm.pkg.component.ParsedIntentInfoImpl;
+import com.android.server.pm.pkg.component.ParsedPermission;
+import com.android.server.pm.pkg.component.ParsedPermissionImpl;
 import com.android.server.pm.pkg.component.ParsedProviderImpl;
+import com.android.server.pm.pkg.component.ParsedUsesPermissionImpl;
 import com.android.server.pm.pkg.parsing.ParsingPackage;
 import com.android.server.utils.WatchableTester;
 
@@ -160,6 +164,17 @@
         return pkg(packageName).addLibraryName(libName);
     }
 
+    private static ParsingPackage pkgWithCustomPermissions(String packageName,
+            String... permNames) {
+        ParsingPackage newPkg = pkg(packageName);
+        for (String permName : permNames) {
+            ParsedPermission permission = new ParsedPermissionImpl();
+            ((ParsedComponentImpl) permission).setName(permName);
+            newPkg.addPermission(permission);
+        }
+        return newPkg;
+    }
+
     private static ParsedActivity createActivity(String packageName, IntentFilter[] filters) {
         ParsedActivityImpl activity = new ParsedActivityImpl();
         activity.setPackageName(packageName);
@@ -227,8 +242,8 @@
     @Test
     public void testSystemReadyPropogates() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */null, mMockHandler);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
         watcher.register();
         appsFilter.onSystemReady(mPmInternal);
@@ -239,8 +254,8 @@
     @Test
     public void testQueriesAction_FilterMatches() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
         watcher.register();
         simulateAddBasicAndroid(appsFilter);
@@ -264,8 +279,8 @@
     @Test
     public void testQueriesProtectedAction_FilterDoesNotMatch() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
         watcher.register();
         final Signature frameworkSignature = Mockito.mock(Signature.class);
@@ -313,8 +328,8 @@
     @Test
     public void testQueriesProvider_FilterMatches() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
         watcher.register();
         simulateAddBasicAndroid(appsFilter);
@@ -338,8 +353,8 @@
     @Test
     public void testOnUserUpdated_FilterMatches() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
 
         appsFilter.onSystemReady(mPmInternal);
@@ -386,8 +401,8 @@
     @Test
     public void testQueriesDifferentProvider_Filters() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
         watcher.register();
         simulateAddBasicAndroid(appsFilter);
@@ -411,8 +426,8 @@
     @Test
     public void testQueriesProviderWithSemiColon_FilterMatches() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -430,8 +445,8 @@
     @Test
     public void testQueriesAction_NoMatchingAction_Filters() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -447,8 +462,8 @@
     @Test
     public void testQueriesAction_NoMatchingActionFilterLowSdk_DoesntFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -469,8 +484,8 @@
     @Test
     public void testNoQueries_Filters() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -486,10 +501,9 @@
 
     @Test
     public void testNoUsesLibrary_Filters() throws Exception {
-        final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock,
-                new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
-                mMockHandler);
-
+        final AppsFilterImpl appsFilter =
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -513,10 +527,9 @@
 
     @Test
     public void testUsesLibrary_DoesntFilter() throws Exception {
-        final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock,
-                new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
-                mMockHandler);
-
+        final AppsFilterImpl appsFilter =
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -541,10 +554,9 @@
 
     @Test
     public void testUsesOptionalLibrary_DoesntFilter() throws Exception {
-        final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock,
-                new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
-                mMockHandler);
-
+        final AppsFilterImpl appsFilter =
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -569,10 +581,9 @@
 
     @Test
     public void testUsesLibrary_ShareUid_DoesntFilter() throws Exception {
-        final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock,
-                new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
-                mMockHandler);
-
+        final AppsFilterImpl appsFilter =
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -603,8 +614,8 @@
     @Test
     public void testForceQueryable_SystemDoesntFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -623,8 +634,8 @@
     @Test
     public void testForceQueryable_NonSystemFilters() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -641,9 +652,8 @@
     @Test
     public void testForceQueryableByDevice_SystemCaller_DoesntFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock,
-                        new String[]{"com.some.package"}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{"com.some.package"},
+                        /* systemAppsQueryable */ false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -662,8 +672,8 @@
     @Test
     public void testSystemSignedTarget_DoesntFilter() throws CertificateException {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         appsFilter.onSystemReady(mPmInternal);
 
         final Signature frameworkSignature = Mockito.mock(Signature.class);
@@ -692,9 +702,8 @@
     @Test
     public void testForceQueryableByDevice_NonSystemCaller_Filters() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock,
-                        new String[]{"com.some.package"}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{"com.some.package"},
+                        /* systemAppsQueryable */ false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -712,8 +721,8 @@
     @Test
     public void testSystemQueryable_DoesntFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{},
-                        true /* system force queryable */, null, mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        true, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -731,8 +740,8 @@
     @Test
     public void testQueriesPackage_DoesntFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -751,8 +760,8 @@
         when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class)))
                 .thenReturn(false);
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -769,8 +778,8 @@
     @Test
     public void testSystemUid_DoesntFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -786,8 +795,8 @@
     @Test
     public void testSystemUidSecondaryUser_DoesntFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -804,8 +813,8 @@
     @Test
     public void testNonSystemUid_NoCallingSetting_Filters() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -817,10 +826,10 @@
     }
 
     @Test
-    public void testNoTargetPackage_filters() throws Exception {
+    public void testNoTargetPackage_Filters() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -991,8 +1000,8 @@
     @Test
     public void testInitiatingApp_DoesntFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -1010,8 +1019,8 @@
     @Test
     public void testUninstalledInitiatingApp_Filters() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -1029,8 +1038,8 @@
     @Test
     public void testOriginatingApp_Filters() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
         watcher.register();
         simulateAddBasicAndroid(appsFilter);
@@ -1055,8 +1064,8 @@
     @Test
     public void testInstallingApp_DoesntFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
         watcher.register();
         simulateAddBasicAndroid(appsFilter);
@@ -1081,8 +1090,8 @@
     @Test
     public void testInstrumentation_DoesntFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
         watcher.register();
         simulateAddBasicAndroid(appsFilter);
@@ -1110,8 +1119,8 @@
     @Test
     public void testWhoCanSee() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
         watcher.register();
         simulateAddBasicAndroid(appsFilter);
@@ -1185,8 +1194,8 @@
     @Test
     public void testOnChangeReport() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
         watcher.register();
         simulateAddBasicAndroid(appsFilter);
@@ -1260,8 +1269,8 @@
     @Test
     public void testOnChangeReportedFilter() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
         final WatchableTester watcher = new WatchableTester(appsFilter, "onChange filter");
@@ -1287,8 +1296,8 @@
     public void testAppsFilterRead() throws Exception {
         when(mFeatureConfigMock.snapshot()).thenReturn(mFeatureConfigMock);
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -1338,8 +1347,8 @@
     @Test
     public void testSdkSandbox_canSeeForceQueryable() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -1358,8 +1367,8 @@
     @Test
     public void testSdkSandbox_cannotSeeNonForceQueryable() throws Exception {
         final AppsFilterImpl appsFilter =
-                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
-                        mMockHandler);
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
         simulateAddBasicAndroid(appsFilter);
         appsFilter.onSystemReady(mPmInternal);
 
@@ -1375,6 +1384,200 @@
                         null /* callingSetting */, target, SYSTEM_USER));
     }
 
+    @Test
+    public void testSdkSandbox_implicitAccessGranted_canSeePackage() throws Exception {
+        final AppsFilterImpl appsFilter =
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
+                        mMockHandler);
+        final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
+        watcher.register();
+        simulateAddBasicAndroid(appsFilter);
+        watcher.verifyChangeReported("addBasic");
+        appsFilter.onSystemReady(mPmInternal);
+        watcher.verifyChangeReported("systemReady");
+
+        PackageSetting target = simulateAddPackage(appsFilter,
+                pkg("com.some.package"), DUMMY_TARGET_APPID,
+                setting -> setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
+
+        int callingUid = 20123;
+        assertTrue(Process.isSdkSandboxUid(callingUid));
+
+        // Without granting the implicit access the app shouldn't be visible to the sdk sandbox uid.
+        assertTrue(
+                appsFilter.shouldFilterApplication(mSnapshot, callingUid,
+                        null /* callingSetting */, target, SYSTEM_USER));
+
+        appsFilter.grantImplicitAccess(callingUid, target.getAppId(), false /* retainOnUpdate */);
+        watcher.verifyChangeReported("grantImplicitAccess");
+
+        // After implicit access was granted the app should be visible to the sdk sandbox uid.
+        assertFalse(
+                appsFilter.shouldFilterApplication(mSnapshot, callingUid,
+                        null /* callingSetting */, target, SYSTEM_USER));
+    }
+
+    @Test
+    public void testUsesPermission_installPermissionDefinerBeforeRequester_DoesntFilter()
+            throws Exception {
+        final AppsFilterImpl appsFilter =
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
+        simulateAddBasicAndroid(appsFilter);
+        appsFilter.onSystemReady(mPmInternal);
+
+        final PackageSetting target = simulateAddPackage(appsFilter,
+                pkgWithCustomPermissions("com.some.package",
+                        "com.some.custom_permission"),
+                DUMMY_TARGET_APPID);
+        final PackageSetting calling = simulateAddPackage(appsFilter,
+                pkg("com.some.other.package").addUsesPermission(
+                        new ParsedUsesPermissionImpl("com.some.custom_permission", 0)),
+                DUMMY_CALLING_APPID);
+
+        assertFalse(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
+    }
+
+    @Test
+    public void testUsesPermission_installPermissionRequesterBeforeDefiner_DoesntFilter()
+            throws Exception {
+        final AppsFilterImpl appsFilter =
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
+        simulateAddBasicAndroid(appsFilter);
+        appsFilter.onSystemReady(mPmInternal);
+
+        final PackageSetting calling = simulateAddPackage(appsFilter,
+                pkg("com.some.other.package").addUsesPermission(
+                        new ParsedUsesPermissionImpl("com.some.custom_permission", 0)),
+                DUMMY_CALLING_APPID);
+
+        final PackageSetting target = simulateAddPackage(appsFilter,
+                pkgWithCustomPermissions("com.some.package",
+                        "com.some.custom_permission"),
+                DUMMY_TARGET_APPID);
+
+        assertFalse(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
+    }
+
+    @Test
+    public void testUsesPermission_visibilityFromPermissionDefinerToRequester_Filters()
+            throws Exception {
+        final AppsFilterImpl appsFilter =
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
+        simulateAddBasicAndroid(appsFilter);
+        appsFilter.onSystemReady(mPmInternal);
+
+        final PackageSetting calling = simulateAddPackage(appsFilter,
+                pkgWithCustomPermissions("com.some.package",
+                        "com.some.custom_permission"),
+                DUMMY_CALLING_APPID);
+
+        final PackageSetting target = simulateAddPackage(appsFilter,
+                pkg("com.some.other.package").addUsesPermission(
+                        new ParsedUsesPermissionImpl("com.some.custom_permission", 0)),
+                DUMMY_TARGET_APPID);
+
+        assertTrue(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
+    }
+
+    @Test
+    public void testUsesPermission_multipleCustomPermissions() throws Exception {
+        final AppsFilterImpl appsFilter =
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
+        simulateAddBasicAndroid(appsFilter);
+        appsFilter.onSystemReady(mPmInternal);
+
+        final PackageSetting target = simulateAddPackage(appsFilter,
+                pkgWithCustomPermissions("com.some.package",
+                        "com.some.custom_permission1", "com.some.custom_permission2"),
+                DUMMY_TARGET_APPID);
+
+        final PackageSetting calling1 = simulateAddPackage(appsFilter,
+                pkg("com.some.other.package")
+                        .addUsesPermission(new ParsedUsesPermissionImpl(
+                                "com.some.custom_permission1", 0)),
+                DUMMY_CALLING_APPID);
+
+        final PackageSetting calling2 = simulateAddPackage(appsFilter,
+                pkg("com.some.another.package")
+                        .addUsesPermission(new ParsedUsesPermissionImpl(
+                                "com.some.custom_permission2", 0))
+                        .addUsesPermission(new ParsedUsesPermissionImpl(
+                                "com.some.custom_permission3", 0)),
+                DUMMY_CALLING_APPID + 1);
+
+        assertFalse(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling1, target,
+                        SYSTEM_USER));
+        assertFalse(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID + 1,
+                        calling2, target, SYSTEM_USER));
+        assertTrue(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling1,
+                        calling2, SYSTEM_USER));
+    }
+
+    @Test
+    public void testUsesPermission_multiplePermissionDefiners_DoesntFilter() throws Exception {
+        final AppsFilterImpl appsFilter =
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
+
+        simulateAddBasicAndroid(appsFilter);
+        appsFilter.onSystemReady(mPmInternal);
+
+
+        final PackageSetting target1 = simulateAddPackage(appsFilter,
+                pkgWithCustomPermissions("com.some.package1", "com.some.custom_permission"),
+                DUMMY_TARGET_APPID);
+        final PackageSetting target2 = simulateAddPackage(appsFilter,
+                pkgWithCustomPermissions("com.some.package2", "com.some.custom_permission"),
+                DUMMY_TARGET_APPID + 1);
+        final PackageSetting calling = simulateAddPackage(appsFilter,
+                pkg("com.some.other.package")
+                        .addUsesPermission(new ParsedUsesPermissionImpl(
+                                "com.some.custom_permission", 0)),
+                DUMMY_CALLING_APPID);
+
+        assertFalse(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target1,
+                        SYSTEM_USER));
+        assertFalse(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target2,
+                        SYSTEM_USER));
+
+    }
+
+    @Test
+    public void testNoUsesPermission_Filters() throws Exception {
+        final AppsFilterImpl appsFilter =
+                new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+                        false, /* overlayProvider */ null, mMockHandler);
+
+        simulateAddBasicAndroid(appsFilter);
+        appsFilter.onSystemReady(mPmInternal);
+
+
+        final PackageSetting target = simulateAddPackage(appsFilter,
+                pkgWithCustomPermissions("com.some.package", "com.some.custom_permission"),
+                DUMMY_TARGET_APPID);
+        final PackageSetting calling = simulateAddPackage(appsFilter,
+                pkg("com.some.other.package"),
+                DUMMY_CALLING_APPID);
+
+        assertTrue(
+                appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+                        SYSTEM_USER));
+    }
     private List<Integer> toList(int[] array) {
         ArrayList<Integer> ret = new ArrayList<>(array.length);
         for (int i = 0; i < array.length; i++) {
diff --git a/services/tests/servicestests/src/com/android/server/policy/SideFpsEventHandlerTest.java b/services/tests/servicestests/src/com/android/server/policy/SideFpsEventHandlerTest.java
index 371861f..7746bd6 100644
--- a/services/tests/servicestests/src/com/android/server/policy/SideFpsEventHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/policy/SideFpsEventHandlerTest.java
@@ -53,33 +53,30 @@
 
 /**
  * Unit tests for {@link SideFpsEventHandler}.
- * <p/>
- * Run with <code>atest SideFpsEventHandlerTest</code>.
+ *
+ * <p>Run with <code>atest SideFpsEventHandlerTest</code>.
  */
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 public class SideFpsEventHandlerTest {
 
-    private static final List<Integer> sAllStates = List.of(
-            BiometricStateListener.STATE_IDLE,
-            BiometricStateListener.STATE_ENROLLING,
-            BiometricStateListener.STATE_KEYGUARD_AUTH,
-            BiometricStateListener.STATE_BP_AUTH,
-            BiometricStateListener.STATE_AUTH_OTHER);
+    private static final List<Integer> sAllStates =
+            List.of(
+                    BiometricStateListener.STATE_IDLE,
+                    BiometricStateListener.STATE_ENROLLING,
+                    BiometricStateListener.STATE_KEYGUARD_AUTH,
+                    BiometricStateListener.STATE_BP_AUTH,
+                    BiometricStateListener.STATE_AUTH_OTHER);
 
     @Rule
     public TestableContext mContext =
             new TestableContext(InstrumentationRegistry.getContext(), null);
-    @Mock
-    private PackageManager mPackageManager;
-    @Mock
-    private FingerprintManager mFingerprintManager;
-    @Spy
-    private AlertDialog.Builder mDialogBuilder = new AlertDialog.Builder(mContext);
-    @Mock
-    private AlertDialog mAlertDialog;
-    @Mock
-    private Window mWindow;
+
+    @Mock private PackageManager mPackageManager;
+    @Mock private FingerprintManager mFingerprintManager;
+    @Spy private AlertDialog.Builder mDialogBuilder = new AlertDialog.Builder(mContext);
+    @Mock private AlertDialog mAlertDialog;
+    @Mock private Window mWindow;
 
     private TestLooper mLooper = new TestLooper();
     private SideFpsEventHandler mEventHandler;
@@ -95,9 +92,12 @@
         when(mDialogBuilder.create()).thenReturn(mAlertDialog);
         when(mAlertDialog.getWindow()).thenReturn(mWindow);
 
-        mEventHandler = new SideFpsEventHandler(
-                mContext, new Handler(mLooper.getLooper()),
-                mContext.getSystemService(PowerManager.class), () -> mDialogBuilder);
+        mEventHandler =
+                new SideFpsEventHandler(
+                        mContext,
+                        new Handler(mLooper.getLooper()),
+                        mContext.getSystemService(PowerManager.class),
+                        () -> mDialogBuilder);
     }
 
     @Test
@@ -105,7 +105,7 @@
         when(mPackageManager.hasSystemFeature(eq(PackageManager.FEATURE_FINGERPRINT)))
                 .thenReturn(false);
 
-        assertThat(mEventHandler.onSinglePressDetected(60L)).isFalse();
+        assertThat(mEventHandler.shouldConsumeSinglePress(60L)).isFalse();
 
         mLooper.dispatchAll();
         verify(mAlertDialog, never()).show();
@@ -117,7 +117,7 @@
 
         for (int state : sAllStates) {
             setBiometricState(state);
-            assertThat(mEventHandler.onSinglePressDetected(200L)).isFalse();
+            assertThat(mEventHandler.shouldConsumeSinglePress(200L)).isFalse();
 
             mLooper.dispatchAll();
             verify(mAlertDialog, never()).show();
@@ -130,7 +130,7 @@
 
         for (int state : sAllStates) {
             setBiometricState(state);
-            assertThat(mEventHandler.onSinglePressDetected(400L)).isFalse();
+            assertThat(mEventHandler.shouldConsumeSinglePress(400L)).isFalse();
 
             mLooper.dispatchAll();
             verify(mAlertDialog, never()).show();
@@ -139,13 +139,13 @@
 
     @Test
     public void ignoresWhenIdleOrUnknown() throws Exception {
-        setupWithSensor(true /* hasSfps */, true /* initialized */);
+        setupWithSensor(true /* hasSidefps */, true /* initialized */);
 
         setBiometricState(BiometricStateListener.STATE_IDLE);
-        assertThat(mEventHandler.onSinglePressDetected(80000L)).isFalse();
+        assertThat(mEventHandler.shouldConsumeSinglePress(80000L)).isFalse();
 
         setBiometricState(BiometricStateListener.STATE_AUTH_OTHER);
-        assertThat(mEventHandler.onSinglePressDetected(90000L)).isFalse();
+        assertThat(mEventHandler.shouldConsumeSinglePress(90000L)).isFalse();
 
         mLooper.dispatchAll();
         verify(mAlertDialog, never()).show();
@@ -156,7 +156,7 @@
         setupWithSensor(true /* hasSfps */, true /* initialized */);
 
         setBiometricState(BiometricStateListener.STATE_KEYGUARD_AUTH);
-        assertThat(mEventHandler.onSinglePressDetected(80000L)).isFalse();
+        assertThat(mEventHandler.shouldConsumeSinglePress(80000L)).isFalse();
 
         mLooper.dispatchAll();
         verify(mAlertDialog, never()).show();
@@ -164,13 +164,13 @@
 
     @Test
     public void promptsWhenBPisActive() throws Exception {
-        setupWithSensor(true /* hasSfps */, true /* initialized */);
+        setupWithSensor(true /* hasSideFps */, true /* initialized */);
 
         setBiometricState(BiometricStateListener.STATE_BP_AUTH);
-        assertThat(mEventHandler.onSinglePressDetected(80000L)).isTrue();
+        assertThat(mEventHandler.shouldConsumeSinglePress(80000L)).isTrue();
 
         mLooper.dispatchAll();
-        verify(mAlertDialog).show();
+        verify(mAlertDialog, never()).show();
     }
 
     @Test
@@ -178,7 +178,57 @@
         setupWithSensor(true /* hasSfps */, true /* initialized */);
 
         setBiometricState(BiometricStateListener.STATE_ENROLLING);
-        assertThat(mEventHandler.onSinglePressDetected(80000L)).isTrue();
+        assertThat(mEventHandler.shouldConsumeSinglePress(80000L)).isTrue();
+
+        mLooper.dispatchAll();
+        verify(mAlertDialog).show();
+        verify(mAlertDialog, never()).dismiss();
+    }
+
+    @Test
+    public void dismissesDialogOnTouchWhenEnrolling() throws Exception {
+        setupWithSensor(true /* hasSfps */, true /* initialized */);
+
+        setBiometricState(BiometricStateListener.STATE_ENROLLING);
+        when(mAlertDialog.isShowing()).thenReturn(true);
+        assertThat(mEventHandler.shouldConsumeSinglePress(80000L)).isTrue();
+
+        mLooper.dispatchAll();
+        verify(mAlertDialog).show();
+
+        mBiometricStateListener.onBiometricAction(BiometricStateListener.ACTION_SENSOR_TOUCH);
+        mLooper.moveTimeForward(10000);
+        mLooper.dispatchAll();
+
+        verify(mAlertDialog).dismiss();
+    }
+
+    @Test
+    public void dismissesDialogFailsWhenPowerPressedAndDialogShowing() throws Exception {
+        setupWithSensor(true /* hasSfps */, true /* initialized */);
+
+        setBiometricState(BiometricStateListener.STATE_ENROLLING);
+        when(mAlertDialog.isShowing()).thenReturn(true);
+        assertThat(mEventHandler.shouldConsumeSinglePress(80000L)).isTrue();
+
+        mLooper.dispatchAll();
+        verify(mAlertDialog).show();
+
+        mBiometricStateListener.onBiometricAction(BiometricStateListener.ACTION_SENSOR_TOUCH);
+        assertThat(mEventHandler.shouldConsumeSinglePress(60L)).isTrue();
+
+        mLooper.dispatchAll();
+        verify(mAlertDialog, never()).dismiss();
+    }
+
+    @Test
+    public void showDialogAfterTap() throws Exception {
+        setupWithSensor(true /* hasSfps */, true /* initialized */);
+
+        setBiometricState(BiometricStateListener.STATE_ENROLLING);
+        when(mAlertDialog.isShowing()).thenReturn(true);
+        mBiometricStateListener.onBiometricAction(BiometricStateListener.ACTION_SENSOR_TOUCH);
+        assertThat(mEventHandler.shouldConsumeSinglePress(60L)).isTrue();
 
         mLooper.dispatchAll();
         verify(mAlertDialog).show();
@@ -201,11 +251,13 @@
                 ArgumentCaptor.forClass(IFingerprintAuthenticatorsRegisteredCallback.class);
         verify(mFingerprintManager).addAuthenticatorsRegisteredCallback(fpCallbackCaptor.capture());
         if (initialized) {
-            fpCallbackCaptor.getValue().onAllAuthenticatorsRegistered(
-                    List.of(mock(FingerprintSensorPropertiesInternal.class)));
+            fpCallbackCaptor
+                    .getValue()
+                    .onAllAuthenticatorsRegistered(
+                            List.of(mock(FingerprintSensorPropertiesInternal.class)));
             if (hasSfps) {
-                ArgumentCaptor<BiometricStateListener> captor = ArgumentCaptor.forClass(
-                        BiometricStateListener.class);
+                ArgumentCaptor<BiometricStateListener> captor =
+                        ArgumentCaptor.forClass(BiometricStateListener.class);
                 verify(mFingerprintManager).registerBiometricStateListener(captor.capture());
                 mBiometricStateListener = captor.getValue();
             }
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index 78f7f66..f1f423d 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -158,6 +158,7 @@
     private UserSwitchedReceiver mUserSwitchedReceiver;
     private Resources mResourcesSpy;
     private OffsettableClock mClock;
+    private long mLastElapsedRealtime;
     private TestLooper mTestLooper;
 
     private static class IntentFilterMatcher implements ArgumentMatcher<IntentFilter> {
@@ -286,7 +287,18 @@
 
             @Override
             PowerManagerService.Clock createClock() {
-                return () -> mClock.now();
+                return new PowerManagerService.Clock() {
+                    @Override
+                    public long uptimeMillis() {
+                        return mClock.now();
+                    }
+
+                    @Override
+                    public long elapsedRealtime() {
+                        mLastElapsedRealtime = mClock.now();
+                        return mLastElapsedRealtime;
+                    }
+                };
             }
 
             @Override
@@ -1686,6 +1698,7 @@
 
         mService.setWakefulnessLocked(nonDefaultPowerGroupId, WAKEFULNESS_DOZING, eventTime2,
                 0, PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0, null, null);
+        long eventElapsedRealtime1 = mLastElapsedRealtime;
         assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
         assertThat(mService.getBinderServiceInstance().getLastSleepReason()).isEqualTo(
                 PowerManager.GO_TO_SLEEP_REASON_APPLICATION);
@@ -1693,19 +1706,20 @@
         mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_AWAKE,
                 eventTime3, /* uid= */ 0, PowerManager.WAKE_REASON_PLUGGED_IN, /* opUid= */
                 0, /* opPackageName= */ null, /* details= */ null);
+        long eventElapsedRealtime2 = mLastElapsedRealtime;
         PowerManager.WakeData wakeData = mService.getLocalServiceInstance().getLastWakeup();
         assertThat(wakeData.wakeTime).isEqualTo(eventTime3);
         assertThat(wakeData.wakeReason).isEqualTo(PowerManager.WAKE_REASON_PLUGGED_IN);
-        assertThat(wakeData.sleepDuration).isEqualTo(eventTime3 - eventTime2);
+        assertThat(wakeData.sleepDurationRealtime)
+                .isEqualTo(eventElapsedRealtime2 - eventElapsedRealtime1);
 
         // The global wake time and reason as well as sleep duration shouldn't change when another
         // PowerGroup wakes up.
         mService.setWakefulnessLocked(nonDefaultPowerGroupId, WAKEFULNESS_AWAKE,
                 eventTime4, /* uid= */ 0, PowerManager.WAKE_REASON_CAMERA_LAUNCH, /* opUid= */
                 0, /* opPackageName= */ null, /* details= */ null);
-        assertThat(wakeData.wakeTime).isEqualTo(eventTime3);
-        assertThat(wakeData.wakeReason).isEqualTo(PowerManager.WAKE_REASON_PLUGGED_IN);
-        assertThat(wakeData.sleepDuration).isEqualTo(eventTime3 - eventTime2);
+        PowerManager.WakeData wakeData2 = mService.getLocalServiceInstance().getLastWakeup();
+        assertThat(wakeData2).isEqualTo(wakeData);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index c016406..308a4b6 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -928,6 +928,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 185169504)
     public void testNotificationEvent_quotaBump() throws Exception {
         mInjector.mSettingsBuilder
                 .setBoolean("trigger_quota_bump_on_notification_seen", true);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 6e3bc5b..830237a 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -3380,19 +3380,80 @@
     }
 
     @Test
-    public void testSnoozeRunnable_reSnoozeASingleSnoozedNotification() throws Exception {
+    public void testSnoozeRunnable_tooManySnoozed_singleNotification() {
+        final NotificationRecord notification = generateNotificationRecord(
+                mTestNotificationChannel, 1, null, true);
+        mService.addNotification(notification);
+
+        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
+        when(mSnoozeHelper.canSnooze(1)).thenReturn(false);
+
+        NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
+                mService.new SnoozeNotificationRunnable(
+                        notification.getKey(), 100, null);
+        snoozeNotificationRunnable.run();
+
+        verify(mSnoozeHelper, never()).snooze(any(NotificationRecord.class), anyLong());
+        assertThat(mService.getNotificationRecordCount()).isEqualTo(1);
+    }
+
+    @Test
+    public void testSnoozeRunnable_tooManySnoozed_singleGroupChildNotification() {
+        final NotificationRecord notification = generateNotificationRecord(
+                mTestNotificationChannel, 1, "group", true);
+        final NotificationRecord notificationChild = generateNotificationRecord(
+                mTestNotificationChannel, 1, "group", false);
+        mService.addNotification(notification);
+        mService.addNotification(notificationChild);
+
+        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
+        when(mSnoozeHelper.canSnooze(2)).thenReturn(false);
+
+        NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
+                mService.new SnoozeNotificationRunnable(
+                        notificationChild.getKey(), 100, null);
+        snoozeNotificationRunnable.run();
+
+        verify(mSnoozeHelper, never()).snooze(any(NotificationRecord.class), anyLong());
+        assertThat(mService.getNotificationRecordCount()).isEqualTo(2);
+    }
+
+    @Test
+    public void testSnoozeRunnable_tooManySnoozed_summaryNotification() {
+        final NotificationRecord notification = generateNotificationRecord(
+                mTestNotificationChannel, 1, "group", true);
+        final NotificationRecord notificationChild = generateNotificationRecord(
+                mTestNotificationChannel, 12, "group", false);
+        final NotificationRecord notificationChild2 = generateNotificationRecord(
+                mTestNotificationChannel, 13, "group", false);
+        mService.addNotification(notification);
+        mService.addNotification(notificationChild);
+        mService.addNotification(notificationChild2);
+
+        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
+        when(mSnoozeHelper.canSnooze(3)).thenReturn(false);
+
+        NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
+                mService.new SnoozeNotificationRunnable(
+                        notification.getKey(), 100, null);
+        snoozeNotificationRunnable.run();
+
+        verify(mSnoozeHelper, never()).snooze(any(NotificationRecord.class), anyLong());
+        assertThat(mService.getNotificationRecordCount()).isEqualTo(3);
+    }
+
+    @Test
+    public void testSnoozeRunnable_reSnoozeASingleSnoozedNotification() {
         final NotificationRecord notification = generateNotificationRecord(
                 mTestNotificationChannel, 1, null, true);
         mService.addNotification(notification);
         when(mSnoozeHelper.getNotification(any())).thenReturn(notification);
+        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
 
         NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
                 mService.new SnoozeNotificationRunnable(
                 notification.getKey(), 100, null);
         snoozeNotificationRunnable.run();
-        NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable2 =
-                mService.new SnoozeNotificationRunnable(
-                notification.getKey(), 100, null);
         snoozeNotificationRunnable.run();
 
         // snooze twice
@@ -3400,19 +3461,17 @@
     }
 
     @Test
-    public void testSnoozeRunnable_reSnoozeASnoozedNotificationWithGroupKey() throws Exception {
+    public void testSnoozeRunnable_reSnoozeASnoozedNotificationWithGroupKey() {
         final NotificationRecord notification = generateNotificationRecord(
                 mTestNotificationChannel, 1, "group", true);
         mService.addNotification(notification);
         when(mSnoozeHelper.getNotification(any())).thenReturn(notification);
+        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
 
         NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
                 mService.new SnoozeNotificationRunnable(
                 notification.getKey(), 100, null);
         snoozeNotificationRunnable.run();
-        NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable2 =
-                mService.new SnoozeNotificationRunnable(
-                notification.getKey(), 100, null);
         snoozeNotificationRunnable.run();
 
         // snooze twice
@@ -3430,6 +3489,7 @@
         when(mSnoozeHelper.getNotification(any())).thenReturn(notification);
         when(mSnoozeHelper.getNotifications(
                 anyString(), anyString(), anyInt())).thenReturn(new ArrayList<>());
+        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
 
         NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
                 mService.new SnoozeNotificationRunnable(
@@ -3439,8 +3499,8 @@
                 .thenReturn(new ArrayList<>(Arrays.asList(notification, notification2)));
         NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable2 =
                 mService.new SnoozeNotificationRunnable(
-                        notification.getKey(), 100, null);
-        snoozeNotificationRunnable.run();
+                        notification2.getKey(), 100, null);
+        snoozeNotificationRunnable2.run();
 
         // snooze twice
         verify(mSnoozeHelper, times(4)).snooze(any(NotificationRecord.class), anyLong());
@@ -3454,6 +3514,7 @@
                 mTestNotificationChannel, 2, "group", false);
         mService.addNotification(grouped);
         mService.addNotification(nonGrouped);
+        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
 
         NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
                 mService.new SnoozeNotificationRunnable(
@@ -3483,6 +3544,7 @@
         mService.addNotification(parent);
         mService.addNotification(child);
         mService.addNotification(child2);
+        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
 
         NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
                 mService.new SnoozeNotificationRunnable(
@@ -3504,6 +3566,7 @@
         mService.addNotification(parent);
         mService.addNotification(child);
         mService.addNotification(child2);
+        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
 
         NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
                 mService.new SnoozeNotificationRunnable(
@@ -3529,6 +3592,7 @@
                 mTestNotificationChannel, 2, "group", false);
         mService.addNotification(parent);
         mService.addNotification(child);
+        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
 
         NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
                 mService.new SnoozeNotificationRunnable(
@@ -3556,6 +3620,7 @@
         final NotificationRecord child = generateNotificationRecord(
                 mTestNotificationChannel, 2, "group", false);
         mService.addNotification(child);
+        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
 
         NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
                 mService.new SnoozeNotificationRunnable(
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
index 4c7e843..f2b1dc9 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
@@ -18,6 +18,7 @@
 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
 import static android.content.pm.PackageManager.GET_PERMISSIONS;
 import static android.content.pm.PackageManager.PERMISSION_DENIED;
@@ -74,6 +75,8 @@
 
     private PermissionHelper mPermissionHelper;
 
+    private static final int USER_FLAG_MASK = FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED;
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
@@ -183,7 +186,8 @@
         verify(mPermManager).grantRuntimePermission(
                 "pkg", Manifest.permission.POST_NOTIFICATIONS, 10);
         verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS,
-                FLAG_PERMISSION_USER_SET, FLAG_PERMISSION_USER_SET, true, 10);
+                USER_FLAG_MASK | FLAG_PERMISSION_GRANTED_BY_DEFAULT,
+                FLAG_PERMISSION_USER_SET, true, 10);
     }
 
     @Test
@@ -201,7 +205,8 @@
         verify(mPermManager).grantRuntimePermission(
                 "pkg", Manifest.permission.POST_NOTIFICATIONS, 10);
         verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS,
-                FLAG_PERMISSION_USER_SET, FLAG_PERMISSION_USER_SET, true, 10);
+                USER_FLAG_MASK | FLAG_PERMISSION_GRANTED_BY_DEFAULT,
+                FLAG_PERMISSION_USER_SET, true, 10);
     }
 
     @Test
@@ -214,7 +219,8 @@
         verify(mPermManager).revokeRuntimePermission(
                 eq("pkg"), eq(Manifest.permission.POST_NOTIFICATIONS), eq(10), anyString());
         verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS,
-                FLAG_PERMISSION_USER_SET, FLAG_PERMISSION_USER_SET, true, 10);
+                USER_FLAG_MASK | FLAG_PERMISSION_GRANTED_BY_DEFAULT,
+                FLAG_PERMISSION_USER_SET, true, 10);
     }
 
     @Test
@@ -227,7 +233,7 @@
         verify(mPermManager).grantRuntimePermission(
                 "pkg", Manifest.permission.POST_NOTIFICATIONS, 10);
         verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS,
-                0, FLAG_PERMISSION_USER_SET, true, 10);
+                USER_FLAG_MASK, 0, true, 10);
     }
 
     @Test
@@ -240,7 +246,8 @@
         verify(mPermManager).revokeRuntimePermission(
                 eq("pkg"), eq(Manifest.permission.POST_NOTIFICATIONS), eq(10), anyString());
         verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS,
-                0, FLAG_PERMISSION_USER_SET, true, 10);
+                USER_FLAG_MASK | FLAG_PERMISSION_GRANTED_BY_DEFAULT, 0,
+                true, 10);
     }
 
     @Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
index 2ae2ef7..7817e81 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
@@ -15,10 +15,12 @@
  */
 package com.android.server.notification;
 
+import static com.android.server.notification.SnoozeHelper.CONCURRENT_SNOOZE_LIMIT;
 import static com.android.server.notification.SnoozeHelper.EXTRA_KEY;
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
 
@@ -38,7 +40,6 @@
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
-import android.os.SystemClock;
 import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -49,7 +50,6 @@
 
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.internal.util.FastXmlSerializer;
 import com.android.server.UiServiceTestCase;
 import com.android.server.pm.PackageManagerService;
 
@@ -59,9 +59,7 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
@@ -197,18 +195,6 @@
     }
 
     @Test
-    public void testCleanupContextShouldRemovePersistedRecord() {
-        NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
-        mSnoozeHelper.snooze(r, "context");
-        mSnoozeHelper.cleanupPersistedContext(r.getSbn().getKey());
-        assertNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification(
-                r.getUser().getIdentifier(),
-                r.getSbn().getPackageName(),
-                r.getSbn().getKey()
-        ));
-    }
-
-    @Test
     public void testReadNoneSnoozedNotification() throws XmlPullParserException,
             IOException, InterruptedException {
         NotificationRecord r = getNotificationRecord(
@@ -218,8 +204,9 @@
         assertEquals("should see a zero value for unsnoozed notification",
                 0L,
                 mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
-                        UserHandle.SYSTEM.getIdentifier(),
-                        "not_my_package", r.getKey()).longValue());
+                        UserHandle.SYSTEM.getIdentifier(), "not_my_package",
+                        getNotificationRecord("not_my_package", 1, "one",
+                                UserHandle.SYSTEM).getKey()).longValue());
     }
 
     @Test
@@ -281,6 +268,22 @@
     }
 
     @Test
+    public void testSnoozeLimit() {
+        for (int i = 0; i < CONCURRENT_SNOOZE_LIMIT; i++ ) {
+            NotificationRecord r = getNotificationRecord("pkg", i, i+"", UserHandle.SYSTEM);
+
+            assertTrue("cannot snooze record " + i, mSnoozeHelper.canSnooze(1));
+
+            if (i % 2 == 0) {
+                mSnoozeHelper.snooze(r, null);
+            } else {
+                mSnoozeHelper.snooze(r, 9000);
+            }
+        }
+        assertFalse(mSnoozeHelper.canSnooze(1));
+    }
+
+    @Test
     public void testCancelByApp() throws Exception {
         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
         NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM);
@@ -575,7 +578,7 @@
     }
 
     @Test
-    public void testClearData() {
+    public void testClearData_userPackage() {
         // snooze 2 from same package
         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
         NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM);
@@ -599,17 +602,72 @@
     }
 
     @Test
+    public void testClearData_user() {
+        // snooze 2 from same package
+        NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
+        NotificationRecord r2 = getNotificationRecord("pkg2", 2, "two", UserHandle.SYSTEM);
+        NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three", UserHandle.SYSTEM);
+        NotificationRecord r4 = getNotificationRecord("pkg", 2, "two", UserHandle.ALL);
+        mSnoozeHelper.snooze(r, 1000);
+        mSnoozeHelper.snooze(r2, 1000);
+        mSnoozeHelper.snooze(r3, "until");
+        mSnoozeHelper.snooze(r4, "until");
+
+        assertTrue(mSnoozeHelper.isSnoozed(
+                UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
+        assertTrue(mSnoozeHelper.isSnoozed(
+                UserHandle.USER_SYSTEM, r2.getSbn().getPackageName(), r2.getKey()));
+        assertTrue(mSnoozeHelper.isSnoozed(
+                UserHandle.USER_SYSTEM, r3.getSbn().getPackageName(), r3.getKey()));
+        assertTrue(mSnoozeHelper.isSnoozed(
+                UserHandle.USER_ALL, r4.getSbn().getPackageName(), r4.getKey()));
+
+        // clear data
+        mSnoozeHelper.clearData(UserHandle.USER_SYSTEM);
+
+        // nothing in USER_SYSTEM snoozed; alarms canceled
+        assertFalse(mSnoozeHelper.isSnoozed(
+                UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
+        assertFalse(mSnoozeHelper.isSnoozed(
+                UserHandle.USER_SYSTEM, r2.getSbn().getPackageName(), r2.getKey()));
+        assertFalse(mSnoozeHelper.isSnoozed(
+                UserHandle.USER_SYSTEM, r3.getSbn().getPackageName(), r3.getKey()));
+        assertTrue(mSnoozeHelper.isSnoozed(
+                UserHandle.USER_SYSTEM, r4.getSbn().getPackageName(), r4.getKey()));
+
+        assertNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification(
+                r3.getUser().getIdentifier(), r3.getSbn().getPackageName(),
+                r3.getSbn().getKey()));
+        assertNotNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification(
+                r4.getUser().getIdentifier(), r4.getSbn().getPackageName(),
+                r4.getSbn().getKey()));
+        assertEquals(0L, mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
+                r.getUser().getIdentifier(), r.getSbn().getPackageName(),
+                r.getSbn().getKey()).longValue());
+        assertEquals(0L, mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
+                r2.getUser().getIdentifier(), r2.getSbn().getPackageName(),
+                r2.getSbn().getKey()).longValue());
+
+        // 2 for initial timed-snoozes, once each for canceling the USER_SYSTEM snoozes
+        verify(mAm, times(5)).cancel(any(PendingIntent.class));
+    }
+
+    @Test
     public void testClearData_otherRecordsUntouched() {
         // 2 packages, 2 users
         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
+        NotificationRecord rb = getNotificationRecord("pkg", 1, "oneb", UserHandle.SYSTEM);
         NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.ALL);
         NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three", UserHandle.SYSTEM);
         mSnoozeHelper.snooze(r, 1000);
+        mSnoozeHelper.snooze(rb, "until");
         mSnoozeHelper.snooze(r2, 1000);
         mSnoozeHelper.snooze(r3, 1000);
         assertTrue(mSnoozeHelper.isSnoozed(
                 UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
         assertTrue(mSnoozeHelper.isSnoozed(
+                UserHandle.USER_SYSTEM, rb.getSbn().getPackageName(), rb.getKey()));
+        assertTrue(mSnoozeHelper.isSnoozed(
                 UserHandle.USER_ALL, r2.getSbn().getPackageName(), r2.getKey()));
         assertTrue(mSnoozeHelper.isSnoozed(
                 UserHandle.USER_SYSTEM, r3.getSbn().getPackageName(), r3.getKey()));
@@ -619,12 +677,22 @@
 
         assertFalse(mSnoozeHelper.isSnoozed(
                 UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
+        assertFalse(mSnoozeHelper.isSnoozed(
+                UserHandle.USER_SYSTEM, rb.getSbn().getPackageName(), rb.getKey()));
         assertTrue(mSnoozeHelper.isSnoozed(
                 UserHandle.USER_ALL, r2.getSbn().getPackageName(), r2.getKey()));
         assertTrue(mSnoozeHelper.isSnoozed(
                 UserHandle.USER_SYSTEM, r3.getSbn().getPackageName(), r3.getKey()));
+
+        assertNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification(
+                rb.getUser().getIdentifier(), rb.getSbn().getPackageName(),
+                rb.getSbn().getKey()));
+        assertEquals(0L, mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
+                r.getUser().getIdentifier(), r.getSbn().getPackageName(),
+                r.getSbn().getKey()).longValue());
+
         // once for each initial snooze, once for canceling one snooze
-        verify(mAm, times(4)).cancel(any(PendingIntent.class));
+        verify(mAm, times(5)).cancel(any(PendingIntent.class));
     }
 
     private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index 5b909a3..1d52b7f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -19,6 +19,7 @@
 import static android.app.ActivityManager.START_SUCCESS;
 import static android.app.ActivityManager.START_TASK_TO_FRONT;
 import static android.content.ComponentName.createRelative;
+import static android.view.WindowManager.TRANSIT_OPEN;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
@@ -75,6 +76,7 @@
     private ActivityRecord mTrampolineActivity;
     private ActivityRecord mTopActivity;
     private ActivityOptions mActivityOptions;
+    private Transition mTransition;
     private boolean mLaunchTopByTrampoline;
     private boolean mNewActivityCreated = true;
     private long mExpectedStartedId;
@@ -98,6 +100,11 @@
                 .setTask(mTrampolineActivity.getTask())
                 .setComponent(createRelative(DEFAULT_COMPONENT_PACKAGE_NAME, "TopActivity"))
                 .build();
+        mTopActivity.mDisplayContent.mOpeningApps.add(mTopActivity);
+        mTransition = new Transition(TRANSIT_OPEN, 0 /* flags */,
+                mTopActivity.mTransitionController, createTestBLASTSyncEngine());
+        mTransition.mParticipants.add(mTopActivity);
+        mTopActivity.mTransitionController.moveToCollecting(mTransition);
         // becomes invisible when covered by mTopActivity
         mTrampolineActivity.mVisibleRequested = false;
     }
@@ -437,11 +444,13 @@
     @Test
     public void testActivityDrawnBeforeTransition() {
         mTopActivity.setVisible(false);
-        notifyActivityLaunching(mTopActivity.intent);
+        onIntentStarted(mTopActivity.intent);
         // Assume the activity is launched the second time consecutively. The drawn event is from
         // the first time (omitted in test) launch that is earlier than transition.
         doReturn(true).when(mTopActivity).isReportedDrawn();
         notifyWindowsDrawn(mTopActivity);
+        verifyNoMoreInteractions(mLaunchObserver);
+
         notifyActivityLaunched(START_SUCCESS, mTopActivity);
         // If the launching activity was drawn when starting transition, the launch event should
         // be reported successfully.
@@ -452,6 +461,18 @@
     }
 
     @Test
+    public void testActivityDrawnWithoutTransition() {
+        mTopActivity.mDisplayContent.mOpeningApps.remove(mTopActivity);
+        mTransition.mParticipants.remove(mTopActivity);
+        onIntentStarted(mTopActivity.intent);
+        notifyAndVerifyActivityLaunched(mTopActivity);
+        notifyWindowsDrawn(mTopActivity);
+        // Even if there is no notifyTransitionStarting, the launch event can still be reported
+        // because the drawn activity is not involved in transition.
+        verifyOnActivityLaunchFinished(mTopActivity);
+    }
+
+    @Test
     public void testConcurrentLaunches() {
         onActivityLaunched(mTopActivity);
         clearInvocations(mLaunchObserver);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 0c3b270..3f3d01a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -49,7 +49,6 @@
 import static android.os.Process.NOBODY_UID;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.InsetsState.ITYPE_IME;
-import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
 import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
@@ -2539,21 +2538,6 @@
     }
 
     @Test
-    public void testStuckExitingWindow() {
-        final WindowState closingWindow = createWindow(null, FIRST_APPLICATION_WINDOW,
-                "closingWindow");
-        closingWindow.mAnimatingExit = true;
-        closingWindow.mRemoveOnExit = true;
-        closingWindow.mActivityRecord.commitVisibility(
-                false /* visible */, true /* performLayout */);
-
-        // We pretended that we were running an exit animation, but that should have been cleared up
-        // by changing visibility of ActivityRecord
-        closingWindow.removeIfPossible();
-        assertTrue(closingWindow.mRemoved);
-    }
-
-    @Test
     public void testSetOrientation() {
         final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build();
         activity.setVisible(true);
@@ -3149,6 +3133,7 @@
         mDisplayContent.mOpeningApps.clear();
         app.mActivityRecord.commitVisibility(false, false);
         app.mActivityRecord.onWindowsGone();
+        mDisplayContent.computeImeTargetIfNeeded(app.mActivityRecord);
 
         assertTrue(app.mActivityRecord.mLastImeShown);
         assertTrue(app.mActivityRecord.mImeInsetsFrozenUntilStartInput);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index fe3c26a..cd087e6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -1406,7 +1406,7 @@
             ActivityRecord source, ActivityOptions options, Task inTask,
             TaskFragment inTaskFragment) {
         starter.startActivityInner(target, source, null /* voiceSession */,
-                null /* voiceInteractor */, 0 /* startFlags */, true /* doResume */,
+                null /* voiceInteractor */, 0 /* startFlags */,
                 options, inTask, inTaskFragment, false /* restrictedBgActivity */,
                 null /* intentGrants */);
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index f2d6273..513791d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -47,6 +47,7 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.clearInvocations;
@@ -89,6 +90,7 @@
 
     @Before
     public void setUp() throws Exception {
+        assumeFalse(WindowManagerService.sEnableShellTransitions);
         mAppTransitionController = new AppTransitionController(mWm, mDisplayContent);
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 40e266c..11a7c7d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -2118,7 +2118,6 @@
         final WindowState appWin2 = createWindow(null, TYPE_BASE_APPLICATION, act2, "appWin2");
         appWin2.setHasSurface(true);
         assertTrue(appWin2.canBeImeTarget());
-        doReturn(true).when(appWin1).isClosing();
         doReturn(true).when(appWin1).inTransitionSelfOrParent();
 
         // Test step 3: Verify appWin2 will be the next IME target and the IME snapshot surface will
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
index 47c2176..21197ba 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
@@ -184,7 +184,6 @@
                 /* voiceSession */null,
                 /* voiceInteractor */ null,
                 /* startFlags */ 0,
-                /* doResume */true,
                 /* options */null,
                 /* inTask */null,
                 /* inTaskFragment */ null,
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index ffa21fa..6c161cf 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -27,6 +27,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -44,12 +45,15 @@
 
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
+import android.util.SparseArray;
 import android.view.InsetsSourceControl;
 import android.view.InsetsState;
 import android.view.InsetsVisibilities;
 
 import androidx.test.filters.SmallTest;
 
+import com.android.internal.util.function.TriConsumer;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -269,15 +273,18 @@
     @Test
     public void testImeForDispatch() {
         final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
-        final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime");
+        final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
 
         // IME cannot be the IME target.
         ime.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
 
         WindowContainerInsetsSourceProvider statusBarProvider =
                 getController().getSourceProvider(ITYPE_STATUS_BAR);
-        statusBarProvider.setWindowContainer(statusBar, null, ((displayFrames, windowState, rect) ->
+        final SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>> imeOverrideProviders =
+                new SparseArray<>();
+        imeOverrideProviders.put(TYPE_INPUT_METHOD, ((displayFrames, windowState, rect) ->
                 rect.set(0, 1, 2, 3)));
+        statusBarProvider.setWindowContainer(statusBar, null, imeOverrideProviders);
         getController().getSourceProvider(ITYPE_IME).setWindowContainer(ime, null, null);
         statusBar.setControllableInsetProvider(statusBarProvider);
         statusBar.updateSourceFrame(statusBar.getFrame());
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 324e244..f2640d2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -1496,6 +1496,79 @@
     }
 
     @Test
+    public void testComputeConfigResourceOverrides_unresizableApp() {
+        // Set up a display in landscape and ignoring orientation request.
+        setUpDisplaySizeWithApp(2800, 1400);
+        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+
+        prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
+
+        final Rect activityBounds = new Rect(mActivity.getBounds());
+
+        int originalScreenWidthDp = mActivity.getConfiguration().screenWidthDp;
+        int originalScreenHeighthDp = mActivity.getConfiguration().screenHeightDp;
+
+        // App should launch in fixed orientation letterbox.
+        // Activity bounds should be 700x1400 with the ratio as the display.
+        assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+        assertFitted();
+        assertEquals(originalScreenWidthDp, mActivity.getConfiguration().smallestScreenWidthDp);
+        assertTrue(originalScreenWidthDp < originalScreenHeighthDp);
+
+        // Rotate display to portrait.
+        rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
+
+        // After we rotate, the activity should go in the size-compat mode and report the same
+        // configuration values.
+        assertScaled();
+        assertEquals(originalScreenWidthDp, mActivity.getConfiguration().smallestScreenWidthDp);
+        assertEquals(originalScreenWidthDp, mActivity.getConfiguration().screenWidthDp);
+        assertEquals(originalScreenHeighthDp, mActivity.getConfiguration().screenHeightDp);
+
+        // Restart activity
+        mActivity.restartProcessIfVisible();
+
+        // Now configuration should be updated
+        assertFitted();
+        assertNotEquals(originalScreenWidthDp, mActivity.getConfiguration().screenWidthDp);
+        assertNotEquals(originalScreenHeighthDp, mActivity.getConfiguration().screenHeightDp);
+        assertEquals(mActivity.getConfiguration().screenWidthDp,
+                mActivity.getConfiguration().smallestScreenWidthDp);
+    }
+
+    @Test
+    public void testComputeConfigResourceOverrides_resizableFixedOrientationActivity() {
+        // Set up a display in landscape and ignoring orientation request.
+        setUpDisplaySizeWithApp(2800, 1400);
+        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+
+        // Portrait fixed app without max aspect.
+        prepareLimitedBounds(mActivity, SCREEN_ORIENTATION_PORTRAIT, false /* isUnresizable */);
+
+        final Rect activityBounds = new Rect(mActivity.getBounds());
+
+        int originalScreenWidthDp = mActivity.getConfiguration().screenWidthDp;
+        int originalScreenHeighthDp = mActivity.getConfiguration().screenHeightDp;
+
+        // App should launch in fixed orientation letterbox.
+        // Activity bounds should be 700x1400 with the ratio as the display.
+        assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+        assertFitted();
+        assertEquals(originalScreenWidthDp, mActivity.getConfiguration().smallestScreenWidthDp);
+        assertTrue(originalScreenWidthDp < originalScreenHeighthDp);
+
+        // Rotate display to portrait.
+        rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
+
+        // Now configuration should be updated
+        assertFitted();
+        assertNotEquals(originalScreenWidthDp, mActivity.getConfiguration().screenWidthDp);
+        assertNotEquals(originalScreenHeighthDp, mActivity.getConfiguration().screenHeightDp);
+        assertEquals(mActivity.getConfiguration().screenWidthDp,
+                mActivity.getConfiguration().smallestScreenWidthDp);
+    }
+
+    @Test
     public void testSplitAspectRatioForUnresizablePortraitApps() {
         // Set up a display in landscape and ignoring orientation request.
         int screenWidth = 1600;
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index 46e21f1..1f03039 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -268,6 +268,20 @@
         assertFalse(task.hasChild());
         // In real case, the task should be preserved for adding new activity.
         assertTrue(task.isAttached());
+
+        final ActivityRecord activityA = new ActivityBuilder(mAtm).setTask(task).build();
+        final ActivityRecord activityB = new ActivityBuilder(mAtm).setTask(task).build();
+        final ActivityRecord activityC = new ActivityBuilder(mAtm).setTask(task).build();
+        activityA.setState(ActivityRecord.State.STOPPED, "test");
+        activityB.setState(ActivityRecord.State.PAUSED, "test");
+        activityC.setState(ActivityRecord.State.RESUMED, "test");
+        doReturn(true).when(activityB).shouldBeVisibleUnchecked();
+        doReturn(true).when(activityC).shouldBeVisibleUnchecked();
+        activityA.getConfiguration().densityDpi += 100;
+        assertTrue(task.performClearTop(activityA, 0 /* launchFlags */).finishing);
+        // The bottom activity should destroy directly without relaunch for config change.
+        assertEquals(ActivityRecord.State.DESTROYING, activityA.getState());
+        verify(activityA, never()).startRelaunching();
     }
 
     @Test
@@ -691,7 +705,8 @@
         final ActivityRecord.CompatDisplayInsets compatInsets =
                 new ActivityRecord.CompatDisplayInsets(
                         display, activity, /* fixedOrientationBounds= */ null);
-        task.computeConfigResourceOverrides(inOutConfig, parentConfig, compatInsets);
+        task.computeConfigResourceOverrides(
+                inOutConfig, parentConfig, compatInsets, /* areBoundsLetterboxed */ true);
 
         assertEquals(largerLandscapeBounds, inOutConfig.windowConfiguration.getAppBounds());
         final float density = parentConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
index 67e0a35..4227939 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -30,6 +30,7 @@
 import static android.view.WindowManager.TRANSIT_CLOSE;
 import static android.view.WindowManager.TRANSIT_OPEN;
 import static android.view.WindowManager.TRANSIT_TO_BACK;
+import static android.window.TransitionInfo.FLAG_IS_EMBEDDED;
 import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
 import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER;
 import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
@@ -62,8 +63,10 @@
 import android.util.ArraySet;
 import android.view.SurfaceControl;
 import android.window.IDisplayAreaOrganizer;
+import android.window.ITaskFragmentOrganizer;
 import android.window.ITaskOrganizer;
 import android.window.ITransitionPlayer;
+import android.window.TaskFragmentOrganizer;
 import android.window.TransitionInfo;
 
 import androidx.test.filters.SmallTest;
@@ -1008,6 +1011,43 @@
         assertTrue(openTransition.allReady());
     }
 
+    @Test
+    public void testIsEmbeddedChange() {
+        final Transition transition = createTestTransition(TRANSIT_OPEN);
+        final ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges;
+        final ArraySet<WindowContainer> participants = transition.mParticipants;
+
+        final Task task = createTask(mDisplayContent);
+        final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
+        mAtm.mTaskFragmentOrganizerController.registerOrganizer(
+                ITaskFragmentOrganizer.Stub.asInterface(organizer.getOrganizerToken().asBinder()));
+        final TaskFragment embeddedTf = new TaskFragmentBuilder(mAtm)
+                .setParentTask(task)
+                .createActivityCount(2)
+                .setOrganizer(organizer)
+                .build();
+        final ActivityRecord closingActivity = embeddedTf.getBottomMostActivity();
+        final ActivityRecord openingActivity = embeddedTf.getTopMostActivity();
+        // Start states.
+        changes.put(embeddedTf, new Transition.ChangeInfo(true /* vis */, false /* exChg */));
+        changes.put(closingActivity, new Transition.ChangeInfo(true /* vis */, false /* exChg */));
+        changes.put(openingActivity, new Transition.ChangeInfo(false /* vis */, true /* exChg */));
+        // End states.
+        closingActivity.mVisibleRequested = false;
+        openingActivity.mVisibleRequested = true;
+
+        participants.add(closingActivity);
+        participants.add(openingActivity);
+        final ArrayList<WindowContainer> targets = Transition.calculateTargets(
+                participants, changes);
+        final TransitionInfo info = Transition.calculateTransitionInfo(
+                transition.mType, 0 /* flags */, targets, changes, mMockT);
+
+        assertEquals(2, info.getChanges().size());
+        assertTrue((info.getChanges().get(0).getFlags() & FLAG_IS_EMBEDDED) != 0);
+        assertTrue((info.getChanges().get(1).getFlags() & FLAG_IS_EMBEDDED) != 0);
+    }
+
     private static void makeTaskOrganized(Task... tasks) {
         final ITaskOrganizer organizer = mock(ITaskOrganizer.class);
         for (Task t : tasks) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index 1a64f5e..685a8f4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -29,8 +29,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
 
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
@@ -48,7 +46,6 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.content.pm.PackageManager;
 import android.graphics.Rect;
 import android.os.Binder;
 import android.os.IBinder;
@@ -81,11 +78,6 @@
     @Rule
     public ExpectedException mExpectedException = ExpectedException.none();
 
-    private boolean isAutomotive() {
-        return getInstrumentation().getTargetContext().getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_AUTOMOTIVE);
-    }
-
     @Test
     public void testAddWindowToken() {
         IBinder token = mock(IBinder.class);
@@ -301,7 +293,8 @@
         mWm.setInTouchMode(!currentTouchMode);
 
         verify(mWm.mInputManager).setInTouchMode(
-                !currentTouchMode, callingPid, callingUid, /* hasPermission= */ true);
+                !currentTouchMode, callingPid, callingUid, /* hasPermission= */ true,
+                DEFAULT_DISPLAY);
     }
 
     @Test
@@ -316,7 +309,8 @@
         mWm.setInTouchMode(!currentTouchMode);
 
         verify(mWm.mInputManager).setInTouchMode(
-                !currentTouchMode, callingPid, callingUid, /* hasPermission= */ false);
+                !currentTouchMode, callingPid, callingUid, /* hasPermission= */ false,
+                DEFAULT_DISPLAY);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 9c2aac0..5407412 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -459,6 +459,23 @@
     }
 
     @Test
+    public void testRegisterTaskOrganizerWithExistingTasks_noSurfaceControl()
+            throws RemoteException {
+        final Task rootTask = createRootTask();
+        final Task task = createTask(rootTask);
+        final Task rootTask2 = createRootTask();
+        final Task task2 = createTask(rootTask2);
+        rootTask2.setSurfaceControl(null);
+        ArrayList<TaskAppearedInfo> existingTasks = new ArrayList<>();
+        final ITaskOrganizer organizer = registerMockOrganizer(existingTasks);
+        assertContainsTasks(existingTasks, rootTask);
+
+        // Verify we don't get onTaskAppeared if we are returned the tasks
+        verify(organizer, never())
+                .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
+    }
+
+    @Test
     public void testTaskTransaction() {
         removeGlobalMinSizeRestriction();
         final Task rootTask = new TaskBuilder(mSupervisor)
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index fb7400b..334cfd5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -664,12 +664,11 @@
         assertEquals(expectedChildPos, childPos);
 
         // Surface should apply the scale.
+        final SurfaceControl.Transaction t = w.getPendingTransaction();
         w.prepareSurfaces();
-        verify(w.getPendingTransaction()).setMatrix(w.getSurfaceControl(),
-                overrideScale, 0, 0, overrideScale);
+        verify(t).setMatrix(w.mSurfaceControl, overrideScale, 0, 0, overrideScale);
         // Child surface inherits parent's scale, so it doesn't need to scale.
-        verify(child.getPendingTransaction(), never()).setMatrix(any(), anyInt(), anyInt(),
-                anyInt(), anyInt());
+        verify(t, never()).setMatrix(any(), anyInt(), anyInt(), anyInt(), anyInt());
 
         // According to "dp * density / 160 = px", density is scaled and the size in dp is the same.
         final CompatibilityInfo compatInfo = cmp.compatibilityInfoForPackageLocked(
@@ -686,6 +685,13 @@
         final Rect unscaledClientBounds = new Rect(clientConfig.windowConfiguration.getBounds());
         unscaledClientBounds.scale(overrideScale);
         assertEquals(w.getWindowConfiguration().getBounds(), unscaledClientBounds);
+
+        // Child window without scale (e.g. different app) should apply inverse scale of parent.
+        doReturn(1f).when(cmp).getCompatScale(anyString(), anyInt());
+        final WindowState child2 = createWindow(w, TYPE_APPLICATION_SUB_PANEL, "child2");
+        clearInvocations(t);
+        child2.prepareSurfaces();
+        verify(t).setMatrix(child2.mSurfaceControl, w.mInvGlobalScale, 0, 0, w.mInvGlobalScale);
     }
 
     @UseTestDisplay(addWindows = {W_ABOVE_ACTIVITY, W_NOTIFICATION_SHADE})
@@ -720,6 +726,17 @@
         outWaitingForDrawn.clear();
         invisibleApp.requestDrawIfNeeded(outWaitingForDrawn);
         assertTrue(outWaitingForDrawn.isEmpty());
+
+        // Drawn state should not be changed for insets change when screen is off.
+        spyOn(mWm.mPolicy);
+        doReturn(false).when(mWm.mPolicy).isScreenOn();
+        makeWindowVisibleAndDrawn(startingApp);
+        startingApp.getConfiguration().orientation = 0; // Reset to be the same as last reported.
+        startingApp.getWindowFrames().setInsetsChanged(true);
+        startingApp.updateResizingWindowIfNeeded();
+        assertTrue(mWm.mResizingWindows.contains(startingApp));
+        assertTrue(startingApp.isDrawn());
+        assertFalse(startingApp.getOrientationChanging());
     }
 
     @UseTestDisplay(addWindows = W_ABOVE_ACTIVITY)
@@ -992,6 +1009,7 @@
         assertTrue(app.mActivityRecord.mImeInsetsFrozenUntilStartInput);
 
         // Verify the IME insets is visible on app, but not for app2 during app task switching.
+        mDisplayContent.computeImeTargetIfNeeded(app.mActivityRecord);
         assertTrue(app.getInsetsState().getSource(ITYPE_IME).isVisible());
         assertFalse(app2.getInsetsState().getSource(ITYPE_IME).isVisible());
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 8a539cd..0cbf1b2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -811,7 +811,7 @@
             }
 
             @Override
-            public void topFocusedWindowChanged(String packageName,
+            public void topFocusedWindowChanged(ComponentName component,
                     InsetsVisibilities requestedVisibilities) {
             }
         };
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 84bfff6..a0b01a7 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -2377,10 +2377,9 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.CHANGE_APP_IDLE_STATE)
         @Override
         public void setAppStandbyBucket(String packageName, int bucket, int userId) {
-            getContext().enforceCallingPermission(Manifest.permission.CHANGE_APP_IDLE_STATE,
-                    "No permission to change app standby state");
 
             final int callingUid = Binder.getCallingUid();
             final int callingPid = Binder.getCallingPid();
@@ -2426,10 +2425,9 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.CHANGE_APP_IDLE_STATE)
         @Override
         public void setAppStandbyBuckets(ParceledListSlice appBuckets, int userId) {
-            getContext().enforceCallingPermission(Manifest.permission.CHANGE_APP_IDLE_STATE,
-                    "No permission to change app standby state");
 
             final int callingUid = Binder.getCallingUid();
             final int callingPid = Binder.getCallingPid();
@@ -2477,12 +2475,10 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.CHANGE_APP_LAUNCH_TIME_ESTIMATE)
         @Override
         public void setEstimatedLaunchTime(String packageName, long estimatedLaunchTime,
                 int userId) {
-            getContext().enforceCallingPermission(
-                    Manifest.permission.CHANGE_APP_LAUNCH_TIME_ESTIMATE,
-                    "No permission to change app launch estimates");
 
             final long token = Binder.clearCallingIdentity();
             try {
@@ -2493,11 +2489,9 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.CHANGE_APP_LAUNCH_TIME_ESTIMATE)
         @Override
         public void setEstimatedLaunchTimes(ParceledListSlice estimatedLaunchTimes, int userId) {
-            getContext().enforceCallingPermission(
-                    Manifest.permission.CHANGE_APP_LAUNCH_TIME_ESTIMATE,
-                    "No permission to change app launch estimates");
 
             final long token = Binder.clearCallingIdentity();
             try {
diff --git a/services/usb/java/com/android/server/usb/MtpNotificationManager.java b/services/usb/java/com/android/server/usb/MtpNotificationManager.java
index 8845f11..70bafc0 100644
--- a/services/usb/java/com/android/server/usb/MtpNotificationManager.java
+++ b/services/usb/java/com/android/server/usb/MtpNotificationManager.java
@@ -117,7 +117,7 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             final UsbDevice device =
-                    intent.getExtras().<UsbDevice>getParcelable(UsbManager.EXTRA_DEVICE);
+                    intent.getExtras().<UsbDevice>getParcelable(UsbManager.EXTRA_DEVICE, android.hardware.usb.UsbDevice.class);
             if (device == null) {
                 return;
             }
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 6ea416b..85b9f75 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -341,8 +341,8 @@
         BroadcastReceiver portReceiver = new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
-                ParcelableUsbPort port = intent.getParcelableExtra(UsbManager.EXTRA_PORT);
-                UsbPortStatus status = intent.getParcelableExtra(UsbManager.EXTRA_PORT_STATUS);
+                ParcelableUsbPort port = intent.getParcelableExtra(UsbManager.EXTRA_PORT, android.hardware.usb.ParcelableUsbPort.class);
+                UsbPortStatus status = intent.getParcelableExtra(UsbManager.EXTRA_PORT_STATUS, android.hardware.usb.UsbPortStatus.class);
                 mHandler.updateHostState(
                         port.getUsbPort(context.getSystemService(UsbManager.class)), status);
             }
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index 5e633ab..f8df6c6 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -1156,7 +1156,7 @@
             switch (msg.what) {
                 case MSG_UPDATE_PORTS: {
                     Bundle b = msg.getData();
-                    ArrayList<RawPortInfo> PortInfo = b.getParcelableArrayList(PORT_INFO);
+                    ArrayList<RawPortInfo> PortInfo = b.getParcelableArrayList(PORT_INFO, com.android.server.usb.hal.port.RawPortInfo.class);
                     synchronized (mLock) {
                         updatePortsLocked(null, PortInfo);
                     }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index bcfee82..7699262 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -1149,9 +1149,9 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
         @Override
         public void setDisabled(boolean disabled) {
-            enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
             synchronized (this) {
                 if (mTemporarilyDisabled == disabled) {
                     if (DEBUG) Slog.d(TAG, "setDisabled(): already " + disabled);
@@ -1207,6 +1207,7 @@
 
         //----------------- Hotword Detection/Validation APIs --------------------------------//
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_HOTWORD_DETECTION)
         @Override
         public void updateState(
                 @NonNull Identity voiceInteractorIdentity,
@@ -1214,7 +1215,6 @@
                 @Nullable SharedMemory sharedMemory,
                 IHotwordRecognitionStatusCallback callback,
                 int detectorType) {
-            enforceCallingPermission(Manifest.permission.MANAGE_HOTWORD_DETECTION);
             synchronized (this) {
                 enforceIsCurrentVoiceInteractionService();
 
@@ -1256,13 +1256,12 @@
             }
         }
 
+        @android.annotation.EnforcePermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD})
         @Override
         public void startListeningFromMic(
                 AudioFormat audioFormat,
                 IMicrophoneHotwordDetectionVoiceInteractionCallback callback)
                 throws RemoteException {
-            enforceCallingPermission(Manifest.permission.RECORD_AUDIO);
-            enforceCallingPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD);
             synchronized (this) {
                 enforceIsCurrentVoiceInteractionService();
 
@@ -1322,13 +1321,12 @@
             }
         }
 
+        @android.annotation.EnforcePermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD})
         @Override
         public void triggerHardwareRecognitionEventForTest(
                 SoundTrigger.KeyphraseRecognitionEvent event,
                 IHotwordRecognitionStatusCallback callback)
                 throws RemoteException {
-            enforceCallingPermission(Manifest.permission.RECORD_AUDIO);
-            enforceCallingPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD);
             synchronized (this) {
                 enforceIsCurrentVoiceInteractionService();
 
@@ -1669,10 +1667,10 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
         @Override
         public boolean showSessionForActiveService(Bundle args, int sourceFlags,
                 IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken) {
-            enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
             if (DEBUG_USER) Slog.d(TAG, "showSessionForActiveService()");
 
             synchronized (this) {
@@ -1700,9 +1698,9 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
         @Override
         public void hideCurrentSession() throws RemoteException {
-            enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
 
             if (mImpl == null) {
                 return;
@@ -1721,9 +1719,9 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
         @Override
         public void launchVoiceAssistFromKeyguard() {
-            enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
             synchronized (this) {
                 if (mImpl == null) {
                     Slog.w(TAG, "launchVoiceAssistFromKeyguard without running voice interaction"
@@ -1739,34 +1737,34 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
         @Override
         public boolean isSessionRunning() {
-            enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
             synchronized (this) {
                 return mImpl != null && mImpl.mActiveSession != null;
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
         @Override
         public boolean activeServiceSupportsAssist() {
-            enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
             synchronized (this) {
                 return mImpl != null && mImpl.mInfo != null && mImpl.mInfo.getSupportsAssist();
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
         @Override
         public boolean activeServiceSupportsLaunchFromKeyguard() throws RemoteException {
-            enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
             synchronized (this) {
                 return mImpl != null && mImpl.mInfo != null
                         && mImpl.mInfo.getSupportsLaunchFromKeyguard();
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
         @Override
         public void onLockscreenShown() {
-            enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
             synchronized (this) {
                 if (mImpl == null) {
                     return;
@@ -1786,19 +1784,19 @@
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
         @Override
         public void registerVoiceInteractionSessionListener(
                 IVoiceInteractionSessionListener listener) {
-            enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
             synchronized (this) {
                 mVoiceInteractionSessionListeners.register(listener);
             }
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
         @Override
         public void getActiveServiceSupportedActions(List<String> voiceActions,
                 IVoiceActionCheckCallback callback) {
-            enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
             synchronized (this) {
                 if (mImpl == null) {
                     try {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index a061618..093e976 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -399,8 +399,8 @@
             final int taskId = data.getInt(ASSIST_TASK_ID);
             final IBinder activityId = data.getBinder(ASSIST_ACTIVITY_ID);
             final Bundle assistData = data.getBundle(ASSIST_KEY_DATA);
-            final AssistStructure structure = data.getParcelable(ASSIST_KEY_STRUCTURE);
-            final AssistContent content = data.getParcelable(ASSIST_KEY_CONTENT);
+            final AssistStructure structure = data.getParcelable(ASSIST_KEY_STRUCTURE, android.app.assist.AssistStructure.class);
+            final AssistContent content = data.getParcelable(ASSIST_KEY_CONTENT, android.app.assist.AssistContent.class);
             int uid = -1;
             if (assistData != null) {
                 uid = assistData.getInt(Intent.EXTRA_ASSIST_UID, -1);
diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java
index 37b4e65..d1d16ff 100644
--- a/telecomm/java/android/telecom/CallScreeningService.java
+++ b/telecomm/java/android/telecom/CallScreeningService.java
@@ -495,6 +495,9 @@
              * Note: Calls will still be logged with type
              * {@link android.provider.CallLog.Calls#BLOCKED_TYPE}, regardless of how this property
              * is set.
+             * <p>
+             * Note: Only the carrier and system call screening apps can use this parameter;
+             * this parameter is ignored otherwise.
              */
             public Builder setSkipCallLog(boolean shouldSkipCallLog) {
                 mShouldSkipCallLog = shouldSkipCallLog;
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index bce6809..f341bc2 100755
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -2044,7 +2044,7 @@
         if (isHandover) {
             PhoneAccountHandle fromPhoneAccountHandle = request.getExtras() != null
                     ? (PhoneAccountHandle) request.getExtras().getParcelable(
-                    TelecomManager.EXTRA_HANDOVER_FROM_PHONE_ACCOUNT) : null;
+                    TelecomManager.EXTRA_HANDOVER_FROM_PHONE_ACCOUNT, android.telecom.PhoneAccountHandle.class) : null;
             if (!isIncoming) {
                 connection = onCreateOutgoingHandoverConnection(fromPhoneAccountHandle, request);
             } else {
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 0f7dde5..9fcf44e 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1269,7 +1269,7 @@
         if (service != null) {
             try {
                 return service.getPhoneAccountsSupportingScheme(uriScheme,
-                        mContext.getOpPackageName());
+                        mContext.getOpPackageName()).getList();
             } catch (RemoteException e) {
                 Log.e(TAG, "Error calling ITelecomService#getPhoneAccountsSupportingScheme", e);
             }
@@ -1312,7 +1312,7 @@
         if (service != null) {
             try {
                 return service.getSelfManagedPhoneAccounts(mContext.getOpPackageName(),
-                        mContext.getAttributionTag());
+                        mContext.getAttributionTag()).getList();
             } catch (RemoteException e) {
                 Log.e(TAG, "Error calling ITelecomService#getSelfManagedPhoneAccounts()", e);
             }
@@ -1340,7 +1340,7 @@
         if (service != null) {
             try {
                 return service.getOwnSelfManagedPhoneAccounts(mContext.getOpPackageName(),
-                        mContext.getAttributionTag());
+                        mContext.getAttributionTag()).getList();
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -1366,7 +1366,7 @@
         if (service != null) {
             try {
                 return service.getCallCapablePhoneAccounts(includeDisabledAccounts,
-                        mContext.getOpPackageName(), mContext.getAttributionTag());
+                        mContext.getOpPackageName(), mContext.getAttributionTag()).getList();
             } catch (RemoteException e) {
                 Log.e(TAG, "Error calling ITelecomService#getCallCapablePhoneAccounts("
                         + includeDisabledAccounts + ")", e);
@@ -1390,7 +1390,7 @@
         ITelecomService service = getTelecomService();
         if (service != null) {
             try {
-                return service.getPhoneAccountsForPackage(mContext.getPackageName());
+                return service.getPhoneAccountsForPackage(mContext.getPackageName()).getList();
             } catch (RemoteException e) {
                 Log.e(TAG, "Error calling ITelecomService#getPhoneAccountsForPackage", e);
             }
@@ -1450,7 +1450,7 @@
         ITelecomService service = getTelecomService();
         if (service != null) {
             try {
-                return service.getAllPhoneAccounts();
+                return service.getAllPhoneAccounts().getList();
             } catch (RemoteException e) {
                 Log.e(TAG, "Error calling ITelecomService#getAllPhoneAccounts", e);
             }
@@ -1469,7 +1469,7 @@
         ITelecomService service = getTelecomService();
         if (service != null) {
             try {
-                return service.getAllPhoneAccountHandles();
+                return service.getAllPhoneAccountHandles().getList();
             } catch (RemoteException e) {
                 Log.e(TAG, "Error calling ITelecomService#getAllPhoneAccountHandles", e);
             }
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 101280a..f1a6dd1 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -24,6 +24,7 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.telecom.PhoneAccount;
+import android.content.pm.ParceledListSlice;
 
 /**
  * Interface used to interact with Telecom. Mostly this is used by TelephonyManager for passing
@@ -57,31 +58,31 @@
     /**
      * @see TelecomServiceImpl#getCallCapablePhoneAccounts
      */
-    List<PhoneAccountHandle> getCallCapablePhoneAccounts(
+    ParceledListSlice<PhoneAccountHandle> getCallCapablePhoneAccounts(
             boolean includeDisabledAccounts, String callingPackage, String callingFeatureId);
 
     /**
      * @see TelecomServiceImpl#getSelfManagedPhoneAccounts
      */
-    List<PhoneAccountHandle> getSelfManagedPhoneAccounts(String callingPackage,
+    ParceledListSlice<PhoneAccountHandle> getSelfManagedPhoneAccounts(String callingPackage,
             String callingFeatureId);
 
     /**
      * @see TelecomServiceImpl#getOwnSelfManagedPhoneAccounts
      */
-    List<PhoneAccountHandle> getOwnSelfManagedPhoneAccounts(String callingPackage,
+    ParceledListSlice<PhoneAccountHandle> getOwnSelfManagedPhoneAccounts(String callingPackage,
             String callingFeatureId);
 
     /**
      * @see TelecomManager#getPhoneAccountsSupportingScheme
      */
-    List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(in String uriScheme,
+    ParceledListSlice<PhoneAccountHandle> getPhoneAccountsSupportingScheme(in String uriScheme,
             String callingPackage);
 
     /**
      * @see TelecomManager#getPhoneAccountsForPackage
      */
-    List<PhoneAccountHandle> getPhoneAccountsForPackage(in String packageName);
+    ParceledListSlice<PhoneAccountHandle> getPhoneAccountsForPackage(in String packageName);
 
     /**
      * @see TelecomManager#getPhoneAccount
@@ -96,12 +97,12 @@
     /**
      * @see TelecomManager#getAllPhoneAccounts
      */
-    List<PhoneAccount> getAllPhoneAccounts();
+    ParceledListSlice<PhoneAccount> getAllPhoneAccounts();
 
     /**
      * @see TelecomManager#getAllPhoneAccountHandles
      */
-    List<PhoneAccountHandle> getAllPhoneAccountHandles();
+    ParceledListSlice<PhoneAccountHandle> getAllPhoneAccountHandles();
 
     /**
      * @see TelecomServiceImpl#getSimCallManager
diff --git a/telephony/common/com/android/internal/telephony/SmsApplication.java b/telephony/common/com/android/internal/telephony/SmsApplication.java
index 4924a82..4230225 100644
--- a/telephony/common/com/android/internal/telephony/SmsApplication.java
+++ b/telephony/common/com/android/internal/telephony/SmsApplication.java
@@ -1146,4 +1146,35 @@
         }
         return null;
     }
+
+    /**
+     * Check if a package is default mms app (or equivalent, like bluetooth)
+     *
+     * @param context context from the calling app
+     * @param packageName the name of the package to be checked
+     * @return true if the package is default mms app or bluetooth
+     */
+    @UnsupportedAppUsage
+    public static boolean isDefaultMmsApplication(Context context, String packageName) {
+        if (packageName == null) {
+            return false;
+        }
+        String defaultMmsPackage = getDefaultMmsApplicationPackageName(context);
+        String bluetoothPackageName = context.getResources()
+                .getString(com.android.internal.R.string.config_systemBluetoothStack);
+
+        if ((defaultMmsPackage != null && defaultMmsPackage.equals(packageName))
+                || bluetoothPackageName.equals(packageName)) {
+            return true;
+        }
+        return false;
+    }
+
+    private static String getDefaultMmsApplicationPackageName(Context context) {
+        ComponentName component = getDefaultMmsApplication(context, false);
+        if (component != null) {
+            return component.getPackageName();
+        }
+        return null;
+    }
 }
diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java
index 38becc6..297940e 100644
--- a/telephony/java/android/telephony/CellSignalStrengthNr.java
+++ b/telephony/java/android/telephony/CellSignalStrengthNr.java
@@ -49,7 +49,7 @@
     private static final String TAG = "CellSignalStrengthNr";
 
     // Lifted from Default carrier configs and max range of SSRSRP
-    // Boundaries: [-140 dB, -44 dB]
+    // Boundaries: [-156 dB, -31 dB]
     private int[] mSsRsrpThresholds = new int[] {
             -110, /* SIGNAL_STRENGTH_POOR */
             -90, /* SIGNAL_STRENGTH_MODERATE */
@@ -173,14 +173,14 @@
      */
     public CellSignalStrengthNr(int csiRsrp, int csiRsrq, int csiSinr, int csiCqiTableIndex,
             List<Byte> csiCqiReport, int ssRsrp, int ssRsrq, int ssSinr) {
-        mCsiRsrp = inRangeOrUnavailable(csiRsrp, -140, -44);
+        mCsiRsrp = inRangeOrUnavailable(csiRsrp, -156, -31);
         mCsiRsrq = inRangeOrUnavailable(csiRsrq, -20, -3);
         mCsiSinr = inRangeOrUnavailable(csiSinr, -23, 23);
         mCsiCqiTableIndex = inRangeOrUnavailable(csiCqiTableIndex, 1, 3);
         mCsiCqiReport = csiCqiReport.stream()
-                .map(cqi -> new Integer(inRangeOrUnavailable(Byte.toUnsignedInt(cqi), 0, 15)))
+                .map(cqi -> inRangeOrUnavailable(Byte.toUnsignedInt(cqi), 0, 15))
                 .collect(Collectors.toList());
-        mSsRsrp = inRangeOrUnavailable(ssRsrp, -140, -44);
+        mSsRsrp = inRangeOrUnavailable(ssRsrp, -156, -31);
         mSsRsrq = inRangeOrUnavailable(ssRsrq, -43, 20);
         mSsSinr = inRangeOrUnavailable(ssSinr, -23, 40);
         updateLevel(null, null);
@@ -212,8 +212,8 @@
     }
 
     /**
-     * Reference: 3GPP TS 38.215.
-     * Range: -140 dBm to -44 dBm.
+     * Reference: 3GPP TS 38.133 10.1.6.1.
+     * Range: -156 dBm to -31 dBm.
      * @return SS reference signal received power, {@link CellInfo#UNAVAILABLE} means unreported
      * value.
      */
@@ -242,8 +242,8 @@
     }
 
     /**
-     * Reference: 3GPP TS 38.215.
-     * Range: -140 dBm to -44 dBm.
+     * Reference: 3GPP TS 38.133 10.1.6.1.
+     * Range: -156 dBm to -31 dBm.
      * @return CSI reference signal received power, {@link CellInfo#UNAVAILABLE} means unreported
      * value.
      */
diff --git a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
index 24dfbd0..a004cc3 100644
--- a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
+++ b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
@@ -21,6 +21,7 @@
 import android.text.Editable;
 import android.text.Selection;
 import android.text.TextWatcher;
+import android.text.style.TtsSpan;
 
 import com.android.i18n.phonenumbers.AsYouTypeFormatter;
 import com.android.i18n.phonenumbers.PhoneNumberUtil;
@@ -119,6 +120,13 @@
             }
             mSelfChange = false;
         }
+
+        //remove previous TTS spans
+        TtsSpan[] ttsSpans = s.getSpans(0, s.length(), TtsSpan.class);
+        for (TtsSpan ttsSpan : ttsSpans) {
+            s.removeSpan(ttsSpan);
+        }
+
         PhoneNumberUtils.ttsSpanAsPhoneNumber(s, 0, s.length());
     }
 
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 6fe9bf9..bfa60ba 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -1445,7 +1445,7 @@
      */
     @UnsupportedAppUsage
     private void setFromNotifierBundle(Bundle m) {
-        ServiceState ssFromBundle = m.getParcelable(EXTRA_SERVICE_STATE);
+        ServiceState ssFromBundle = m.getParcelable(EXTRA_SERVICE_STATE, android.telephony.ServiceState.class);
         if (ssFromBundle != null) {
             copyFrom(ssFromBundle);
         }
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index f74ef0f..f1af68f 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -906,12 +906,12 @@
     @Deprecated
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     private void setFromNotifierBundle(Bundle m) {
-        mCdma = m.getParcelable("Cdma");
-        mGsm = m.getParcelable("Gsm");
-        mWcdma = m.getParcelable("Wcdma");
-        mTdscdma = m.getParcelable("Tdscdma");
-        mLte = m.getParcelable("Lte");
-        mNr = m.getParcelable("Nr");
+        mCdma = m.getParcelable("Cdma", android.telephony.CellSignalStrengthCdma.class);
+        mGsm = m.getParcelable("Gsm", android.telephony.CellSignalStrengthGsm.class);
+        mWcdma = m.getParcelable("Wcdma", android.telephony.CellSignalStrengthWcdma.class);
+        mTdscdma = m.getParcelable("Tdscdma", android.telephony.CellSignalStrengthTdscdma.class);
+        mLte = m.getParcelable("Lte", android.telephony.CellSignalStrengthLte.class);
+        mNr = m.getParcelable("Nr", android.telephony.CellSignalStrengthNr.class);
     }
 
     /**
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 432d087..a7468a9 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -4867,7 +4867,7 @@
                                 return;
                             }
                             ParcelUuid resultUuid =
-                                    result.getParcelable(KEY_CALL_COMPOSER_PICTURE_HANDLE);
+                                    result.getParcelable(KEY_CALL_COMPOSER_PICTURE_HANDLE, android.os.ParcelUuid.class);
                             if (resultUuid == null) {
                                 Log.e(TAG, "Got null uuid without an error"
                                         + " while uploading call composer pic");
@@ -8417,6 +8417,51 @@
     }
 
     /**
+     * Fetches the sim service table from the EFUST/EFIST based on the application type
+     * {@link #APPTYPE_USIM} or {@link #APPTYPE_ISIM}. The return value is hexaString format
+     * representing X bytes (x >= 1). Each bit of every byte indicates which optional services
+     * are available for the given application type.
+     * The USIM service table EF is described in as per Section 4.2.8 of 3GPP TS 31.102.
+     * The ISIM service table EF is described in as per Section 4.2.7 of 3GPP TS 31.103.
+     * The list of services mapped to the exact nth byte of response as mentioned in Section 4.2
+     * .7 of 3GPP TS 31.103. Eg. Service n°1: Local Phone Book, Service n°2: Fixed Dialling
+     * Numbers (FDN) - Bit 1 and 2 of the 1st Byte represent service Local Phone Book and Fixed
+     * Dialling Numbers (FDN)respectively. The coding format for each service type  should be
+     * interpreted as bit = 1: service available;bit = 0:service not available.
+     *
+     * @param appType of type int of either {@link #APPTYPE_USIM} or {@link #APPTYPE_ISIM}.
+     * @return HexString represents sim service table else null.
+     * @throws SecurityException if the caller does not have the required permission/privileges
+     * @hide
+     */
+
+    @Nullable
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
+    public String getSimServiceTable(int appType) {
+        try {
+            IPhoneSubInfo info = getSubscriberInfoService();
+            if (info == null) {
+                Rlog.e(TAG, "getSimServiceTable(): IPhoneSubInfo is null");
+                return null;
+            }
+            //Fetches the sim service table based on subId and appType
+            if (appType == APPTYPE_ISIM) {
+                return info.getIsimIst(getSubId());
+            } else if ((appType == APPTYPE_USIM)) {
+                return info.getSimServiceTable(getSubId(), APPTYPE_USIM);
+            } else {
+                return null;
+            }
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "getSimServiceTable(): RemoteException=" + ex.getMessage());
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "getSimServiceTable(): NullPointerException=" + ex.getMessage());
+        }
+        return null;
+    }
+
+    /**
      * Resets the {@link android.telephony.ims.ImsService} associated with the specified sim slot.
      * Used by diagnostic apps to force the IMS stack to be disabled and re-enabled in an effort to
      * recover from scenarios where the {@link android.telephony.ims.ImsService} gets in to a bad
@@ -10375,7 +10420,7 @@
             protected void onReceiveResult(int resultCode, Bundle ussdResponse) {
                 Rlog.d(TAG, "USSD:" + resultCode);
                 checkNotNull(ussdResponse, "ussdResponse cannot be null.");
-                UssdResponse response = ussdResponse.getParcelable(USSD_RESPONSE);
+                UssdResponse response = ussdResponse.getParcelable(USSD_RESPONSE, android.telephony.UssdResponse.class);
 
                 if (resultCode == USSD_RETURN_SUCCESS) {
                     callback.onReceiveUssdResponse(telephonyManager, response.getUssdRequest(),
@@ -15921,6 +15966,17 @@
     }
 
     /**
+     * Setup sIPhoneSubInfo for testing.
+     * @hide
+     */
+    @VisibleForTesting
+    public static void setupIPhoneSubInfoForTest(IPhoneSubInfo iPhoneSubInfo) {
+        synchronized (sCacheLock) {
+            sIPhoneSubInfo = iPhoneSubInfo;
+        }
+    }
+
+    /**
      * Whether device can connect to 5G network when two SIMs are active.
      * @hide
      * TODO b/153669716: remove or make system API.
@@ -16867,7 +16923,7 @@
                         }
 
                         NetworkSlicingConfig slicingConfig =
-                                result.getParcelable(KEY_SLICING_CONFIG_HANDLE);
+                                result.getParcelable(KEY_SLICING_CONFIG_HANDLE, android.telephony.data.NetworkSlicingConfig.class);
                         executor.execute(() -> callback.onResult(slicingConfig));
                     }
             });
diff --git a/telephony/java/android/telephony/UiccSlotInfo.java b/telephony/java/android/telephony/UiccSlotInfo.java
index 06c5b5c..5e02532 100644
--- a/telephony/java/android/telephony/UiccSlotInfo.java
+++ b/telephony/java/android/telephony/UiccSlotInfo.java
@@ -129,7 +129,7 @@
         this.mLogicalSlotIdx = logicalSlotIdx;
         this.mIsExtendedApduSupported = isExtendedApduSupported;
         this.mIsRemovable = false;
-        this.mPortList = null;
+        this.mPortList = new ArrayList<UiccPortInfo>();
     }
 
     /**
diff --git a/telephony/java/android/telephony/VisualVoicemailService.java b/telephony/java/android/telephony/VisualVoicemailService.java
index fe30eb7..a530917 100644
--- a/telephony/java/android/telephony/VisualVoicemailService.java
+++ b/telephony/java/android/telephony/VisualVoicemailService.java
@@ -157,14 +157,14 @@
         @Override
         public void handleMessage(final Message msg) {
             final PhoneAccountHandle handle = msg.getData()
-                    .getParcelable(DATA_PHONE_ACCOUNT_HANDLE);
+                    .getParcelable(DATA_PHONE_ACCOUNT_HANDLE, android.telecom.PhoneAccountHandle.class);
             VisualVoicemailTask task = new VisualVoicemailTask(msg.replyTo, msg.arg1);
             switch (msg.what) {
                 case MSG_ON_CELL_SERVICE_CONNECTED:
                     onCellServiceConnected(task, handle);
                     break;
                 case MSG_ON_SMS_RECEIVED:
-                    VisualVoicemailSms sms = msg.getData().getParcelable(DATA_SMS);
+                    VisualVoicemailSms sms = msg.getData().getParcelable(DATA_SMS, android.telephony.VisualVoicemailSms.class);
                     onSmsReceived(task, sms);
                     break;
                 case MSG_ON_SIM_REMOVED:
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index 1252dc1..7d63688 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -1001,7 +1001,7 @@
     public void startResolutionActivity(Activity activity, int requestCode, Intent resultIntent,
             PendingIntent callbackIntent) throws IntentSender.SendIntentException {
         PendingIntent resolutionIntent =
-                resultIntent.getParcelableExtra(EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT);
+                resultIntent.getParcelableExtra(EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT, android.app.PendingIntent.class);
         if (resolutionIntent == null) {
             throw new IllegalArgumentException("Invalid result intent");
         }
@@ -1032,7 +1032,7 @@
         if (!isEnabled()) {
             PendingIntent callbackIntent =
                     resolutionIntent.getParcelableExtra(
-                            EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT);
+                            EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT, android.app.PendingIntent.class);
             if (callbackIntent != null) {
                 sendUnavailableError(callbackIntent);
             }
diff --git a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
index dd1061f..556d6f4 100644
--- a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
+++ b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
@@ -195,7 +195,7 @@
                 return false;
             }
             DownloadRequest request = intent.getParcelableExtra(
-                    MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST);
+                    MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST, android.telephony.mbms.DownloadRequest.class);
             String expectedTokenFileName = request.getHash() + DOWNLOAD_TOKEN_SUFFIX;
             File expectedTokenFile = new File(
                     MbmsUtils.getEmbmsTempFileDirForService(context, request.getFileServiceId()),
@@ -236,7 +236,7 @@
 
     private void moveDownloadedFile(Context context, Intent intent) {
         DownloadRequest request = intent.getParcelableExtra(
-                MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST);
+                MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST, android.telephony.mbms.DownloadRequest.class);
         Intent intentForApp = request.getIntentForApp();
         if (intentForApp == null) {
             Log.i(LOG_TAG, "Malformed app notification intent");
@@ -256,7 +256,7 @@
             return;
         }
 
-        Uri finalTempFile = intent.getParcelableExtra(VendorUtils.EXTRA_FINAL_URI);
+        Uri finalTempFile = intent.getParcelableExtra(VendorUtils.EXTRA_FINAL_URI, android.net.Uri.class);
         if (!verifyTempFilePath(context, request.getFileServiceId(), finalTempFile)) {
             Log.w(LOG_TAG, "Download result specified an invalid temp file " + finalTempFile);
             setResultCode(RESULT_DOWNLOAD_FINALIZATION_ERROR);
@@ -264,7 +264,7 @@
         }
 
         FileInfo completedFileInfo =
-                (FileInfo) intent.getParcelableExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO);
+                (FileInfo) intent.getParcelableExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO, android.telephony.mbms.FileInfo.class);
         Path appSpecifiedDestination = FileSystems.getDefault().getPath(
                 request.getDestinationUri().getPath());
 
@@ -288,13 +288,13 @@
 
     private void cleanupPostMove(Context context, Intent intent) {
         DownloadRequest request = intent.getParcelableExtra(
-                MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST);
+                MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST, android.telephony.mbms.DownloadRequest.class);
         if (request == null) {
             Log.w(LOG_TAG, "Intent does not include a DownloadRequest. Ignoring.");
             return;
         }
 
-        List<Uri> tempFiles = intent.getParcelableArrayListExtra(VendorUtils.EXTRA_TEMP_LIST);
+        List<Uri> tempFiles = intent.getParcelableArrayListExtra(VendorUtils.EXTRA_TEMP_LIST, android.net.Uri.class);
         if (tempFiles == null) {
             return;
         }
@@ -318,7 +318,7 @@
             return;
         }
         int fdCount = intent.getIntExtra(VendorUtils.EXTRA_FD_COUNT, 0);
-        List<Uri> pausedList = intent.getParcelableArrayListExtra(VendorUtils.EXTRA_PAUSED_LIST);
+        List<Uri> pausedList = intent.getParcelableArrayListExtra(VendorUtils.EXTRA_PAUSED_LIST, android.net.Uri.class);
 
         if (fdCount == 0 && (pausedList == null || pausedList.size() == 0)) {
             Log.i(LOG_TAG, "No temp files actually requested. Ending.");
@@ -417,7 +417,7 @@
         String serviceId = intent.getStringExtra(VendorUtils.EXTRA_SERVICE_ID);
         File tempFileDir = MbmsUtils.getEmbmsTempFileDirForService(context, serviceId);
         final List<Uri> filesInUse =
-                intent.getParcelableArrayListExtra(VendorUtils.EXTRA_TEMP_FILES_IN_USE);
+                intent.getParcelableArrayListExtra(VendorUtils.EXTRA_TEMP_FILES_IN_USE, android.net.Uri.class);
         File[] filesToDelete = tempFileDir.listFiles(new FileFilter() {
             @Override
             public boolean accept(File file) {
diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
index 78335fd..4fa7f43 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
@@ -232,4 +232,26 @@
      */
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)")
     String getSmscIdentity(int subId, int appType);
+
+    /**
+     * Fetches the sim service table from the EFUST/EFIST based on the application type
+     * {@link #APPTYPE_USIM} or {@link #APPTYPE_ISIM}. The return value is hexaString format
+     * representing X bytes (x >= 1). Each bit of every byte indicates which optional services
+     * are available for the given application type.
+     * The USIM service table EF is described in as per Section 4.2.8 of 3GPP TS 31.102.
+     * The ISIM service table EF is described in as per Section 4.2.7 of 3GPP TS 31.103.
+     * The list of services mapped to the exact nth byte of response as mentioned in Section 4.2
+     * .7 of 3GPP TS 31.103. Eg. Service n°1: Local Phone Book, Service n°2: Fixed Dialling
+     * Numbers (FDN) - Bit 1 and 2 of the 1st Byte represent service Local Phone Book and Fixed
+     * Dialling Numbers (FDN)respectively. The coding format for each service type  should be
+     * interpreted as bit = 1: service available;bit = 0:service not available.
+     *
+     * @param appType of type int of either {@link #APPTYPE_USIM} or {@link #APPTYPE_ISIM}.
+     * @return HexString represents sim service table else null.
+     * @throws SecurityException if the caller does not have the required permission/privileges
+     * @hide
+     */
+
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)")
+    String getSimServiceTable(int subId, int appType);
 }
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index b905212..09101d8 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -212,23 +212,6 @@
     public static final String SECRET_CODE_ACTION = "android.provider.Telephony.SECRET_CODE";
 
     /**
-     * <p>Broadcast Action: It indicates one column of a subinfo record has been changed
-     * <p class="note">This is a protected intent that can only be sent
-     * by the system.
-     */
-    public static final String ACTION_SUBINFO_CONTENT_CHANGE
-            = "android.intent.action.ACTION_SUBINFO_CONTENT_CHANGE";
-
-    /**
-     * <p>Broadcast Action: It indicates subinfo record update is completed
-     * when SIM inserted state change
-     * <p class="note">This is a protected intent that can only be sent
-     * by the system.
-     */
-    public static final String ACTION_SUBINFO_RECORD_UPDATED
-            = "android.intent.action.ACTION_SUBINFO_RECORD_UPDATED";
-
-    /**
      * Broadcast Action: The default subscription has changed.  This has the following
      * extra values:</p>
      * <ul>
diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp
index 7731e09..855d3c1 100644
--- a/tests/FlickerTests/Android.bp
+++ b/tests/FlickerTests/Android.bp
@@ -46,6 +46,7 @@
         "launcher-helper-lib",
         "launcher-aosp-tapl",
         "platform-test-annotations",
+        "wm-flicker-window-extensions",
     ],
 }
 
@@ -83,5 +84,21 @@
         "flickertestapplib",
         "truth-prebuilt",
         "app-helpers-core",
+        "wm-flicker-window-extensions",
     ],
 }
+
+android_library_import {
+    name: "wm-flicker-window-extensions_nodeps",
+    aars: ["libs/window-extensions-release.aar"],
+    sdk_version: "current",
+}
+
+java_library {
+    name: "wm-flicker-window-extensions",
+    sdk_version: "current",
+    static_libs: [
+        "wm-flicker-window-extensions_nodeps",
+    ],
+    installable: false,
+}
diff --git a/tests/FlickerTests/AndroidManifest.xml b/tests/FlickerTests/AndroidManifest.xml
index fda6091..e173eba0 100644
--- a/tests/FlickerTests/AndroidManifest.xml
+++ b/tests/FlickerTests/AndroidManifest.xml
@@ -43,6 +43,7 @@
     <!-- Allow the test to write directly to /sdcard/ -->
     <application android:requestLegacyExternalStorage="true">
         <uses-library android:name="android.test.runner"/>
+        <uses-library android:name="androidx.window.extensions" android:required="false"/>
     </application>
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/tests/FlickerTests/libs/window-extensions-release.aar b/tests/FlickerTests/libs/window-extensions-release.aar
new file mode 100644
index 0000000..6fc9a67
--- /dev/null
+++ b/tests/FlickerTests/libs/window-extensions-release.aar
Binary files differ
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
new file mode 100644
index 0000000..24c4661
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker
+
+import android.app.Instrumentation
+import android.platform.test.annotations.Presubmit
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.traces.common.ComponentMatcher
+import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
+import org.junit.Assume
+import org.junit.Test
+
+/**
+ * Base test class containing common assertions for [ComponentMatcher.NAV_BAR],
+ * [ComponentMatcher.TASK_BAR], [ComponentMatcher.STATUS_BAR], and general assertions
+ * (layers visible in consecutive states, entire screen covered, etc.)
+ */
+abstract class BaseTest @JvmOverloads constructor(
+    protected val testSpec: FlickerTestParameter,
+    protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation(),
+    protected val tapl: LauncherInstrumentation = LauncherInstrumentation()
+) {
+    init {
+        testSpec.setIsTablet(
+            WindowManagerStateHelper(instrumentation).currentState.wmState.isTablet
+        )
+    }
+
+    /**
+     * Specification of the test transition to execute
+     */
+    abstract val transition: FlickerBuilder.() -> Unit
+
+    /**
+     * Entry point for the test runner. It will use this method to initialize and cache
+     * flicker executions
+     */
+    @FlickerBuilderProvider
+    fun buildFlicker(): FlickerBuilder {
+        return FlickerBuilder(instrumentation).apply {
+            setup {
+                test {
+                    testSpec.setIsTablet(wmHelper.currentState.wmState.isTablet)
+                }
+            }
+            transition()
+        }
+    }
+
+    /**
+     * Checks that all parts of the screen are covered during the transition
+     */
+    @Presubmit
+    @Test
+    open fun entireScreenCovered() = testSpec.entireScreenCovered()
+
+    /**
+     * Checks that the [ComponentMatcher.NAV_BAR] layer is visible during the whole transition
+     *
+     * Note: Phones only
+     */
+    @Presubmit
+    @Test
+    open fun navBarLayerIsVisibleAtStartAndEnd() {
+        Assume.assumeFalse(testSpec.isTablet)
+        testSpec.navBarLayerIsVisibleAtStartAndEnd()
+    }
+
+    /**
+     * Checks the position of the [ComponentMatcher.NAV_BAR] at the start and end of the transition
+     *
+     * Note: Phones only
+     */
+    @Presubmit
+    @Test
+    open fun navBarLayerPositionAtStartAndEnd() {
+        Assume.assumeFalse(testSpec.isTablet)
+        testSpec.navBarLayerPositionAtStartAndEnd()
+    }
+
+    /**
+     * Checks that the [ComponentMatcher.NAV_BAR] window is visible during the whole transition
+     *
+     * Note: Phones only
+     */
+    @Presubmit
+    @Test
+    open fun navBarWindowIsAlwaysVisible() {
+        Assume.assumeFalse(testSpec.isTablet)
+        testSpec.navBarWindowIsAlwaysVisible()
+    }
+
+    /**
+     * Checks that the [ComponentMatcher.TASK_BAR] layer is visible during the whole transition
+     *
+     * Note: Large screen only
+     */
+    @Presubmit
+    @Test
+    open fun taskBarLayerIsVisibleAtStartAndEnd() {
+        Assume.assumeTrue(testSpec.isTablet)
+        testSpec.taskBarLayerIsVisibleAtStartAndEnd()
+    }
+
+    /**
+     * Checks that the [ComponentMatcher.TASK_BAR] window is visible during the whole transition
+     *
+     * Note: Large screen only
+     */
+    @Presubmit
+    @Test
+    open fun taskBarWindowIsAlwaysVisible() {
+        Assume.assumeTrue(testSpec.isTablet)
+        testSpec.taskBarWindowIsAlwaysVisible()
+    }
+
+    /**
+     * Checks that the [ComponentMatcher.STATUS_BAR] layer is visible during the whole transition
+     */
+    @Presubmit
+    @Test
+    open fun statusBarLayerIsVisibleAtStartAndEnd() =
+        testSpec.statusBarLayerIsVisibleAtStartAndEnd()
+
+    /**
+     * Checks the position of the [ComponentMatcher.STATUS_BAR] at the start and end of the
+     * transition
+     */
+    @Presubmit
+    @Test
+    open fun statusBarLayerPositionAtStartAndEnd() = testSpec.statusBarLayerPositionAtStartAndEnd()
+
+    /**
+     * Checks that the [ComponentMatcher.STATUS_BAR] window is visible during the whole transition
+     */
+    @Presubmit
+    @Test
+    open fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible()
+
+    /**
+     * Checks that all layers that are visible on the trace, are visible for at least 2
+     * consecutive entries.
+     */
+    @Presubmit
+    @Test
+    open fun visibleLayersShownMoreThanOneConsecutiveEntry() {
+        testSpec.assertLayers {
+            this.visibleLayersShownMoreThanOneConsecutiveEntry()
+        }
+    }
+
+    /**
+     * Checks that all windows that are visible on the trace, are visible for at least 2
+     * consecutive entries.
+     */
+    @Presubmit
+    @Test
+    open fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
+        testSpec.assertWm {
+            this.visibleWindowsShownMoreThanOneConsecutiveEntry()
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
index 896c730..d173b72 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
@@ -19,30 +19,36 @@
 
 import com.android.server.wm.flicker.helpers.WindowUtils
 import com.android.server.wm.flicker.traces.region.RegionSubject
-import com.android.server.wm.traces.common.FlickerComponentName
-
-val LAUNCHER_COMPONENT = FlickerComponentName(
-    "com.google.android.apps.nexuslauncher",
-    "com.google.android.apps.nexuslauncher.NexusLauncherActivity"
-)
+import com.android.server.wm.traces.common.ComponentMatcher
+import com.android.server.wm.traces.common.IComponentMatcher
 
 /**
- * Checks that [FlickerComponentName.STATUS_BAR] window is visible and above the app windows in
+ * Checks that [ComponentMatcher.STATUS_BAR] window is visible and above the app windows in
  * all WM trace entries
  */
-fun FlickerTestParameter.statusBarWindowIsVisible() {
+fun FlickerTestParameter.statusBarWindowIsAlwaysVisible() {
     assertWm {
-        this.isAboveAppWindowVisible(FlickerComponentName.STATUS_BAR)
+        this.isAboveAppWindowVisible(ComponentMatcher.STATUS_BAR)
     }
 }
 
 /**
- * Checks that [FlickerComponentName.NAV_BAR] window is visible and above the app windows in
+ * Checks that [ComponentMatcher.NAV_BAR] window is visible and above the app windows in
  * all WM trace entries
  */
-fun FlickerTestParameter.navBarWindowIsVisible() {
+fun FlickerTestParameter.navBarWindowIsAlwaysVisible() {
     assertWm {
-        this.isAboveAppWindowVisible(FlickerComponentName.NAV_BAR)
+        this.isAboveAppWindowVisible(ComponentMatcher.NAV_BAR)
+    }
+}
+
+/**
+ * Checks that [ComponentMatcher.TASK_BAR] window is visible and above the app windows in
+ * all WM trace entries
+ */
+fun FlickerTestParameter.taskBarWindowIsAlwaysVisible() {
+    assertWm {
+        this.isAboveAppWindowVisible(ComponentMatcher.TASK_BAR)
     }
 }
 
@@ -80,113 +86,126 @@
 }
 
 /**
- * Checks that [FlickerComponentName.NAV_BAR] layer is visible at the start and end of the SF
+ * Checks that [ComponentMatcher.NAV_BAR] layer is visible at the start and end of the SF
  * trace
  */
-fun FlickerTestParameter.navBarLayerIsVisible() {
+fun FlickerTestParameter.navBarLayerIsVisibleAtStartAndEnd() {
     assertLayersStart {
-        this.isVisible(FlickerComponentName.NAV_BAR)
+        this.isVisible(ComponentMatcher.NAV_BAR)
     }
     assertLayersEnd {
-        this.isVisible(FlickerComponentName.NAV_BAR)
+        this.isVisible(ComponentMatcher.NAV_BAR)
     }
 }
 
 /**
- * Checks that [FlickerComponentName.STATUS_BAR] layer is visible at the start and end of the SF
+ * Checks that [ComponentMatcher.TASK_BAR] layer is visible at the start and end of the SF
  * trace
  */
-fun FlickerTestParameter.statusBarLayerIsVisible() {
+fun FlickerTestParameter.taskBarLayerIsVisibleAtStartAndEnd() {
     assertLayersStart {
-        this.isVisible(FlickerComponentName.STATUS_BAR)
+        this.isVisible(ComponentMatcher.TASK_BAR)
     }
     assertLayersEnd {
-        this.isVisible(FlickerComponentName.STATUS_BAR)
+        this.isVisible(ComponentMatcher.TASK_BAR)
     }
 }
 
 /**
- * Asserts that the [FlickerComponentName.NAV_BAR] layer is at the correct position at the start
+ * Checks that [ComponentMatcher.STATUS_BAR] layer is visible at the start and end of the SF
+ * trace
+ */
+fun FlickerTestParameter.statusBarLayerIsVisibleAtStartAndEnd() {
+    assertLayersStart {
+        this.isVisible(ComponentMatcher.STATUS_BAR)
+    }
+    assertLayersEnd {
+        this.isVisible(ComponentMatcher.STATUS_BAR)
+    }
+}
+
+/**
+ * Asserts that the [ComponentMatcher.NAV_BAR] layer is at the correct position at the start
  * of the SF trace
  */
-fun FlickerTestParameter.navBarLayerPositionStart() {
+fun FlickerTestParameter.navBarLayerPositionAtStart() {
     assertLayersStart {
         val display = this.entry.displays.firstOrNull { !it.isVirtual }
                 ?: error("There is no display!")
-        this.visibleRegion(FlickerComponentName.NAV_BAR)
+        this.visibleRegion(ComponentMatcher.NAV_BAR)
             .coversExactly(WindowUtils.getNavigationBarPosition(display, isGesturalNavigation))
     }
 }
 
 /**
- * Asserts that the [FlickerComponentName.NAV_BAR] layer is at the correct position at the end
+ * Asserts that the [ComponentMatcher.NAV_BAR] layer is at the correct position at the end
  * of the SF trace
  */
-fun FlickerTestParameter.navBarLayerPositionEnd() {
+fun FlickerTestParameter.navBarLayerPositionAtEnd() {
     assertLayersEnd {
         val display = this.entry.displays.minByOrNull { it.id }
             ?: throw RuntimeException("There is no display!")
-        this.visibleRegion(FlickerComponentName.NAV_BAR)
+        this.visibleRegion(ComponentMatcher.NAV_BAR)
             .coversExactly(WindowUtils.getNavigationBarPosition(display, isGesturalNavigation))
     }
 }
 
 /**
- * Asserts that the [FlickerComponentName.NAV_BAR] layer is at the correct position at the start
+ * Asserts that the [ComponentMatcher.NAV_BAR] layer is at the correct position at the start
  * and end of the SF trace
  */
-fun FlickerTestParameter.navBarLayerRotatesAndScales() {
-    navBarLayerPositionStart()
-    navBarLayerPositionEnd()
+fun FlickerTestParameter.navBarLayerPositionAtStartAndEnd() {
+    navBarLayerPositionAtStart()
+    navBarLayerPositionAtEnd()
 }
 
 /**
- * Asserts that the [FlickerComponentName.STATUS_BAR] layer is at the correct position at the start
+ * Asserts that the [ComponentMatcher.STATUS_BAR] layer is at the correct position at the start
  * of the SF trace
  */
-fun FlickerTestParameter.statusBarLayerPositionStart() {
+fun FlickerTestParameter.statusBarLayerPositionAtStart() {
     assertLayersStart {
         val display = this.entry.displays.minByOrNull { it.id }
             ?: throw RuntimeException("There is no display!")
-        this.visibleRegion(FlickerComponentName.STATUS_BAR)
+        this.visibleRegion(ComponentMatcher.STATUS_BAR)
             .coversExactly(WindowUtils.getStatusBarPosition(display))
     }
 }
 
 /**
- * Asserts that the [FlickerComponentName.STATUS_BAR] layer is at the correct position at the end
+ * Asserts that the [ComponentMatcher.STATUS_BAR] layer is at the correct position at the end
  * of the SF trace
  */
-fun FlickerTestParameter.statusBarLayerPositionEnd() {
+fun FlickerTestParameter.statusBarLayerPositionAtEnd() {
     assertLayersEnd {
         val display = this.entry.displays.minByOrNull { it.id }
             ?: throw RuntimeException("There is no display!")
-        this.visibleRegion(FlickerComponentName.STATUS_BAR)
+        this.visibleRegion(ComponentMatcher.STATUS_BAR)
             .coversExactly(WindowUtils.getStatusBarPosition(display))
     }
 }
 
 /**
- * Asserts that the [FlickerComponentName.STATUS_BAR] layer is at the correct position at the start
+ * Asserts that the [ComponentMatcher.STATUS_BAR] layer is at the correct position at the start
  * and end of the SF trace
  */
-fun FlickerTestParameter.statusBarLayerRotatesScales() {
-    statusBarLayerPositionStart()
-    statusBarLayerPositionEnd()
+fun FlickerTestParameter.statusBarLayerPositionAtStartAndEnd() {
+    statusBarLayerPositionAtStart()
+    statusBarLayerPositionAtEnd()
 }
 
 /**
- * Asserts that the visibleRegion of the [FlickerComponentName.SNAPSHOT] layer can cover
+ * Asserts that the visibleRegion of the [ComponentMatcher.SNAPSHOT] layer can cover
  * the visibleRegion of the given app component exactly
  */
 fun FlickerTestParameter.snapshotStartingWindowLayerCoversExactlyOnApp(
-    component: FlickerComponentName
+    component: IComponentMatcher
 ) {
     assertLayers {
         invoke("snapshotStartingWindowLayerCoversExactlyOnApp") {
             val snapshotLayers = it.subjects.filter { subject ->
                 subject.name.contains(
-                        FlickerComponentName.SNAPSHOT.toLayerName()) && subject.isVisible
+                    ComponentMatcher.SNAPSHOT.toLayerName()) && subject.isVisible
             }
             // Verify the size of snapshotRegion covers appVisibleRegion exactly in animation.
             if (snapshotLayers.isNotEmpty()) {
@@ -223,8 +242,8 @@
  *      otherwise we won't and the layer must appear immediately.
  */
 fun FlickerTestParameter.replacesLayer(
-    originalLayer: FlickerComponentName,
-    newLayer: FlickerComponentName,
+    originalLayer: IComponentMatcher,
+    newLayer: IComponentMatcher,
     ignoreEntriesWithRotationLayer: Boolean = false,
     ignoreSnapshot: Boolean = false,
     ignoreSplashscreen: Boolean = true
@@ -233,10 +252,10 @@
         val assertion = this.isVisible(originalLayer)
 
         if (ignoreEntriesWithRotationLayer) {
-            assertion.then().isVisible(FlickerComponentName.ROTATION, isOptional = true)
+            assertion.then().isVisible(ComponentMatcher.ROTATION, isOptional = true)
         }
         if (ignoreSnapshot) {
-            assertion.then().isVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
+            assertion.then().isVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
         }
         if (ignoreSplashscreen) {
             assertion.then().isSplashScreenVisibleFor(newLayer, isOptional = true)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/ActivityEmbeddingTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/ActivityEmbeddingTestBase.kt
new file mode 100644
index 0000000..4cf6691
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/ActivityEmbeddingTestBase.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.activityembedding
+
+import com.android.server.wm.flicker.BaseTest
+import com.android.server.wm.flicker.FlickerTestParameter
+import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper
+import org.junit.Before
+
+abstract class ActivityEmbeddingTestBase(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
+    val testApp = ActivityEmbeddingAppHelper(instrumentation)
+
+    @Before
+    fun assumeActivityEmbeddingSupported() {
+        // The test should only be run on devices that support ActivityEmbedding.
+        ActivityEmbeddingAppHelper.assumeActivityEmbeddingSupportedDevice()
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt
new file mode 100644
index 0000000..4e91ce1
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.activityembedding
+
+import android.platform.test.annotations.Postsubmit
+import android.platform.test.annotations.Presubmit
+import android.view.Surface
+import android.view.WindowManagerPolicyConstants
+import androidx.test.filters.RequiresDevice
+import com.android.server.wm.flicker.FlickerParametersRunnerFactory
+import com.android.server.wm.flicker.FlickerTestParameter
+import com.android.server.wm.flicker.FlickerTestParameterFactory
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test opening an activity that will launch another activity as ActivityEmbedding placeholder in
+ * split.
+ *
+ * To run this test: `atest FlickerTests:OpenActivityEmbeddingPlaceholderSplit`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class OpenActivityEmbeddingPlaceholderSplit(
+    testSpec: FlickerTestParameter
+) : ActivityEmbeddingTestBase(testSpec) {
+
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            eachRun {
+                testApp.launchViaIntent(wmHelper)
+            }
+        }
+        transitions {
+            testApp.launchPlaceholderSplit(wmHelper)
+        }
+        teardown {
+            test {
+                device.pressHome()
+                testApp.exit(wmHelper)
+            }
+        }
+    }
+
+    @Presubmit
+    @Test
+    fun mainActivityBecomesInvisible() {
+        testSpec.assertLayers {
+            isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+                    .then()
+                    .isInvisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+        }
+    }
+
+    @Presubmit
+    @Test
+    fun placeholderSplitBecomesVisible() {
+        testSpec.assertLayers {
+            isInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
+                    .then()
+                    .isVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
+        }
+        testSpec.assertLayers {
+            isInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
+                    .then()
+                    .isVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun entireScreenCovered() = super.entireScreenCovered()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerIsVisibleAtStartAndEnd() =
+        super.statusBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarWindowIsAlwaysVisible() =
+        super.statusBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+    companion object {
+        /**
+         * Creates the test configurations.
+         *
+         * See [FlickerTestParameterFactory.getConfigNonRotationTests] for configuring
+         * repetitions, screen orientation and navigation modes.
+         */
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): Collection<FlickerTestParameter> {
+            return FlickerTestParameterFactory.getInstance()
+                    .getConfigNonRotationTests(
+                            repetitions = 1,
+                            supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90),
+                            supportedNavigationModes = listOf(
+                                    WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
+                                    WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+                            )
+                    )
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
index d0f1dfdd..d53d96b 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
@@ -24,9 +24,6 @@
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group4
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
-import org.junit.Assume.assumeFalse
-import org.junit.Assume.assumeTrue
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -68,6 +65,7 @@
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group4
 class CloseAppBackButtonTest(testSpec: FlickerTestParameter) : CloseAppTransition(testSpec) {
+    /** {@inheritDoc} */
     override val transition: FlickerBuilder.() -> Unit
         get() = {
             super.transition(this)
@@ -82,29 +80,7 @@
     /** {@inheritDoc} */
     @FlakyTest(bugId = 206753786)
     @Test
-    override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
-
-    /** {@inheritDoc} */
-    @FlakyTest(bugId = 206753786)
-    @Test
-    override fun statusBarLayerRotatesScales() {
-        // This test doesn't work in shell transitions because of b/206753786
-        assumeFalse(isShellTransitionsEnabled)
-        super.statusBarLayerRotatesScales()
-    }
-
-    @FlakyTest(bugId = 214452854)
-    @Test
-    fun statusBarLayerRotatesScales_shellTransit() {
-        assumeTrue(isShellTransitionsEnabled)
-        super.statusBarLayerRotatesScales()
-    }
-
-    /** {@inheritDoc} */
-    @FlakyTest(bugId = 229762973)
-    @Test
-    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
-        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
 
     companion object {
         /**
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
index b178e8c..1348d7a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
@@ -64,6 +64,7 @@
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group4
 class CloseAppHomeButtonTest(testSpec: FlickerTestParameter) : CloseAppTransition(testSpec) {
+    /** {@inheritDoc} */
     override val transition: FlickerBuilder.() -> Unit
         get() = {
             super.transition(this)
@@ -82,20 +83,7 @@
     /** {@inheritDoc} */
     @FlakyTest(bugId = 206753786)
     @Test
-    override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
-
-    /** {@inheritDoc} */
-    @FlakyTest(bugId = 206753786)
-    @Test
-    override fun statusBarLayerRotatesScales() {
-        super.statusBarLayerRotatesScales()
-    }
-
-    /** {@inheritDoc} */
-    @FlakyTest(bugId = 229762973)
-    @Test
-    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
-        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
 
     companion object {
         /**
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
index ae002c9..7ff0934 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
@@ -16,39 +16,25 @@
 
 package com.android.server.wm.flicker.close
 
-import android.app.Instrumentation
 import android.platform.test.annotations.Presubmit
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
 import com.android.server.wm.flicker.helpers.StandardAppHelper
 import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
 import com.android.server.wm.flicker.replacesLayer
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName.Companion.LAUNCHER
+import com.android.server.wm.traces.common.ComponentMatcher.Companion.LAUNCHER
 import org.junit.Test
 
 /**
  * Base test class for transitions that close an app back to the launcher screen
  */
-abstract class CloseAppTransition(protected val testSpec: FlickerTestParameter) {
-    protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+abstract class CloseAppTransition(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
     protected open val testApp: StandardAppHelper = SimpleAppHelper(instrumentation)
-    protected val tapl = LauncherInstrumentation()
 
-    /**
-     * Specification of the test transition to execute
-     */
-    protected open val transition: FlickerBuilder.() -> Unit = {
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
         setup {
             test {
                 tapl.setExpectedRotation(testSpec.startRotation)
@@ -66,98 +52,6 @@
     }
 
     /**
-     * Entry point for the test runner. It will use this method to initialize and cache
-     * flicker executions
-     */
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            transition()
-        }
-    }
-
-    /**
-     * Checks that the navigation bar window is visible during the whole transition
-     */
-    @Presubmit
-    @Test
-    open fun navBarWindowIsVisible() {
-        testSpec.navBarWindowIsVisible()
-    }
-
-    /**
-     * Checks that the status bar window is visible during the whole transition
-     */
-    @Presubmit
-    @Test
-    open fun statusBarWindowIsVisible() {
-        testSpec.statusBarWindowIsVisible()
-    }
-
-    /**
-     * Checks that the navigation bar layer is visible during the whole transition
-     */
-    @Presubmit
-    @Test
-    open fun navBarLayerIsVisible() {
-        testSpec.navBarLayerIsVisible()
-    }
-
-    /**
-     * Checks that the status bar layer is visible during the whole transition
-     */
-    @Presubmit
-    @Test
-    open fun statusBarLayerIsVisible() {
-        testSpec.statusBarLayerIsVisible()
-    }
-
-    /**
-     * Checks the position of the navigation bar at the start and end of the transition
-     */
-    @Presubmit
-    @Test
-    open fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
-    /**
-     * Checks the position of the status bar at the start and end of the transition
-     */
-    @Presubmit
-    @Test
-    open fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
-    /**
-     * Checks that all windows that are visible on the trace, are visible for at least 2
-     * consecutive entries.
-     */
-    @Presubmit
-    @Test
-    open fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
-        testSpec.assertWm {
-            this.visibleWindowsShownMoreThanOneConsecutiveEntry()
-        }
-    }
-
-    /**
-     * Checks that all layers that are visible on the trace, are visible for at least 2
-     * consecutive entries.
-     */
-    @Presubmit
-    @Test
-    open fun visibleLayersShownMoreThanOneConsecutiveEntry() {
-        testSpec.assertLayers {
-            this.visibleLayersShownMoreThanOneConsecutiveEntry()
-        }
-    }
-
-    /**
-     * Checks that all parts of the screen are covered during the transition
-     */
-    @Presubmit
-    @Test
-    open fun entireScreenCovered() = testSpec.entireScreenCovered()
-
-    /**
      * Checks that [testApp] is the top visible app window at the start of the transition and
      * that it is replaced by [LAUNCHER] during the transition
      */
@@ -165,9 +59,9 @@
     @Test
     open fun launcherReplacesAppWindowAsTopWindow() {
         testSpec.assertWm {
-            this.isAppWindowOnTop(testApp.component)
-                    .then()
-                    .isAppWindowOnTop(LAUNCHER)
+            this.isAppWindowOnTop(testApp)
+                .then()
+                .isAppWindowOnTop(LAUNCHER)
         }
     }
 
@@ -180,8 +74,8 @@
     open fun launcherWindowBecomesVisible() {
         testSpec.assertWm {
             this.isAppWindowNotOnTop(LAUNCHER)
-                    .then()
-                    .isAppWindowOnTop(LAUNCHER)
+                .then()
+                .isAppWindowOnTop(LAUNCHER)
         }
     }
 
@@ -191,6 +85,10 @@
     @Presubmit
     @Test
     open fun launcherLayerReplacesApp() {
-        testSpec.replacesLayer(testApp.component, LAUNCHER)
+        testSpec.replacesLayer(
+            testApp,
+            LAUNCHER,
+            ignoreEntriesWithRotationLayer = testSpec.isLandscapeOrSeascapeAtStart
+        )
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt
new file mode 100644
index 0000000..af3a8c5
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.helpers
+
+import android.app.Instrumentation
+import android.support.test.launcherhelper.ILauncherStrategy
+import android.support.test.launcherhelper.LauncherStrategyFactory
+import android.util.Log
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.Until
+import androidx.window.extensions.WindowExtensions
+import androidx.window.extensions.WindowExtensionsProvider
+import androidx.window.extensions.embedding.ActivityEmbeddingComponent
+import com.android.server.wm.flicker.testapp.ActivityOptions
+import com.android.server.wm.traces.common.IComponentMatcher
+import com.android.server.wm.traces.common.windowmanager.WindowManagerState.Companion.STATE_RESUMED
+import com.android.server.wm.traces.parser.toFlickerComponent
+import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
+import org.junit.Assume.assumeNotNull
+
+class ActivityEmbeddingAppHelper @JvmOverloads constructor(
+        instr: Instrumentation,
+        launcherName: String = ActivityOptions.ACTIVITY_EMBEDDING_LAUNCHER_NAME,
+        component: IComponentMatcher = MAIN_ACTIVITY_COMPONENT,
+        launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
+                .getInstance(instr)
+                .launcherStrategy
+) : StandardAppHelper(instr, launcherName, component, launcherStrategy) {
+
+    /**
+     * Clicks the button to launch the placeholder primary activity, which should launch the
+     * placeholder secondary activity based on the placeholder rule.
+     */
+    fun launchPlaceholderSplit(wmHelper: WindowManagerStateHelper) {
+        val launchButton = uiDevice.wait(
+                Until.findObject(By.res(getPackage(), "launch_placeholder_split_button")),
+                FIND_TIMEOUT)
+        require(launchButton != null) {
+            "Can't find launch placeholder split button on screen."
+        }
+        launchButton.click()
+        wmHelper.StateSyncBuilder()
+            .withActivityState(PLACEHOLDER_PRIMARY_COMPONENT, STATE_RESUMED)
+            .withActivityState(PLACEHOLDER_SECONDARY_COMPONENT, STATE_RESUMED)
+            .waitForAndVerify()
+    }
+
+    companion object {
+        private const val TAG = "ActivityEmbeddingAppHelper"
+
+        val MAIN_ACTIVITY_COMPONENT = ActivityOptions
+                .ACTIVITY_EMBEDDING_MAIN_ACTIVITY_COMPONENT_NAME.toFlickerComponent()
+
+        val PLACEHOLDER_PRIMARY_COMPONENT = ActivityOptions
+                .ACTIVITY_EMBEDDING_PLACEHOLDER_PRIMARY_ACTIVITY_COMPONENT_NAME.toFlickerComponent()
+
+        val PLACEHOLDER_SECONDARY_COMPONENT = ActivityOptions
+                .ACTIVITY_EMBEDDING_PLACEHOLDER_SECONDARY_ACTIVITY_COMPONENT_NAME
+                .toFlickerComponent()
+
+        @JvmStatic
+        fun getWindowExtensions(): WindowExtensions? {
+            try {
+                return WindowExtensionsProvider.getWindowExtensions()
+            } catch (e: NoClassDefFoundError) {
+                Log.d(TAG, "Extension implementation not found")
+            } catch (e: UnsupportedOperationException) {
+                Log.d(TAG, "Stub Extension")
+            }
+            return null
+        }
+
+        @JvmStatic
+        fun getActivityEmbeddingComponent(): ActivityEmbeddingComponent? {
+            return getWindowExtensions()?.activityEmbeddingComponent
+        }
+
+        @JvmStatic
+        fun assumeActivityEmbeddingSupportedDevice() {
+            assumeNotNull(getActivityEmbeddingComponent())
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FixedOrientationAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FixedOrientationAppHelper.kt
index 2dbf304..28858d4 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FixedOrientationAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FixedOrientationAppHelper.kt
@@ -20,15 +20,15 @@
 import android.support.test.launcherhelper.ILauncherStrategy
 import android.support.test.launcherhelper.LauncherStrategyFactory
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 
- class FixedOrientationAppHelper @JvmOverloads constructor(
+class FixedOrientationAppHelper @JvmOverloads constructor(
      instr: Instrumentation,
      launcherName: String = ActivityOptions.PORTRAIT_ONLY_ACTIVITY_LAUNCHER_NAME,
-     component: FlickerComponentName =
+     component: IComponentMatcher =
              ActivityOptions.PORTRAIT_ONLY_ACTIVITY_COMPONENT_NAME.toFlickerComponent(),
      launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
              .getInstance(instr)
              .launcherStrategy
- ) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
\ No newline at end of file
+ ) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt
index cd184ac..f536a15 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt
@@ -23,7 +23,7 @@
 import androidx.test.uiautomator.By
 import androidx.test.uiautomator.Until
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
 import java.util.regex.Pattern
@@ -33,7 +33,7 @@
     private val rotation: Int,
     private val imePackageName: String = IME_PACKAGE,
     launcherName: String = ActivityOptions.IME_ACTIVITY_AUTO_FOCUS_LAUNCHER_NAME,
-    component: FlickerComponentName =
+    component: IComponentMatcher =
         ActivityOptions.IME_ACTIVITY_AUTO_FOCUS_COMPONENT_NAME.toFlickerComponent()
 ) : ImeAppHelper(instr, launcherName, component) {
     override fun openIME(wmHelper: WindowManagerStateHelper) {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
index 8ac9a75..db64c47 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
@@ -22,14 +22,14 @@
 import androidx.test.uiautomator.By
 import androidx.test.uiautomator.Until
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
 
 open class ImeAppHelper @JvmOverloads constructor(
     instr: Instrumentation,
     launcherName: String = ActivityOptions.IME_ACTIVITY_LAUNCHER_NAME,
-    component: FlickerComponentName =
+    component: IComponentMatcher =
         ActivityOptions.IME_ACTIVITY_COMPONENT_NAME.toFlickerComponent(),
     launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
             .getInstance(instr)
@@ -80,7 +80,7 @@
         }
         finishButton.click()
         wmHelper.StateSyncBuilder()
-            .withActivityRemoved(component)
+            .withActivityRemoved(this)
             .waitForAndVerify()
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt
index 438aeeb..f74054e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt
@@ -20,7 +20,7 @@
 import androidx.test.uiautomator.By
 import androidx.test.uiautomator.Until
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
 
@@ -29,7 +29,7 @@
     private val rotation: Int,
     private val imePackageName: String = IME_PACKAGE,
     launcherName: String = ActivityOptions.EDITOR_POPUP_DIALOG_ACTIVITY_LAUNCHER_NAME,
-    component: FlickerComponentName =
+    component: IComponentMatcher =
             ActivityOptions.EDITOR_POPUP_DIALOG_ACTIVITY_COMPONENT_NAME.toFlickerComponent()
 ) : ImeAppHelper(instr, launcherName, component) {
     override fun openIME(wmHelper: WindowManagerStateHelper) {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt
index 16c4c25..7f8b563 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt
@@ -20,15 +20,15 @@
 import android.support.test.launcherhelper.ILauncherStrategy
 import android.support.test.launcherhelper.LauncherStrategyFactory
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 
 class ImeStateInitializeHelper @JvmOverloads constructor(
     instr: Instrumentation,
     launcherName: String = ActivityOptions.IME_ACTIVITY_INITIALIZE_LAUNCHER_NAME,
-    component: FlickerComponentName =
+    component: IComponentMatcher =
         ActivityOptions.IME_ACTIVITY_INITIALIZE_COMPONENT_NAME.toFlickerComponent(),
     launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
             .getInstance(instr)
             .launcherStrategy
-) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
\ No newline at end of file
+) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt
index 1a2543c..79656a0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt
@@ -23,14 +23,14 @@
 import androidx.test.uiautomator.UiDevice
 import androidx.test.uiautomator.Until
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
 
 class NewTasksAppHelper @JvmOverloads constructor(
     instr: Instrumentation,
     launcherName: String = ActivityOptions.LAUNCH_NEW_TASK_ACTIVITY_LAUNCHER_NAME,
-    component: FlickerComponentName =
+    component: IComponentMatcher =
         ActivityOptions.LAUNCH_NEW_TASK_ACTIVITY_COMPONENT_NAME.toFlickerComponent(),
     launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
         .getInstance(instr)
@@ -47,7 +47,7 @@
         }
         button.click()
         wmHelper.StateSyncBuilder()
-            .withFullScreenApp(component)
+            .withFullScreenApp(this)
             .waitForAndVerify()
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt
index f7ca5ce..a9769d0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt
@@ -20,15 +20,15 @@
 import android.support.test.launcherhelper.ILauncherStrategy
 import android.support.test.launcherhelper.LauncherStrategyFactory
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 
 class NonResizeableAppHelper @JvmOverloads constructor(
     instr: Instrumentation,
     launcherName: String = ActivityOptions.NON_RESIZEABLE_ACTIVITY_LAUNCHER_NAME,
-    component: FlickerComponentName =
+    component: IComponentMatcher =
         ActivityOptions.NON_RESIZEABLE_ACTIVITY_COMPONENT_NAME.toFlickerComponent(),
     launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
         .getInstance(instr)
         .launcherStrategy
-) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
\ No newline at end of file
+) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NotificationAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NotificationAppHelper.kt
index 00b208b..50d036c 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NotificationAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NotificationAppHelper.kt
@@ -22,14 +22,14 @@
 import androidx.test.uiautomator.By
 import androidx.test.uiautomator.Until
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
 
 class NotificationAppHelper @JvmOverloads constructor(
     instr: Instrumentation,
     launcherName: String = ActivityOptions.NOTIFICATION_ACTIVITY_LAUNCHER_NAME,
-    component: FlickerComponentName =
+    component: IComponentMatcher =
             ActivityOptions.NOTIFICATION_ACTIVITY_COMPONENT_NAME.toFlickerComponent(),
     launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
             .getInstance(instr)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SeamlessRotationAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SeamlessRotationAppHelper.kt
index 7bab981..459ca5b 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SeamlessRotationAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SeamlessRotationAppHelper.kt
@@ -20,15 +20,15 @@
 import android.support.test.launcherhelper.ILauncherStrategy
 import android.support.test.launcherhelper.LauncherStrategyFactory
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 
 class SeamlessRotationAppHelper @JvmOverloads constructor(
     instr: Instrumentation,
     launcherName: String = ActivityOptions.SEAMLESS_ACTIVITY_LAUNCHER_NAME,
-    component: FlickerComponentName =
+    component: IComponentMatcher =
         ActivityOptions.SEAMLESS_ACTIVITY_COMPONENT_NAME.toFlickerComponent(),
     launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
         .getInstance(instr)
         .launcherStrategy
-) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
\ No newline at end of file
+) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ShowWhenLockedAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ShowWhenLockedAppHelper.kt
index bd2e575..4952dba 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ShowWhenLockedAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ShowWhenLockedAppHelper.kt
@@ -20,15 +20,15 @@
 import android.support.test.launcherhelper.ILauncherStrategy
 import android.support.test.launcherhelper.LauncherStrategyFactory
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 
 class ShowWhenLockedAppHelper @JvmOverloads constructor(
     instr: Instrumentation,
     launcherName: String = ActivityOptions.SHOW_WHEN_LOCKED_ACTIVITY_LAUNCHER_NAME,
-    component: FlickerComponentName =
+    component: IComponentMatcher =
             ActivityOptions.SHOW_WHEN_LOCKED_ACTIVITY_COMPONENT_NAME.toFlickerComponent(),
     launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
             .getInstance(instr)
             .launcherStrategy
-) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
\ No newline at end of file
+) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SimpleAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SimpleAppHelper.kt
index f6a8817..6bddcac 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SimpleAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SimpleAppHelper.kt
@@ -20,15 +20,15 @@
 import android.support.test.launcherhelper.ILauncherStrategy
 import android.support.test.launcherhelper.LauncherStrategyFactory
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 
 class SimpleAppHelper @JvmOverloads constructor(
     instr: Instrumentation,
     launcherName: String = ActivityOptions.SIMPLE_ACTIVITY_LAUNCHER_NAME,
-    component: FlickerComponentName =
+    component: IComponentMatcher =
         ActivityOptions.SIMPLE_ACTIVITY_AUTO_FOCUS_COMPONENT_NAME.toFlickerComponent(),
     launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
         .getInstance(instr)
         .launcherStrategy
-) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
\ No newline at end of file
+) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt
index 8519da1..a17344f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt
@@ -23,14 +23,14 @@
 import androidx.test.uiautomator.UiDevice
 import androidx.test.uiautomator.Until
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
 
 class TwoActivitiesAppHelper @JvmOverloads constructor(
     instr: Instrumentation,
     launcherName: String = ActivityOptions.BUTTON_ACTIVITY_LAUNCHER_NAME,
-    component: FlickerComponentName =
+    component: IComponentMatcher =
         ActivityOptions.BUTTON_ACTIVITY_COMPONENT_NAME.toFlickerComponent(),
     launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
         .getInstance(instr)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
index 67d2067..6b8fde2 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
@@ -16,28 +16,18 @@
 
 package com.android.server.wm.flicker.ime
 
-import android.app.Instrumentation
-import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.Presubmit
 import android.view.Surface
 import android.view.WindowManagerPolicyConstants
 import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group2
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
 import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -61,42 +51,23 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group2
-class CloseImeAutoOpenWindowToAppTest(private val testSpec: FlickerTestParameter) {
-    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class CloseImeAutoOpenWindowToAppTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
     private val testApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
 
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            setup {
-                eachRun {
-                    testApp.launchViaIntent(wmHelper)
-                }
-            }
-            teardown {
-                eachRun {
-                    testApp.exit(wmHelper)
-                }
-            }
-            transitions {
-                testApp.closeIME(wmHelper)
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            eachRun {
+                testApp.launchViaIntent(wmHelper)
             }
         }
-    }
-
-    @Presubmit
-    @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
-        testSpec.assertWm {
-            this.visibleWindowsShownMoreThanOneConsecutiveEntry()
+        teardown {
+            eachRun {
+                testApp.exit(wmHelper)
+            }
+        }
+        transitions {
+            testApp.closeIME(wmHelper)
         }
     }
 
@@ -104,27 +75,15 @@
     @Test
     fun imeAppWindowIsAlwaysVisible() {
         testSpec.assertWm {
-            this.isAppWindowOnTop(testApp.component)
+            this.isAppWindowOnTop(testApp)
         }
     }
 
     @Presubmit
     @Test
-    fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible()
-
-    @Presubmit
-    @Test
-    fun entireScreenCovered() = testSpec.entireScreenCovered()
-
-    @Presubmit
-    @Test
     fun imeLayerVisibleStart() {
         testSpec.assertLayersStart {
-            this.isVisible(FlickerComponentName.IME)
+            this.isVisible(ComponentMatcher.IME)
         }
     }
 
@@ -132,7 +91,7 @@
     @Test
     fun imeLayerInvisibleEnd() {
         testSpec.assertLayersEnd {
-            this.isInvisible(FlickerComponentName.IME)
+            this.isInvisible(ComponentMatcher.IME)
         }
     }
 
@@ -144,23 +103,7 @@
     @Test
     fun imeAppLayerIsAlwaysVisible() {
         testSpec.assertLayers {
-            this.isVisible(testApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
-    @FlakyTest(bugId = 206753786)
-    @Test
-    fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
-    @Presubmit
-    @Test
-    fun visibleLayersShownMoreThanOneConsecutiveEntry() {
-        testSpec.assertLayers {
-            this.visibleLayersShownMoreThanOneConsecutiveEntry()
+            this.isVisible(testApp)
         }
     }
 
@@ -169,12 +112,14 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                .getConfigNonRotationTests(repetitions = 3,
+                .getConfigNonRotationTests(
+                    repetitions = 3,
                     // b/190352379 (IME doesn't show on app launch in 90 degrees)
                     supportedRotations = listOf(Surface.ROTATION_0),
                     supportedNavigationModes = listOf(
                         WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
-                        WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)
+                        WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+                    )
                 )
         }
     }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
index dcb5dad..99c3ac6 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
@@ -16,28 +16,18 @@
 
 package com.android.server.wm.flicker.ime
 
-import android.app.Instrumentation
-import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.Presubmit
 import android.view.Surface
 import android.view.WindowManagerPolicyConstants
 import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group2
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
 import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -61,46 +51,27 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group2
-class CloseImeAutoOpenWindowToHomeTest(private val testSpec: FlickerTestParameter) {
-    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class CloseImeAutoOpenWindowToHomeTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
     private val testApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
 
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            setup {
-                eachRun {
-                    testApp.launchViaIntent(wmHelper)
-                }
-            }
-            teardown {
-                eachRun {
-                    testApp.exit(wmHelper)
-                }
-            }
-            transitions {
-                device.pressHome()
-                wmHelper.StateSyncBuilder()
-                    .withHomeActivityVisible()
-                    .withImeGone()
-                    .waitForAndVerify()
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            eachRun {
+                testApp.launchViaIntent(wmHelper)
             }
         }
-    }
-
-    @Presubmit
-    @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
-        testSpec.assertWm {
-            this.visibleWindowsShownMoreThanOneConsecutiveEntry()
+        teardown {
+            eachRun {
+                testApp.exit(wmHelper)
+            }
+        }
+        transitions {
+            device.pressHome()
+            wmHelper.StateSyncBuilder()
+                .withHomeActivityVisible()
+                .withImeGone()
+                .waitForAndVerify()
         }
     }
 
@@ -108,21 +79,17 @@
     @Test
     fun imeAppWindowBecomesInvisible() {
         testSpec.assertWm {
-            this.isAppWindowOnTop(testApp.component)
+            this.isAppWindowOnTop(testApp)
                 .then()
-                .isAppWindowNotOnTop(testApp.component)
+                .isAppWindowNotOnTop(testApp)
         }
     }
 
     @Presubmit
     @Test
-    fun entireScreenCovered() = testSpec.entireScreenCovered()
-
-    @Presubmit
-    @Test
     fun imeLayerVisibleStart() {
         testSpec.assertLayersStart {
-            this.isVisible(FlickerComponentName.IME)
+            this.isVisible(ComponentMatcher.IME)
         }
     }
 
@@ -130,7 +97,7 @@
     @Test
     fun imeLayerInvisibleEnd() {
         testSpec.assertLayersEnd {
-            this.isInvisible(FlickerComponentName.IME)
+            this.isInvisible(ComponentMatcher.IME)
         }
     }
 
@@ -142,35 +109,9 @@
     @Test
     fun imeAppLayerBecomesInvisible() {
         testSpec.assertLayers {
-            this.isVisible(testApp.component)
+            this.isVisible(testApp)
                     .then()
-                    .isInvisible(testApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
-    @FlakyTest(bugId = 206753786)
-    @Test
-    fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
-    @Presubmit
-    @Test
-    fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible()
-
-    @Presubmit
-    @Test
-    fun visibleLayersShownMoreThanOneConsecutiveEntry() {
-        testSpec.assertLayers {
-            this.visibleLayersShownMoreThanOneConsecutiveEntry(listOf(
-                FlickerComponentName.IME,
-                FlickerComponentName.SPLASH_SCREEN))
+                    .isInvisible(testApp)
         }
     }
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt
index b979f3e..53f4318 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt
@@ -16,23 +16,19 @@
 
 package com.android.server.wm.flicker.ime
 
-import android.app.Instrumentation
 import android.platform.test.annotations.Postsubmit
 import android.view.Surface
 import android.view.WindowManagerPolicyConstants
 import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group4
 import com.android.server.wm.flicker.dsl.FlickerBuilder
 import com.android.server.wm.flicker.helpers.ImeEditorPopupDialogAppHelper
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarWindowIsVisible
 import com.android.server.wm.flicker.traces.region.RegionSubject
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -44,44 +40,94 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group4
-class CloseImeEditorPopupDialogTest(private val testSpec: FlickerTestParameter) {
-    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class CloseImeEditorPopupDialogTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
     private val imeTestApp = ImeEditorPopupDialogAppHelper(instrumentation, testSpec.startRotation)
 
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            setup {
-                eachRun {
-                    imeTestApp.launchViaIntent(wmHelper)
-                    imeTestApp.openIME(wmHelper)
-                }
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            eachRun {
+                imeTestApp.launchViaIntent(wmHelper)
+                imeTestApp.openIME(wmHelper)
             }
-            transitions {
-                imeTestApp.dismissDialog(wmHelper)
+        }
+        transitions {
+            imeTestApp.dismissDialog(wmHelper)
+            wmHelper.StateSyncBuilder()
+                .withImeGone()
+                .waitForAndVerify()
+        }
+        teardown {
+            eachRun {
+                device.pressHome()
                 wmHelper.StateSyncBuilder()
-                    .withImeGone()
+                    .withHomeActivityVisible()
                     .waitForAndVerify()
-            }
-            teardown {
-                eachRun {
-                    device.pressHome()
-                    wmHelper.StateSyncBuilder()
-                        .withHomeActivityVisible()
-                        .waitForAndVerify()
-                    imeTestApp.exit(wmHelper)
-                }
+                imeTestApp.exit(wmHelper)
             }
         }
     }
 
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
+    override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
 
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
+    override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun entireScreenCovered() =
+        super.entireScreenCovered()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerIsVisibleAtStartAndEnd() =
+        super.statusBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarLayerIsVisibleAtStartAndEnd() =
+        super.taskBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
 
     @Postsubmit
     @Test
@@ -91,12 +137,12 @@
     @Test
     fun imeLayerAndImeSnapshotVisibleOnScreen() {
         testSpec.assertLayers {
-            this.isVisible(FlickerComponentName.IME)
-                    .then()
-                    .isVisible(FlickerComponentName.IME_SNAPSHOT)
-                    .then()
-                    .isInvisible(FlickerComponentName.IME_SNAPSHOT, isOptional = true)
-                    .isInvisible(FlickerComponentName.IME)
+            this.isVisible(ComponentMatcher.IME)
+                .then()
+                .isVisible(ComponentMatcher.IME_SNAPSHOT)
+                .then()
+                .isInvisible(ComponentMatcher.IME_SNAPSHOT, isOptional = true)
+                .isInvisible(ComponentMatcher.IME)
         }
     }
 
@@ -105,15 +151,17 @@
     fun imeSnapshotAssociatedOnAppVisibleRegion() {
         testSpec.assertLayers {
             this.invoke("imeSnapshotAssociatedOnAppVisibleRegion") {
-                val imeSnapshotLayers = it.subjects.filter {
-                    subject -> subject.name.contains(
-                        FlickerComponentName.IME_SNAPSHOT.toLayerName()) && subject.isVisible
+                val imeSnapshotLayers = it.subjects.filter { subject ->
+                    subject.name.contains(
+                        ComponentMatcher.IME_SNAPSHOT.toLayerName()
+                    ) && subject.isVisible
                 }
                 if (imeSnapshotLayers.isNotEmpty()) {
                     val visibleAreas = imeSnapshotLayers.mapNotNull { imeSnapshotLayer ->
-                        imeSnapshotLayer.layer?.visibleRegion }.toTypedArray()
+                        imeSnapshotLayer.layer?.visibleRegion
+                    }.toTypedArray()
                     val imeVisibleRegion = RegionSubject.assertThat(visibleAreas, this, timestamp)
-                    val appVisibleRegion = it.visibleRegion(imeTestApp.component)
+                    val appVisibleRegion = it.visibleRegion(imeTestApp)
                     if (imeVisibleRegion.region.isNotEmpty) {
                         imeVisibleRegion.coversAtMost(appVisibleRegion.region)
                     }
@@ -127,14 +175,14 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                    .getConfigNonRotationTests(
-                            repetitions = 2,
-                            supportedNavigationModes = listOf(
-                                    WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
-                                    WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
-                            ),
-                            supportedRotations = listOf(Surface.ROTATION_0)
-                    )
+                .getConfigNonRotationTests(
+                    repetitions = 2,
+                    supportedNavigationModes = listOf(
+                        WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
+                        WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+                    ),
+                    supportedRotations = listOf(Surface.ROTATION_0)
+                )
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
index 928bb53..113fddf 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
@@ -16,27 +16,19 @@
 
 package com.android.server.wm.flicker.ime
 
-import android.app.Instrumentation
 import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.Presubmit
 import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group2
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
 import com.android.server.wm.flicker.helpers.ImeAppHelper
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
-import org.junit.Assume.assumeFalse
-import org.junit.Assume.assumeTrue
+import com.android.server.wm.flicker.navBarLayerPositionAtStartAndEnd
+import com.android.server.wm.traces.common.ComponentMatcher
+import org.junit.Assume
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -52,96 +44,63 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group2
-class CloseImeWindowToAppTest(private val testSpec: FlickerTestParameter) {
-    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class CloseImeWindowToAppTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
     private val testApp = ImeAppHelper(instrumentation)
 
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            setup {
-                test {
-                    testApp.launchViaIntent(wmHelper)
-                }
-                eachRun {
-                    testApp.openIME(wmHelper)
-                }
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            test {
+                testApp.launchViaIntent(wmHelper)
             }
-            teardown {
-                test {
-                    testApp.exit(wmHelper)
-                }
+            eachRun {
+                testApp.openIME(wmHelper)
             }
-            transitions {
-                testApp.closeIME(wmHelper)
+        }
+        teardown {
+            test {
+                testApp.exit(wmHelper)
             }
         }
+        transitions {
+            testApp.closeIME(wmHelper)
+        }
     }
 
+    /** {@inheritDoc} */
     @Presubmit
     @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
         testSpec.assertWm {
             this.visibleWindowsShownMoreThanOneConsecutiveEntry(listOf(
-                FlickerComponentName.IME,
-                FlickerComponentName.SPLASH_SCREEN,
-                FlickerComponentName.SNAPSHOT))
+                ComponentMatcher.IME,
+                ComponentMatcher.SPLASH_SCREEN,
+                ComponentMatcher.SNAPSHOT))
         }
     }
 
+    /** {@inheritDoc} */
     @Presubmit
     @Test
-    fun imeAppWindowIsAlwaysVisible() {
-        testSpec.assertWm {
-            this.isAppWindowOnTop(testApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
-    @Presubmit
-    @Test
-    fun entireScreenCovered() = testSpec.entireScreenCovered()
-
-    @Presubmit
-    @Test
-    fun navBarLayerRotatesAndScales() {
-        assumeFalse(testSpec.isLandscapeOrSeascapeAtStart)
-        testSpec.navBarLayerRotatesAndScales()
+    override fun navBarLayerPositionAtStartAndEnd() {
+        Assume.assumeFalse(testSpec.isTablet)
+        Assume.assumeFalse(testSpec.isLandscapeOrSeascapeAtStart)
+        testSpec.navBarLayerPositionAtStartAndEnd()
     }
 
     @FlakyTest
     @Test
-    fun navBarLayerRotatesAndScales_Flaky() {
-        assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
-        testSpec.navBarLayerRotatesAndScales()
+    fun navBarLayerPositionAtStartAndEndLandscapeOrSeascapeAtStart() {
+        Assume.assumeFalse(testSpec.isTablet)
+        Assume.assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
+        testSpec.navBarLayerPositionAtStartAndEnd()
     }
 
+    /** {@inheritDoc} */
     @FlakyTest(bugId = 206753786)
     @Test
-    fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
-    @Presubmit
-    @Test
-    fun visibleLayersShownMoreThanOneConsecutiveEntry() {
-        testSpec.assertLayers {
-            this.visibleLayersShownMoreThanOneConsecutiveEntry()
-        }
-    }
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
 
     @Presubmit
     @Test
@@ -151,7 +110,15 @@
     @Test
     fun imeAppLayerIsAlwaysVisible() {
         testSpec.assertLayers {
-            this.isVisible(testApp.component)
+            this.isVisible(testApp)
+        }
+    }
+
+    @Presubmit
+    @Test
+    fun imeAppWindowIsAlwaysVisible() {
+        testSpec.assertWm {
+            this.isAppWindowOnTop(testApp)
         }
     }
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
index 3ff809d..f00a7ab 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
@@ -16,27 +16,18 @@
 
 package com.android.server.wm.flicker.ime
 
-import android.app.Instrumentation
-import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.Presubmit
 import android.view.Surface
 import android.view.WindowManagerPolicyConstants
 import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group2
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
 import com.android.server.wm.flicker.helpers.ImeAppHelper
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -52,53 +43,64 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group2
-class CloseImeWindowToHomeTest(private val testSpec: FlickerTestParameter) {
-    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class CloseImeWindowToHomeTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
     private val testApp = ImeAppHelper(instrumentation)
 
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            setup {
-                eachRun {
-                    testApp.launchViaIntent(wmHelper)
-                    testApp.openIME(wmHelper)
-                }
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            eachRun {
+                testApp.launchViaIntent(wmHelper)
+                testApp.openIME(wmHelper)
             }
-            transitions {
-                device.pressHome()
-                wmHelper.StateSyncBuilder()
-                    .withHomeActivityVisible()
-                    .withImeGone()
-                    .waitForAndVerify()
-            }
-            teardown {
-                test {
-                    testApp.exit(wmHelper)
-                }
+        }
+        transitions {
+            device.pressHome()
+            wmHelper.StateSyncBuilder()
+                .withHomeActivityVisible()
+                .withImeGone()
+                .waitForAndVerify()
+        }
+        teardown {
+            test {
+                testApp.exit(wmHelper)
             }
         }
     }
 
+    /** {@inheritDoc} */
     @Presubmit
     @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
         testSpec.assertWm {
-            this.visibleWindowsShownMoreThanOneConsecutiveEntry(listOf(
-                FlickerComponentName.IME,
-                FlickerComponentName.SPLASH_SCREEN,
-                FlickerComponentName.SNAPSHOT))
+            this.visibleWindowsShownMoreThanOneConsecutiveEntry(
+                listOf(
+                    ComponentMatcher.IME,
+                    ComponentMatcher.SPLASH_SCREEN,
+                    ComponentMatcher.SNAPSHOT
+                )
+            )
         }
     }
 
+    /** {@inheritDoc} */
+    @Presubmit
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() {
+        testSpec.assertLayers {
+            this.visibleLayersShownMoreThanOneConsecutiveEntry(
+                listOf(
+                    ComponentMatcher.IME,
+                    ComponentMatcher.SPLASH_SCREEN
+                )
+            )
+        }
+    }
+
+    @Presubmit
+    @Test
+    fun imeLayerBecomesInvisible() = testSpec.imeLayerBecomesInvisible()
+
     @Presubmit
     @Test
     fun imeWindowBecomesInvisible() = testSpec.imeWindowBecomesInvisible()
@@ -107,53 +109,19 @@
     @Test
     fun imeAppWindowBecomesInvisible() {
         testSpec.assertWm {
-            this.isAppWindowVisible(testApp.component)
-                    .then()
-                    .isAppWindowInvisible(testApp.component)
+            this.isAppWindowVisible(testApp)
+                .then()
+                .isAppWindowInvisible(testApp)
         }
     }
 
     @Presubmit
     @Test
-    fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
-    @Presubmit
-    @Test
-    fun entireScreenCovered() = testSpec.entireScreenCovered()
-
-    @Presubmit
-    @Test
-    fun imeLayerBecomesInvisible() = testSpec.imeLayerBecomesInvisible()
-
-    @Presubmit
-    @Test
     fun imeAppLayerBecomesInvisible() {
         testSpec.assertLayers {
-            this.isVisible(testApp.component)
-                    .then()
-                    .isInvisible(testApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
-    @FlakyTest(bugId = 206753786)
-    @Test
-    fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
-    @Presubmit
-    @Test
-    fun visibleLayersShownMoreThanOneConsecutiveEntry() {
-        testSpec.assertLayers {
-            this.visibleLayersShownMoreThanOneConsecutiveEntry(listOf(
-                FlickerComponentName.IME,
-                FlickerComponentName.SPLASH_SCREEN))
+            this.isVisible(testApp)
+                .then()
+                .isInvisible(testApp)
         }
     }
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt
index ba78e25..19cab3c 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt
@@ -18,52 +18,52 @@
 package com.android.server.wm.flicker.ime
 
 import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
 
 fun FlickerTestParameter.imeLayerBecomesVisible() {
     assertLayers {
-        this.isInvisible(FlickerComponentName.IME)
+        this.isInvisible(ComponentMatcher.IME)
             .then()
-            .isVisible(FlickerComponentName.IME)
+            .isVisible(ComponentMatcher.IME)
     }
 }
 
 fun FlickerTestParameter.imeLayerBecomesInvisible() {
     assertLayers {
-        this.isVisible(FlickerComponentName.IME)
+        this.isVisible(ComponentMatcher.IME)
             .then()
-            .isInvisible(FlickerComponentName.IME)
+            .isInvisible(ComponentMatcher.IME)
     }
 }
 
 fun FlickerTestParameter.imeWindowIsAlwaysVisible(rotatesScreen: Boolean = false) {
     if (rotatesScreen) {
         assertWm {
-            this.isNonAppWindowVisible(FlickerComponentName.IME)
+            this.isNonAppWindowVisible(ComponentMatcher.IME)
                 .then()
-                .isNonAppWindowInvisible(FlickerComponentName.IME)
+                .isNonAppWindowInvisible(ComponentMatcher.IME)
                 .then()
-                .isNonAppWindowVisible(FlickerComponentName.IME)
+                .isNonAppWindowVisible(ComponentMatcher.IME)
         }
     } else {
         assertWm {
-            this.isNonAppWindowVisible(FlickerComponentName.IME)
+            this.isNonAppWindowVisible(ComponentMatcher.IME)
         }
     }
 }
 
 fun FlickerTestParameter.imeWindowBecomesVisible() {
     assertWm {
-        this.isNonAppWindowInvisible(FlickerComponentName.IME)
+        this.isNonAppWindowInvisible(ComponentMatcher.IME)
             .then()
-            .isNonAppWindowVisible(FlickerComponentName.IME)
+            .isNonAppWindowVisible(ComponentMatcher.IME)
     }
 }
 
 fun FlickerTestParameter.imeWindowBecomesInvisible() {
     assertWm {
-        this.isNonAppWindowVisible(FlickerComponentName.IME)
+        this.isNonAppWindowVisible(ComponentMatcher.IME)
             .then()
-            .isNonAppWindowInvisible(FlickerComponentName.IME)
+            .isNonAppWindowInvisible(ComponentMatcher.IME)
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
index d1761fc..95c73df 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
@@ -16,8 +16,7 @@
 
 package com.android.server.wm.flicker.ime
 
-import android.app.Instrumentation
-import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.view.Surface
 import android.view.WindowInsets.Type.ime
@@ -25,14 +24,13 @@
 import android.view.WindowInsets.Type.statusBars
 import android.view.WindowManagerPolicyConstants
 import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.dsl.FlickerBuilder
 import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
 import org.junit.FixMethodOrder
@@ -49,63 +47,121 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class LaunchAppShowImeAndDialogThemeAppTest(private val testSpec: FlickerTestParameter) {
-    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class LaunchAppShowImeAndDialogThemeAppTest(
+    testSpec: FlickerTestParameter
+) : BaseTest(testSpec) {
     private val testApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
 
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            setup {
-                eachRun {
-                    testApp.launchViaIntent(wmHelper)
-                    wmHelper.StateSyncBuilder()
-                        .withImeShown()
-                        .waitForAndVerify()
-                    testApp.startDialogThemedActivity(wmHelper)
-                    // Verify IME insets isn't visible on dialog since it's non-IME focusable window
-                    assertFalse(testApp.getInsetsVisibleFromDialog(ime()))
-                    assertTrue(testApp.getInsetsVisibleFromDialog(statusBars()))
-                    assertTrue(testApp.getInsetsVisibleFromDialog(navigationBars()))
-                }
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            eachRun {
+                testApp.launchViaIntent(wmHelper)
+                wmHelper.StateSyncBuilder()
+                    .withImeShown()
+                    .waitForAndVerify()
+                testApp.startDialogThemedActivity(wmHelper)
+                // Verify IME insets isn't visible on dialog since it's non-IME focusable window
+                assertFalse(testApp.getInsetsVisibleFromDialog(ime()))
+                assertTrue(testApp.getInsetsVisibleFromDialog(statusBars()))
+                assertTrue(testApp.getInsetsVisibleFromDialog(navigationBars()))
             }
-            teardown {
-                eachRun {
-                    testApp.exit(wmHelper)
-                }
+        }
+        teardown {
+            eachRun {
+                testApp.exit(wmHelper)
             }
-            transitions {
-                testApp.dismissDialog(wmHelper)
-            }
+        }
+        transitions {
+            testApp.dismissDialog(wmHelper)
         }
     }
 
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerIsVisibleAtStartAndEnd() =
+        super.statusBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun entireScreenCovered() = super.entireScreenCovered()
+
     /**
-     * Checks that [FlickerComponentName.IME] layer becomes visible during the transition
+     * Checks that [ComponentMatcher.IME] layer becomes visible during the transition
      */
-    @FlakyTest(bugId = 215884488)
+    @Presubmit
     @Test
     fun imeWindowIsAlwaysVisible() = testSpec.imeWindowIsAlwaysVisible()
 
     /**
-     * Checks that [FlickerComponentName.IME] layer is visible at the end of the transition
+     * Checks that [ComponentMatcher.IME] layer is visible at the end of the transition
      */
-    @FlakyTest(bugId = 227142436)
+    @Presubmit
     @Test
     fun imeLayerExistsEnd() {
         testSpec.assertLayersEnd {
-            this.isVisible(FlickerComponentName.IME)
+            this.isVisible(ComponentMatcher.IME)
         }
     }
 
     /**
-     * Checks that [FlickerComponentName.IME_SNAPSHOT] layer is invisible always.
+     * Checks that [ComponentMatcher.IME_SNAPSHOT] layer is invisible always.
      */
     @Presubmit
     @Test
     fun imeSnapshotNotVisible() {
         testSpec.assertLayers {
-            this.isInvisible(FlickerComponentName.IME_SNAPSHOT)
+            this.isInvisible(ComponentMatcher.IME_SNAPSHOT)
         }
     }
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt
index d393ace..442ff1a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt
@@ -16,13 +16,12 @@
 
 package com.android.server.wm.flicker.ime
 
-import android.app.Instrumentation
+import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.view.Surface
 import android.view.WindowManagerPolicyConstants
 import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
@@ -30,7 +29,7 @@
 import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
 import com.android.server.wm.flicker.helpers.ImeStateInitializeHelper
 import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -69,68 +68,124 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class LaunchAppShowImeOnStartTest(private val testSpec: FlickerTestParameter) {
-    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class LaunchAppShowImeOnStartTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
     private val testApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
     private val initializeApp = ImeStateInitializeHelper(instrumentation)
 
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            setup {
-                eachRun {
-                    initializeApp.launchViaIntent(wmHelper)
-                    this.setRotation(testSpec.startRotation)
-                }
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            eachRun {
+                initializeApp.launchViaIntent(wmHelper)
+                this.setRotation(testSpec.startRotation)
             }
-            teardown {
-                eachRun {
-                    initializeApp.exit(wmHelper)
-                    testApp.exit(wmHelper)
-                }
+        }
+        teardown {
+            eachRun {
+                initializeApp.exit(wmHelper)
+                testApp.exit(wmHelper)
             }
-            transitions {
-                testApp.launchViaIntent(wmHelper)
-                wmHelper.StateSyncBuilder()
-                    .withImeShown()
-                    .waitForAndVerify()
-            }
+        }
+        transitions {
+            testApp.launchViaIntent(wmHelper)
+            wmHelper.StateSyncBuilder()
+                .withImeShown()
+                .waitForAndVerify()
         }
     }
 
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerIsVisibleAtStartAndEnd() =
+        super.statusBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun entireScreenCovered() = super.entireScreenCovered()
+
     /**
-     * Checks that [FlickerComponentName.IME] window becomes visible during the transition
+     * Checks that [ComponentMatcher.IME] window becomes visible during the transition
      */
     @Presubmit
     @Test
     fun imeWindowBecomesVisible() = testSpec.imeWindowBecomesVisible()
 
     /**
-     * Checks that [FlickerComponentName.IME] layer becomes visible during the transition
+     * Checks that [ComponentMatcher.IME] layer becomes visible during the transition
      */
     @Presubmit
     @Test
     fun imeLayerBecomesVisible() = testSpec.imeLayerBecomesVisible()
 
     /**
-     * Checks that [FlickerComponentName.IME] layer is invisible at the start of the transition
+     * Checks that [ComponentMatcher.IME] layer is invisible at the start of the transition
      */
     @Presubmit
     @Test
     fun imeLayerNotExistsStart() {
         testSpec.assertLayersStart {
-            this.isInvisible(FlickerComponentName.IME)
+            this.isInvisible(ComponentMatcher.IME)
         }
     }
 
     /**
-     * Checks that [FlickerComponentName.IME] layer is visible at the end of the transition
+     * Checks that [ComponentMatcher.IME] layer is visible at the end of the transition
      */
     @Presubmit
     @Test
     fun imeLayerExistsEnd() {
         testSpec.assertLayersEnd {
-            this.isVisible(FlickerComponentName.IME)
+            this.isVisible(ComponentMatcher.IME)
         }
     }
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt
index 1854d6e..5296e30 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt
@@ -16,25 +16,19 @@
 
 package com.android.server.wm.flicker.ime
 
-import android.app.Instrumentation
+import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.view.Surface
 import android.view.WindowManagerPolicyConstants
 import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group2
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
 import com.android.server.wm.flicker.helpers.ImeAppHelper
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarWindowIsVisible
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -52,39 +46,40 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group2
-class OpenImeWindowAndCloseTest(private val testSpec: FlickerTestParameter) {
-    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class OpenImeWindowAndCloseTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
     private val simpleApp = SimpleAppHelper(instrumentation)
     private val testApp = ImeAppHelper(instrumentation)
 
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            setup {
-                eachRun {
-                    simpleApp.launchViaIntent(wmHelper)
-                    testApp.launchViaIntent(wmHelper)
-                    testApp.openIME(wmHelper)
-                }
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            eachRun {
+                simpleApp.launchViaIntent(wmHelper)
+                testApp.launchViaIntent(wmHelper)
+                testApp.openIME(wmHelper)
             }
-            transitions {
-                testApp.finishActivity(wmHelper)
-            }
-            teardown {
-                test {
-                    simpleApp.exit(wmHelper)
-                }
+        }
+        transitions {
+            testApp.finishActivity(wmHelper)
+        }
+        teardown {
+            test {
+                simpleApp.exit(wmHelper)
             }
         }
     }
 
-    @Presubmit
+    /** {@inheritDoc} */
+    @Postsubmit
     @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
+    override fun navBarLayerPositionAtStartAndEnd() =
+        super.navBarLayerPositionAtStartAndEnd()
 
-    @Presubmit
+    /** {@inheritDoc} */
+    @Postsubmit
     @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
 
     @Presubmit
     @Test
@@ -92,48 +87,21 @@
 
     @Presubmit
     @Test
-    fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible()
-
-    @Presubmit
-    @Test
-    fun entireScreenCovered() = testSpec.entireScreenCovered()
-
-    @Presubmit
-    @Test
     fun imeLayerBecomesInvisible() = testSpec.imeLayerBecomesInvisible()
 
-    @Presubmit
-    @Test
-    fun visibleLayersShownMoreThanOneConsecutiveEntry() {
-        testSpec.assertLayers {
-            this.visibleLayersShownMoreThanOneConsecutiveEntry()
-        }
-    }
-
-    @Test
-    fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
-        testSpec.assertWm {
-            this.visibleWindowsShownMoreThanOneConsecutiveEntry()
-        }
-    }
-
     companion object {
         @Parameterized.Parameters(name = "{0}")
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                    .getConfigNonRotationTests(
-                            repetitions = 3,
-                            supportedRotations = listOf(Surface.ROTATION_0),
-                            supportedNavigationModes = listOf(
-                                    WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
-                                    WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
-                            )
+                .getConfigNonRotationTests(
+                    repetitions = 3,
+                    supportedRotations = listOf(Surface.ROTATION_0),
+                    supportedNavigationModes = listOf(
+                        WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
+                        WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
                     )
+                )
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
index 4f26fc2..b8686bc 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
@@ -16,16 +16,12 @@
 
 package com.android.server.wm.flicker.ime
 
-import android.app.Instrumentation
-import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.platform.test.annotations.RequiresDevice
 import android.view.Surface
 import android.view.WindowManagerPolicyConstants
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
@@ -33,11 +29,7 @@
 import com.android.server.wm.flicker.dsl.FlickerBuilder
 import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
 import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.navBarLayerPositionEnd
-import com.android.server.wm.flicker.navBarWindowIsVisible
 import com.android.server.wm.flicker.snapshotStartingWindowLayerCoversExactlyOnApp
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -54,47 +46,53 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group2
-class OpenImeWindowFromFixedOrientationAppTest(private val testSpec: FlickerTestParameter) {
-    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class OpenImeWindowFromFixedOrientationAppTest(
+    testSpec: FlickerTestParameter
+) : BaseTest(testSpec) {
     private val imeTestApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
-    private val taplInstrumentation = LauncherInstrumentation()
 
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            setup {
-                test {
-                    // Launch the activity with expecting IME will be shown.
-                    imeTestApp.launchViaIntent(wmHelper)
-                }
-                eachRun {
-                    // Swiping out the IME activity to home.
-                    taplInstrumentation.goHome()
-                    wmHelper.StateSyncBuilder()
-                        .withHomeActivityVisible()
-                        .waitForAndVerify()
-                }
-            }
-            transitions {
-                // Bring the exist IME activity to the front in landscape mode device rotation.
-                setRotation(Surface.ROTATION_90)
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            test {
+                // Launch the activity with expecting IME will be shown.
                 imeTestApp.launchViaIntent(wmHelper)
             }
-            teardown {
-                test {
-                    imeTestApp.exit(wmHelper)
-                }
+            eachRun {
+                // Swiping out the IME activity to home.
+                device.pressHome()
+                wmHelper.StateSyncBuilder()
+                    .withHomeActivityVisible()
+                    .waitForAndVerify()
+            }
+        }
+        transitions {
+            // Bring the exist IME activity to the front in landscape mode device rotation.
+            setRotation(Surface.ROTATION_90)
+            imeTestApp.launchViaIntent(wmHelper)
+        }
+        teardown {
+            test {
+                imeTestApp.exit(wmHelper)
             }
         }
     }
 
-    @Presubmit
+    /** {@inheritDoc} */
+    @Postsubmit
     @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
+    override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
 
-    @Presubmit
+    /** {@inheritDoc} */
+    @Postsubmit
     @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
+    override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
 
     @Presubmit
     @Test
@@ -102,19 +100,12 @@
 
     @Presubmit
     @Test
-    fun navBarLayerRotatesAndScales() = testSpec.navBarLayerPositionEnd()
-
-    @FlakyTest(bugId = 206753786)
-    fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
-    @Presubmit
-    @Test
     fun imeLayerBecomesVisible() = testSpec.imeLayerBecomesVisible()
 
     @Postsubmit
     @Test
     fun snapshotStartingWindowLayerCoversExactlyOnApp() {
-        testSpec.snapshotStartingWindowLayerCoversExactlyOnApp(imeTestApp.component)
+        testSpec.snapshotStartingWindowLayerCoversExactlyOnApp(imeTestApp)
     }
 
     companion object {
@@ -128,13 +119,13 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                    .getConfigNonRotationTests(
-                            repetitions = 3,
-                            supportedRotations = listOf(Surface.ROTATION_90),
-                            supportedNavigationModes = listOf(
-                                    WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
-                            )
+                .getConfigNonRotationTests(
+                    repetitions = 3,
+                    supportedRotations = listOf(Surface.ROTATION_90),
+                    supportedNavigationModes = listOf(
+                        WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
                     )
+                )
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
index dbec3643..fdc2193 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
@@ -16,27 +16,17 @@
 
 package com.android.server.wm.flicker.ime
 
-import android.app.Instrumentation
-import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.Presubmit
 import android.view.Surface
 import android.view.WindowManagerPolicyConstants
 import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group2
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
 import com.android.server.wm.flicker.helpers.ImeAppHelper
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -52,97 +42,50 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group2
-class OpenImeWindowTest(private val testSpec: FlickerTestParameter) {
-    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class OpenImeWindowTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
     private val testApp = ImeAppHelper(instrumentation)
 
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            setup {
-                test {
-                    testApp.launchViaIntent(wmHelper)
-                }
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            test {
+                testApp.launchViaIntent(wmHelper)
             }
-            transitions {
-                testApp.openIME(wmHelper)
+        }
+        transitions {
+            testApp.openIME(wmHelper)
+        }
+        teardown {
+            eachRun {
+                testApp.closeIME(wmHelper)
             }
-            teardown {
-                eachRun {
-                    testApp.closeIME(wmHelper)
-                }
-                test {
-                    testApp.exit(wmHelper)
-                }
+            test {
+                testApp.exit(wmHelper)
             }
         }
     }
 
     @Presubmit
     @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
-    @Presubmit
-    @Test
     fun imeWindowBecomesVisible() = testSpec.imeWindowBecomesVisible()
 
     @Presubmit
     @Test
     fun appWindowAlwaysVisibleOnTop() {
         testSpec.assertWm {
-            this.isAppWindowOnTop(testApp.component)
+            this.isAppWindowOnTop(testApp)
         }
     }
 
     @Presubmit
     @Test
-    fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible()
-
-    @Presubmit
-    @Test
-    fun entireScreenCovered() = testSpec.entireScreenCovered()
-
-    @Presubmit
-    @Test
     fun imeLayerBecomesVisible() = testSpec.imeLayerBecomesVisible()
 
     @Presubmit
     @Test
     fun layerAlwaysVisible() {
         testSpec.assertLayers {
-            this.isVisible(testApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
-    @FlakyTest(bugId = 206753786)
-    @Test
-    fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
-    @Presubmit
-    @Test
-    fun visibleLayersShownMoreThanOneConsecutiveEntry() {
-        testSpec.assertLayers {
-            this.visibleLayersShownMoreThanOneConsecutiveEntry()
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
-        testSpec.assertWm {
-            this.visibleWindowsShownMoreThanOneConsecutiveEntry()
+            this.isVisible(testApp)
         }
     }
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt
index eedbd5d3..470fa58 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt
@@ -16,15 +16,12 @@
 
 package com.android.server.wm.flicker.ime
 
-import android.app.Instrumentation
-import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.platform.test.annotations.RequiresDevice
 import android.view.Surface
 import android.view.WindowManagerPolicyConstants
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
@@ -32,16 +29,14 @@
 import com.android.server.wm.flicker.dsl.FlickerBuilder
 import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
 import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.flicker.navBarLayerIsVisibleAtStartAndEnd
+import com.android.server.wm.flicker.statusBarLayerIsVisibleAtStartAndEnd
+import com.android.server.wm.traces.common.ComponentMatcher
 import com.android.server.wm.traces.common.WindowManagerConditionsFactory
 import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
-import org.junit.Assume.assumeFalse
-import org.junit.Assume.assumeTrue
+import org.junit.Assume
 import org.junit.FixMethodOrder
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.MethodSorters
@@ -56,44 +51,39 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group4
-class OpenImeWindowToOverViewTest(private val testSpec: FlickerTestParameter) {
-    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class OpenImeWindowToOverViewTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
     private val imeTestApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
-    private val statusBarInvisible = WindowManagerConditionsFactory.isStatusBarVisible().negate()
-    private val navBarInvisible = WindowManagerConditionsFactory.isNavBarVisible().negate()
 
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            setup {
-                eachRun {
-                    imeTestApp.launchViaIntent(wmHelper)
-                }
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            eachRun {
+                imeTestApp.launchViaIntent(wmHelper)
             }
-            transitions {
-                device.pressRecentApps()
-                val builder = wmHelper.StateSyncBuilder()
-                    .withRecentsActivityVisible()
-                waitNavStatusBarVisibility(builder)
-                builder.waitForAndVerify()
-            }
-            teardown {
-                test {
-                    device.pressHome()
-                    wmHelper.StateSyncBuilder()
-                        .withHomeActivityVisible()
-                        .waitForAndVerify()
-                    imeTestApp.exit(wmHelper)
-                }
+        }
+        transitions {
+            device.pressRecentApps()
+            val builder = wmHelper.StateSyncBuilder()
+                .withRecentsActivityVisible()
+            waitNavStatusBarVisibility(builder)
+            builder.waitForAndVerify()
+        }
+        teardown {
+            test {
+                device.pressHome()
+                wmHelper.StateSyncBuilder()
+                    .withHomeActivityVisible()
+                    .waitForAndVerify()
+                imeTestApp.exit(wmHelper)
             }
         }
     }
 
     /**
-     * The bars (including status bar and navigation bar) are expected to be hidden while
-     * entering overview in landscape if launcher is set to portrait only. Because
-     * "showing portrait overview (launcher) in landscape display" is an intermediate state
-     * depending on the touch-up to decide the intention of gesture, the display may keep in
+     * The bars (including [ComponentMatcher.STATUS_BAR] and [ComponentMatcher.NAV_BAR]) are
+     * expected to be hidden while entering overview in landscape if launcher is set to portrait
+     * only. Because "showing portrait overview (launcher) in landscape display" is an intermediate
+     * state depending on the touch-up to decide the intention of gesture, the display may keep in
      * landscape if return to app, or change to portrait if the gesture is to swipe-to-home.
      *
      * So instead of showing landscape bars with portrait launcher at the same time
@@ -104,20 +94,28 @@
      */
     private fun waitNavStatusBarVisibility(stateSync: WindowManagerStateHelper.StateSyncBuilder) {
         when {
-            testSpec.isLandscapeOrSeascapeAtStart ->
-                stateSync.add(statusBarInvisible)
+            testSpec.isLandscapeOrSeascapeAtStart && !testSpec.isTablet ->
+                stateSync.add(WindowManagerConditionsFactory.isStatusBarVisible().negate())
             else ->
-                stateSync.withNavBarStatusBarVisible()
+                stateSync.withNavOrTaskBarVisible().withStatusBarVisible()
         }
     }
-
-    @Presubmit
+    /** {@inheritDoc} */
+    @Postsubmit
     @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
+    override fun entireScreenCovered() = super.entireScreenCovered()
 
-    @Presubmit
+    /** {@inheritDoc} */
+    @Postsubmit
     @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
 
     @Presubmit
     @Test
@@ -127,9 +125,10 @@
 
     @Presubmit
     @Test
-    fun navBarLayerIsVisible3Button() {
-        assumeFalse(testSpec.isGesturalNavigation)
-        testSpec.navBarLayerIsVisible()
+    fun navBarLayerIsVisibleAtStartAndEnd3Button() {
+        Assume.assumeFalse(testSpec.isTablet)
+        Assume.assumeFalse(testSpec.isGesturalNavigation)
+        testSpec.navBarLayerIsVisibleAtStartAndEnd()
     }
 
     /**
@@ -137,10 +136,11 @@
      */
     @Presubmit
     @Test
-    fun navBarLayerIsVisibleInPortraitGestural() {
-        assumeFalse(testSpec.isLandscapeOrSeascapeAtStart)
-        assumeTrue(testSpec.isGesturalNavigation)
-        testSpec.navBarLayerIsVisible()
+    fun navBarLayerIsVisibleAtStartAndEndGestural() {
+        Assume.assumeFalse(testSpec.isTablet)
+        Assume.assumeTrue(testSpec.isGesturalNavigation)
+        Assume.assumeFalse(isShellTransitionsEnabled)
+        testSpec.navBarLayerIsVisibleAtStartAndEnd()
     }
 
     /**
@@ -150,50 +150,119 @@
     @Postsubmit
     @Test
     fun navBarLayerIsInvisibleInLandscapeGestural() {
-        assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
-        assumeTrue(testSpec.isGesturalNavigation)
-        assumeTrue(isShellTransitionsEnabled)
+        Assume.assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
+        Assume.assumeTrue(testSpec.isGesturalNavigation)
+        Assume.assumeTrue(isShellTransitionsEnabled)
         testSpec.assertLayersStart {
-            this.isVisible(FlickerComponentName.NAV_BAR)
+            this.isVisible(ComponentMatcher.NAV_BAR)
         }
         testSpec.assertLayersEnd {
-            this.isInvisible(FlickerComponentName.NAV_BAR)
+            this.isInvisible(ComponentMatcher.NAV_BAR)
         }
     }
 
+    /**
+     * In the legacy transitions, the nav bar is not marked as invisible.
+     * In the new transitions this is fixed and the nav bar shows as invisible
+     */
+    @Presubmit
+    @Test
+    fun statusBarLayerIsInvisibleInLandscapePhone() {
+        Assume.assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
+        Assume.assumeTrue(testSpec.isGesturalNavigation)
+        Assume.assumeFalse(testSpec.isTablet)
+        testSpec.assertLayersStart {
+            this.isVisible(ComponentMatcher.STATUS_BAR)
+        }
+        testSpec.assertLayersEnd {
+            this.isInvisible(ComponentMatcher.STATUS_BAR)
+        }
+    }
+
+    /**
+     * In the legacy transitions, the nav bar is not marked as invisible.
+     * In the new transitions this is fixed and the nav bar shows as invisible
+     */
+    @Presubmit
+    @Test
+    fun statusBarLayerIsInvisibleInLandscapeTablet() {
+        Assume.assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
+        Assume.assumeTrue(testSpec.isGesturalNavigation)
+        Assume.assumeTrue(testSpec.isTablet)
+        testSpec.statusBarLayerIsVisibleAtStartAndEnd()
+    }
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Visibility changes depending on orientation and navigation mode")
+    override fun navBarLayerIsVisibleAtStartAndEnd() { }
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Visibility changes depending on orientation and navigation mode")
+    override fun navBarLayerPositionAtStartAndEnd() { }
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Visibility changes depending on orientation and navigation mode")
+    override fun statusBarLayerPositionAtStartAndEnd() { }
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Visibility changes depending on orientation and navigation mode")
+    override fun statusBarLayerIsVisibleAtStartAndEnd() { }
+
+    @Postsubmit
+    @Test
+    override fun taskBarLayerIsVisibleAtStartAndEnd() =
+        super.taskBarLayerIsVisibleAtStartAndEnd()
+
     @Postsubmit
     @Test
     fun statusBarLayerIsVisibleInPortrait() {
-        assumeFalse(testSpec.isLandscapeOrSeascapeAtStart)
-        testSpec.statusBarLayerIsVisible()
+        Assume.assumeFalse(testSpec.isLandscapeOrSeascapeAtStart)
+        testSpec.statusBarLayerIsVisibleAtStartAndEnd()
     }
 
     @Presubmit
     @Test
-    fun statusBarLayerIsInvisibleInLandscape() {
-        assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
+    fun statusBarLayerIsInvisibleInLandscapeShell() {
+        Assume.assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
+        Assume.assumeFalse(testSpec.isTablet)
+        Assume.assumeTrue(isShellTransitionsEnabled)
         testSpec.assertLayersStart {
-            this.isVisible(FlickerComponentName.STATUS_BAR)
+            this.isVisible(ComponentMatcher.STATUS_BAR)
         }
         testSpec.assertLayersEnd {
-            this.isInvisible(FlickerComponentName.STATUS_BAR)
+            this.isInvisible(ComponentMatcher.STATUS_BAR)
         }
     }
 
-    @FlakyTest(bugId = 228011606)
+    @Presubmit
+    @Test
+    fun statusBarLayerIsVisibleInLandscapeLegacy() {
+        Assume.assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
+        Assume.assumeTrue(testSpec.isTablet)
+        Assume.assumeFalse(isShellTransitionsEnabled)
+        testSpec.statusBarLayerIsVisibleAtStartAndEnd()
+    }
+
+    @Presubmit
     @Test
     fun imeLayerIsVisibleAndAssociatedWithAppWidow() {
         testSpec.assertLayersStart {
-            isVisible(FlickerComponentName.IME).visibleRegion(FlickerComponentName.IME)
-                    .coversAtMost(isVisible(imeTestApp.component)
-                            .visibleRegion(imeTestApp.component).region)
+            isVisible(ComponentMatcher.IME).visibleRegion(ComponentMatcher.IME)
+                .coversAtMost(
+                    isVisible(imeTestApp)
+                        .visibleRegion(imeTestApp).region
+                )
         }
         testSpec.assertLayers {
             this.invoke("imeLayerIsVisibleAndAlignAppWidow") {
-                val imeVisibleRegion = it.visibleRegion(FlickerComponentName.IME)
-                val appVisibleRegion = it.visibleRegion(imeTestApp.component)
+                val imeVisibleRegion = it.visibleRegion(ComponentMatcher.IME)
+                val appVisibleRegion = it.visibleRegion(imeTestApp)
                 if (imeVisibleRegion.region.isNotEmpty) {
-                    it.isVisible(FlickerComponentName.IME)
+                    it.isVisible(ComponentMatcher.IME)
                     imeVisibleRegion.coversAtMost(appVisibleRegion.region)
                 }
             }
@@ -211,14 +280,14 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                    .getConfigNonRotationTests(
-                            repetitions = 1,
-                            supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90),
-                            supportedNavigationModes = listOf(
-                                    WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
-                                    WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
-                            )
+                .getConfigNonRotationTests(
+                    repetitions = 1,
+                    supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90),
+                    supportedNavigationModes = listOf(
+                        WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
+                        WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
                     )
+                )
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
index 7d4724c..e911260 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
@@ -16,34 +16,23 @@
 
 package com.android.server.wm.flicker.ime
 
-import android.app.Instrumentation
 import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.Presubmit
 import android.view.Surface
 import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group2
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
 import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
 import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import com.android.server.wm.flicker.helpers.reopenAppFromOverview
 import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
-import com.android.server.wm.traces.common.FlickerComponentName.Companion.LAUNCHER
-import org.junit.Assume.assumeFalse
-import org.junit.Assume.assumeTrue
-import org.junit.Before
+import com.android.server.wm.traces.common.ComponentMatcher
+import com.android.server.wm.traces.common.ComponentMatcher.Companion.LAUNCHER
+import org.junit.Assume
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -59,61 +48,67 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group2
-open class ReOpenImeWindowTest(private val testSpec: FlickerTestParameter) {
-    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+open class ReOpenImeWindowTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
     private val testApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
 
-    @Before
-    open fun before() {
-        assumeFalse(isShellTransitionsEnabled)
-    }
-
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            setup {
-                test {
-                    testApp.launchViaIntent(wmHelper)
-                    testApp.openIME(wmHelper)
-                }
-                eachRun {
-                    this.setRotation(testSpec.startRotation)
-                    device.pressRecentApps()
-                    wmHelper.StateSyncBuilder()
-                        .withRecentsActivityVisible()
-                        .waitForAndVerify()
-                }
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            test {
+                testApp.launchViaIntent(wmHelper)
+                testApp.openIME(wmHelper)
             }
-            transitions {
-                device.reopenAppFromOverview(wmHelper)
+            eachRun {
+                this.setRotation(testSpec.startRotation)
+                device.pressRecentApps()
                 wmHelper.StateSyncBuilder()
-                    .withImeShown()
+                    .withRecentsActivityVisible()
                     .waitForAndVerify()
             }
-            teardown {
-                test {
-                    testApp.exit(wmHelper)
-                }
+        }
+        transitions {
+            device.reopenAppFromOverview(wmHelper)
+            wmHelper.StateSyncBuilder()
+                .withImeShown()
+                .waitForAndVerify()
+        }
+        teardown {
+            test {
+                testApp.exit(wmHelper)
             }
         }
     }
 
-    @Presubmit
+    /** {@inheritDoc} */
+    @FlakyTest(bugId = 206753786)
     @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
 
+    /** {@inheritDoc} */
     @Presubmit
     @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() {
+        // depends on how much of the animation transactions are sent to SF at once
+        // sometimes this layer appears for 2-3 frames, sometimes for only 1
+        val recentTaskComponent = ComponentMatcher("", "RecentTaskScreenshotSurface")
+        testSpec.assertLayers {
+            this.visibleLayersShownMoreThanOneConsecutiveEntry(
+                listOf(ComponentMatcher.SPLASH_SCREEN,
+                    ComponentMatcher.SNAPSHOT, recentTaskComponent)
+            )
+        }
+    }
 
+    /** {@inheritDoc} */
     @Presubmit
     @Test
-    fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
-        val component = FlickerComponentName("", "RecentTaskScreenshotSurface")
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
+        val component = ComponentMatcher("", "RecentTaskScreenshotSurface")
         testSpec.assertWm {
             this.visibleWindowsShownMoreThanOneConsecutiveEntry(
-                    ignoreWindows = listOf(FlickerComponentName.SPLASH_SCREEN,
-                        FlickerComponentName.SNAPSHOT,
+                    ignoreWindows = listOf(ComponentMatcher.SPLASH_SCREEN,
+                        ComponentMatcher.SNAPSHOT,
                         component)
             )
         }
@@ -136,66 +131,53 @@
     @Presubmit
     @Test
     fun imeAppWindowVisibilityLegacy() {
-        assumeFalse(isShellTransitionsEnabled)
+        Assume.assumeFalse(isShellTransitionsEnabled)
         // the app starts visible in live tile, and stays visible for the duration of entering
         // and exiting overview. However, legacy transitions seem to have a bug which causes
         // everything to restart during the test, so expect the app to disappear and come back.
         // Since we log 1x per frame, sometimes the activity visibility and the app visibility
         // are updated together, sometimes not, thus ignore activity check at the start
         testSpec.assertWm {
-            this.isAppWindowVisible(testApp.component)
+            this.isAppWindowVisible(testApp)
                     .then()
-                    .isAppWindowInvisible(testApp.component)
+                    .isAppWindowInvisible(testApp)
                     .then()
-                    .isAppWindowVisible(testApp.component)
+                    .isAppWindowVisible(testApp)
         }
     }
 
     @FlakyTest(bugId = 204570898)
     @Test
     fun imeAppWindowVisibility() {
-        assumeTrue(isShellTransitionsEnabled)
+        Assume.assumeTrue(isShellTransitionsEnabled)
         // the app starts visible in live tile, and stays visible for the duration of entering
         // and exiting overview. Since we log 1x per frame, sometimes the activity visibility
         // and the app visibility are updated together, sometimes not, thus ignore activity
         // check at the start
         testSpec.assertWm {
-            this.isAppWindowVisible(testApp.component)
+            this.isAppWindowVisible(testApp)
         }
     }
 
     @Presubmit
     @Test
-    // During testing the launcher is always in portrait mode
-    fun entireScreenCovered() = testSpec.entireScreenCovered()
-
-    @Presubmit
-    @Test
-    fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible()
-
-    @Presubmit
-    @Test
     fun imeLayerIsBecomesVisibleLegacy() {
-        assumeFalse(isShellTransitionsEnabled)
+        Assume.assumeFalse(isShellTransitionsEnabled)
         testSpec.assertLayers {
-            this.isVisible(FlickerComponentName.IME)
+            this.isVisible(ComponentMatcher.IME)
                     .then()
-                    .isInvisible(FlickerComponentName.IME)
+                    .isInvisible(ComponentMatcher.IME)
                     .then()
-                    .isVisible(FlickerComponentName.IME)
+                    .isVisible(ComponentMatcher.IME)
         }
     }
 
     @FlakyTest(bugId = 204570898)
     @Test
     fun imeLayerIsBecomesVisible() {
-        assumeTrue(isShellTransitionsEnabled)
+        Assume.assumeTrue(isShellTransitionsEnabled)
         testSpec.assertLayers {
-            this.isVisible(FlickerComponentName.IME)
+            this.isVisible(ComponentMatcher.IME)
         }
     }
 
@@ -203,33 +185,11 @@
     @Test
     fun appLayerReplacesLauncher() {
         testSpec.assertLayers {
-            this.isVisible(FlickerComponentName.LAUNCHER)
+            this.isVisible(ComponentMatcher.LAUNCHER)
                 .then()
-                .isVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
+                .isVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
                 .then()
-                .isVisible(testApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
-    @FlakyTest(bugId = 206753786)
-    @Test
-    fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
-    @Presubmit
-    @Test
-    fun visibleLayersShownMoreThanOneConsecutiveEntry() {
-        // depends on how much of the animation transactions are sent to SF at once
-        // sometimes this layer appears for 2-3 frames, sometimes for only 1
-        val recentTaskComponent = FlickerComponentName("", "RecentTaskScreenshotSurface")
-        testSpec.assertLayers {
-            this.visibleLayersShownMoreThanOneConsecutiveEntry(
-                    listOf(FlickerComponentName.SPLASH_SCREEN,
-                        FlickerComponentName.SNAPSHOT, recentTaskComponent)
-            )
+                .isVisible(testApp)
         }
     }
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest_ShellTransit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest_ShellTransit.kt
deleted file mode 100644
index 5362a41..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest_ShellTransit.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker.ime
-
-import android.platform.test.annotations.FlakyTest
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.annotation.Group2
-import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
-import org.junit.Assume
-import org.junit.Before
-import org.junit.FixMethodOrder
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test IME window opening transitions.
- * To run this test: `atest FlickerTests:ReOpenImeWindowTest`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group2
-@FlakyTest(bugId = 221854428)
-class ReOpenImeWindowTest_ShellTransit(private val testSpec: FlickerTestParameter)
-    : ReOpenImeWindowTest(testSpec) {
-    @Before
-    override fun before() {
-        Assume.assumeTrue(isShellTransitionsEnabled)
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
index d118846..0aeeb03 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
@@ -16,13 +16,12 @@
 
 package com.android.server.wm.flicker.ime
 
-import android.app.Instrumentation
+import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.view.Surface
 import android.view.WindowManagerPolicyConstants
 import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
@@ -33,9 +32,7 @@
 import com.android.server.wm.flicker.helpers.WindowUtils
 import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
 import org.junit.Assume
 import org.junit.Before
 import org.junit.FixMethodOrder
@@ -54,8 +51,9 @@
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group4
 @Presubmit
-open class SwitchImeWindowsFromGestureNavTest(private val testSpec: FlickerTestParameter) {
-    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+open class SwitchImeWindowsFromGestureNavTest(
+    testSpec: FlickerTestParameter
+) : BaseTest(testSpec) {
     private val testApp = SimpleAppHelper(instrumentation)
     private val imeTestApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
 
@@ -64,132 +62,157 @@
         Assume.assumeFalse(isShellTransitionsEnabled)
     }
 
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            setup {
-                eachRun {
-                    this.setRotation(testSpec.startRotation)
-                    testApp.launchViaIntent(wmHelper)
-                    wmHelper.StateSyncBuilder()
-                        .withFullScreenApp(testApp.component)
-                        .waitForAndVerify()
-
-                    imeTestApp.launchViaIntent(wmHelper)
-                    wmHelper.StateSyncBuilder()
-                        .withFullScreenApp(imeTestApp.component)
-                        .waitForAndVerify()
-
-                    imeTestApp.openIME(wmHelper)
-                }
-            }
-            teardown {
-                eachRun {
-                    device.pressHome()
-                    wmHelper.StateSyncBuilder()
-                        .withHomeActivityVisible()
-                        .waitForAndVerify()
-                    testApp.exit(wmHelper)
-                    imeTestApp.exit(wmHelper)
-                }
-            }
-            transitions {
-                // [Step1]: Swipe right from imeTestApp to testApp task
-                createTag(TAG_IME_VISIBLE)
-                val displayBounds = WindowUtils.getDisplayBounds(testSpec.startRotation)
-                device.swipe(0, displayBounds.bounds.height,
-                        displayBounds.bounds.width, displayBounds.bounds.height, 50)
-
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            eachRun {
+                this.setRotation(testSpec.startRotation)
+                testApp.launchViaIntent(wmHelper)
                 wmHelper.StateSyncBuilder()
-                    .withFullScreenApp(testApp.component)
+                    .withFullScreenApp(testApp)
                     .waitForAndVerify()
-                createTag(TAG_IME_INVISIBLE)
-            }
-            transitions {
-                // [Step2]: Swipe left to back to imeTestApp task
-                val displayBounds = WindowUtils.getDisplayBounds(testSpec.startRotation)
-                device.swipe(displayBounds.bounds.width, displayBounds.bounds.height,
-                        0, displayBounds.bounds.height, 50)
+
+                imeTestApp.launchViaIntent(wmHelper)
                 wmHelper.StateSyncBuilder()
-                    .withFullScreenApp(imeTestApp.component)
+                    .withFullScreenApp(imeTestApp)
                     .waitForAndVerify()
+
+                imeTestApp.openIME(wmHelper)
             }
         }
+        teardown {
+            eachRun {
+                device.pressHome()
+                wmHelper.StateSyncBuilder()
+                    .withHomeActivityVisible()
+                    .waitForAndVerify()
+                testApp.exit(wmHelper)
+                imeTestApp.exit(wmHelper)
+            }
+        }
+        transitions {
+            // [Step1]: Swipe right from imeTestApp to testApp task
+            createTag(TAG_IME_VISIBLE)
+            val displayBounds = WindowUtils.getDisplayBounds(testSpec.startRotation)
+            device.swipe(
+                0, displayBounds.bounds.height,
+                displayBounds.bounds.width, displayBounds.bounds.height, 50
+            )
+
+            wmHelper.StateSyncBuilder()
+                .withFullScreenApp(testApp)
+                .waitForAndVerify()
+            createTag(TAG_IME_INVISIBLE)
+        }
+        transitions {
+            // [Step2]: Swipe left to back to imeTestApp task
+            val displayBounds = WindowUtils.getDisplayBounds(testSpec.startRotation)
+            device.swipe(
+                displayBounds.bounds.width, displayBounds.bounds.height,
+                0, displayBounds.bounds.height, 50
+            )
+            wmHelper.StateSyncBuilder()
+                .withFullScreenApp(imeTestApp)
+                .waitForAndVerify()
+        }
     }
 
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun entireScreenCovered() = super.entireScreenCovered()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerIsVisibleAtStartAndEnd() =
+        super.statusBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
+
     @Test
     fun imeAppWindowVisibility() {
         testSpec.assertWm {
-            isAppWindowVisible(imeTestApp.component)
+            isAppWindowVisible(imeTestApp)
                 .then()
-                .isAppSnapshotStartingWindowVisibleFor(testApp.component, isOptional = true)
+                .isAppSnapshotStartingWindowVisibleFor(testApp, isOptional = true)
                 .then()
-                .isAppWindowVisible(testApp.component)
+                .isAppWindowVisible(testApp)
                 .then()
-                .isAppSnapshotStartingWindowVisibleFor(imeTestApp.component, isOptional = true)
+                .isAppSnapshotStartingWindowVisibleFor(imeTestApp, isOptional = true)
                 .then()
-                .isAppWindowVisible(imeTestApp.component)
+                .isAppWindowVisible(imeTestApp)
         }
     }
 
     @Test
-    fun navBarLayerIsVisibleAroundSwitching() {
+    open fun imeLayerIsVisibleWhenSwitchingToImeApp() {
         testSpec.assertLayersStart {
-            isVisible(FlickerComponentName.NAV_BAR)
-        }
-        testSpec.assertLayersEnd {
-            isVisible(FlickerComponentName.NAV_BAR)
-        }
-    }
-
-    @Test
-    fun statusBarLayerIsVisibleAroundSwitching() {
-        testSpec.assertLayersStart {
-            isVisible(FlickerComponentName.STATUS_BAR)
-        }
-        testSpec.assertLayersEnd {
-            isVisible(FlickerComponentName.STATUS_BAR)
-        }
-    }
-
-    @Test
-    fun imeLayerIsVisibleWhenSwitchingToImeApp() {
-        testSpec.assertLayersStart {
-            isVisible(FlickerComponentName.IME)
+            isVisible(ComponentMatcher.IME)
         }
         testSpec.assertLayersTag(TAG_IME_VISIBLE) {
-            isVisible(FlickerComponentName.IME)
+            isVisible(ComponentMatcher.IME)
         }
         testSpec.assertLayersEnd {
-            isVisible(FlickerComponentName.IME)
+            isVisible(ComponentMatcher.IME)
         }
     }
 
     @Test
     fun imeLayerIsInvisibleWhenSwitchingToTestApp() {
         testSpec.assertLayersTag(TAG_IME_INVISIBLE) {
-            isInvisible(FlickerComponentName.IME)
+            isInvisible(ComponentMatcher.IME)
         }
     }
 
-    @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
-    @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
     companion object {
         @Parameterized.Parameters(name = "{0}")
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                    .getConfigNonRotationTests(
-                            repetitions = 3,
-                            supportedNavigationModes = listOf(
-                                    WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
-                            ),
-                            supportedRotations = listOf(Surface.ROTATION_0)
-                    )
+                .getConfigNonRotationTests(
+                    repetitions = 3,
+                    supportedNavigationModes = listOf(
+                        WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+                    ),
+                    supportedRotations = listOf(Surface.ROTATION_0)
+                )
         }
 
         private const val TAG_IME_VISIBLE = "imeVisible"
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest_ShellTransit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest_ShellTransit.kt
index 3dbe1ec..457e973 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest_ShellTransit.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest_ShellTransit.kt
@@ -24,8 +24,8 @@
 import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import org.junit.Assume
 import org.junit.Before
-
 import org.junit.FixMethodOrder
+import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.MethodSorters
 import org.junit.runners.Parameterized
@@ -39,11 +39,30 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group4
-@FlakyTest(bugId = 228012334)
-class SwitchImeWindowsFromGestureNavTest_ShellTransit(testSpec: FlickerTestParameter)
-    : SwitchImeWindowsFromGestureNavTest(testSpec) {
+class SwitchImeWindowsFromGestureNavTest_ShellTransit(
+    testSpec: FlickerTestParameter
+) : SwitchImeWindowsFromGestureNavTest(testSpec) {
     @Before
     override fun before() {
         Assume.assumeTrue(isShellTransitionsEnabled)
     }
+
+    @FlakyTest(bugId = 228012334)
+    @Test
+    override fun entireScreenCovered() = super.entireScreenCovered()
+
+    @FlakyTest(bugId = 228012334)
+    @Test
+    override fun imeLayerIsVisibleWhenSwitchingToImeApp() =
+        super.imeLayerIsVisibleWhenSwitchingToImeApp()
+
+    @FlakyTest(bugId = 228012334)
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+    @FlakyTest(bugId = 228012334)
+    @Test
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
index a33f0ea..86b8e5f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
@@ -16,21 +16,18 @@
 
 package com.android.server.wm.flicker.launch
 
-import android.app.Instrumentation
+import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.Presubmit
 import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group4
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
 import com.android.server.wm.flicker.helpers.TwoActivitiesAppHelper
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 import org.junit.FixMethodOrder
 import org.junit.Test
@@ -59,39 +56,36 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group4
-class ActivitiesTransitionTest(val testSpec: FlickerTestParameter) {
-    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class ActivitiesTransitionTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
     private val testApp: TwoActivitiesAppHelper = TwoActivitiesAppHelper(instrumentation)
-    private val tapl = LauncherInstrumentation()
 
-    /**
-     * Entry point for the test runner. It will use this method to initialize and cache
-     * flicker executions
-     */
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            setup {
-                test {
-                    tapl.setExpectedRotation(testSpec.startRotation)
-                    testApp.launchViaIntent(wmHelper)
-                }
-            }
-            teardown {
-                test {
-                    testApp.exit(wmHelper)
-                }
-            }
-            transitions {
-                testApp.openSecondActivity(device, wmHelper)
-                tapl.pressBack()
-                wmHelper.StateSyncBuilder()
-                    .withFullScreenApp(testApp.component)
-                    .waitForAndVerify()
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            test {
+                tapl.setExpectedRotation(testSpec.startRotation)
+                testApp.launchViaIntent(wmHelper)
             }
         }
+        teardown {
+            test {
+                testApp.exit(wmHelper)
+            }
+        }
+        transitions {
+            testApp.openSecondActivity(device, wmHelper)
+            tapl.pressBack()
+            wmHelper.StateSyncBuilder()
+                .withFullScreenApp(testApp)
+                .waitForAndVerify()
+        }
     }
 
+    /** {@inheritDoc} */
+    @FlakyTest(bugId = 206753786)
+    @Test
+    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+
     /**
      * Checks that the [ActivityOptions.BUTTON_ACTIVITY_COMPONENT_NAME] activity is visible at
      * the start of the transition, that
@@ -116,14 +110,7 @@
     }
 
     /**
-     * Checks that all parts of the screen are covered during the transition
-     */
-    @Presubmit
-    @Test
-    fun entireScreenCovered() = testSpec.entireScreenCovered()
-
-    /**
-     * Checks that the [FlickerComponentName.LAUNCHER] window is not on top. The launcher cannot be
+     * Checks that the [ComponentMatcher.LAUNCHER] window is not on top. The launcher cannot be
      * asserted with `isAppWindowVisible` because it contains 2 windows with the exact same name,
      * and both are never simultaneously visible
      */
@@ -131,17 +118,17 @@
     @Test
     fun launcherWindowNotOnTop() {
         testSpec.assertWm {
-            this.isAppWindowNotOnTop(FlickerComponentName.LAUNCHER)
+            this.isAppWindowNotOnTop(ComponentMatcher.LAUNCHER)
         }
     }
 
     /**
-     * Checks that the [FlickerComponentName.LAUNCHER] layer is never visible during the transition
+     * Checks that the [ComponentMatcher.LAUNCHER] layer is never visible during the transition
      */
     @Presubmit
     @Test
     fun launcherLayerNotVisible() {
-        testSpec.assertLayers { this.isInvisible(FlickerComponentName.LAUNCHER) }
+        testSpec.assertLayers { this.isInvisible(ComponentMatcher.LAUNCHER) }
     }
 
     companion object {
@@ -155,7 +142,7 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                    .getConfigNonRotationTests(repetitions = 3)
+                .getConfigNonRotationTests(repetitions = 3)
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt
index c927044..accf8af 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt
@@ -54,11 +54,10 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group1
-class OpenAppColdFromIcon(testSpec: FlickerTestParameter) :
-    OpenAppFromLauncherTransition(testSpec) {
-    /**
-     * Defines the transition used to run the test
-     */
+class OpenAppColdFromIcon(
+    testSpec: FlickerTestParameter
+) : OpenAppFromLauncherTransition(testSpec) {
+    /** {@inheritDoc} */
     override val transition: FlickerBuilder.() -> Unit
         get() = {
             super.transition(this)
@@ -82,85 +81,107 @@
             }
         }
 
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun appWindowAsTopWindowAtEnd() =
+        super.appWindowAsTopWindowAtEnd()
+
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
     override fun appWindowReplacesLauncherAsTopWindow() =
         super.appWindowReplacesLauncherAsTopWindow()
 
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
     override fun appLayerBecomesVisible() =
         super.appLayerBecomesVisible()
 
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun appLayerReplacesLauncher() =
-        super.appLayerReplacesLauncher()
+    override fun appLayerReplacesLauncher() = super.appLayerReplacesLauncher()
 
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun appWindowBecomesTopWindow() =
-        super.appWindowBecomesTopWindow()
+    override fun appWindowBecomesTopWindow() = super.appWindowBecomesTopWindow()
 
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun appWindowBecomesVisible() =
-        super.appWindowBecomesVisible()
+    override fun appWindowBecomesVisible() = super.appWindowBecomesVisible()
 
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun entireScreenCovered() =
-        super.entireScreenCovered()
+    override fun entireScreenCovered() = super.entireScreenCovered()
 
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun focusChanges() =
-        super.focusChanges()
+    override fun focusChanges() = super.focusChanges()
 
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun navBarLayerIsVisible() =
-        super.navBarLayerIsVisible()
+    override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
 
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun navBarLayerRotatesAndScales() =
-        super.navBarLayerRotatesAndScales()
+    override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
 
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun navBarWindowIsVisible() =
-        super.navBarWindowIsVisible()
+    override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
 
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun statusBarLayerRotatesScales() =
-        super.statusBarLayerRotatesScales()
+    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
 
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun statusBarLayerIsVisible() =
-        super.statusBarLayerIsVisible()
+    override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
 
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun statusBarWindowIsVisible() =
-        super.statusBarWindowIsVisible()
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
 
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerIsVisibleAtStartAndEnd() =
+        super.statusBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
     override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
         super.visibleLayersShownMoreThanOneConsecutiveEntry()
 
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
     override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
         super.visibleWindowsShownMoreThanOneConsecutiveEntry()
 
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun appWindowIsTopWindowAtEnd() =
-        super.appWindowIsTopWindowAtEnd()
+    override fun appWindowIsTopWindowAtEnd() = super.appWindowIsTopWindowAtEnd()
 
     companion object {
         /**
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
index e52b6c3..60a159154 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
@@ -54,11 +54,10 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group1
-open class OpenAppColdTest(testSpec: FlickerTestParameter) :
-    OpenAppFromLauncherTransition(testSpec) {
-    /**
-     * Defines the transition used to run the test
-     */
+open class OpenAppColdTest(
+    testSpec: FlickerTestParameter
+) : OpenAppFromLauncherTransition(testSpec) {
+    /** {@inheritDoc} */
     override val transition: FlickerBuilder.() -> Unit
         get() = {
             super.transition(this)
@@ -81,41 +80,14 @@
     /** {@inheritDoc} */
     @FlakyTest(bugId = 206753786)
     @Test
-    override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
-
-    /** {@inheritDoc} */
-    @FlakyTest(bugId = 206753786)
-    @Test
-    override fun navBarLayerRotatesAndScales() {
-        super.navBarLayerRotatesAndScales()
-    }
+    override fun navBarLayerPositionAtStartAndEnd() =
+        super.navBarLayerPositionAtStartAndEnd()
 
     /** {@inheritDoc} */
     @Presubmit
     @Test
     override fun appLayerReplacesLauncher() = super.appLayerReplacesLauncher()
 
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun appWindowReplacesLauncherAsTopWindow() =
-        super.appWindowReplacesLauncherAsTopWindow()
-
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
-
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun navBarWindowIsVisible() = super.navBarWindowIsVisible()
-
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun entireScreenCovered() = super.entireScreenCovered()
-
     companion object {
         /**
          * Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt
index 269d82d..2d4d798 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt
@@ -19,17 +19,18 @@
 import android.platform.test.annotations.Presubmit
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.replacesLayer
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
 import org.junit.Test
 
 /**
  * Base class for app launch tests
  */
-abstract class OpenAppFromLauncherTransition(testSpec: FlickerTestParameter) :
-    OpenAppTransition(testSpec) {
+abstract class OpenAppFromLauncherTransition(
+    testSpec: FlickerTestParameter
+) : OpenAppTransition(testSpec) {
 
     /**
-     * Checks that the focus changes from the launcher to [testApp]
+     * Checks that the focus changes from the [ComponentMatcher.LAUNCHER] to [testApp]
      */
     @Presubmit
     @Test
@@ -40,31 +41,44 @@
     }
 
     /**
-     * Checks that [FlickerComponentName.LAUNCHER] layer is visible at the start of the transition,
+     * Checks that [ComponentMatcher.LAUNCHER] layer is visible at the start of the transition,
      * and is replaced by [testApp], which remains visible until the end
      */
     open fun appLayerReplacesLauncher() {
-        testSpec.replacesLayer(FlickerComponentName.LAUNCHER, testApp.component,
-                ignoreEntriesWithRotationLayer = true, ignoreSnapshot = true,
-                ignoreSplashscreen = true)
+        testSpec.replacesLayer(
+            ComponentMatcher.LAUNCHER, testApp,
+            ignoreEntriesWithRotationLayer = true, ignoreSnapshot = true,
+            ignoreSplashscreen = true
+        )
     }
 
     /**
-     * Checks that [FlickerComponentName.LAUNCHER] window is visible at the start of the
-     * transition, and is replaced by a snapshot or splash screen (optional), and finally, is
-     * replaced by [testApp], which remains visible until the end
+     * Checks that [ComponentMatcher.LAUNCHER] window is the top window at the start of the
+     * transition, and is replaced by a [ComponentMatcher.SNAPSHOT] or
+     * [ComponentMatcher.SPLASH_SCREEN], or [testApp], which remains visible until the end
      */
     @Presubmit
     @Test
     open fun appWindowReplacesLauncherAsTopWindow() {
         testSpec.assertWm {
-            this.isAppWindowOnTop(FlickerComponentName.LAUNCHER)
-                    .then()
-                    .isAppWindowOnTop(FlickerComponentName.SNAPSHOT, isOptional = true)
-                    .then()
-                    .isAppWindowOnTop(FlickerComponentName.SPLASH_SCREEN, isOptional = true)
-                    .then()
-                    .isAppWindowOnTop(testApp.component)
+            this.isAppWindowOnTop(ComponentMatcher.LAUNCHER)
+                .then()
+                .isAppWindowOnTop(
+                    testApp
+                        .or(ComponentMatcher.SNAPSHOT)
+                        .or(ComponentMatcher.SPLASH_SCREEN)
+                )
+        }
+    }
+
+    /**
+     * Checks that [testApp] window is the top window at the en dof the trace
+     */
+    @Presubmit
+    @Test
+    open fun appWindowAsTopWindowAtEnd() {
+        testSpec.assertWmEnd {
+            this.isAppWindowOnTop(testApp)
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
index cea97ad..220e4ca 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
@@ -24,9 +24,12 @@
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group1
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.navBarLayerPositionEnd
-import com.android.server.wm.flicker.statusBarLayerPositionEnd
+import com.android.server.wm.flicker.navBarLayerPositionAtEnd
+import com.android.server.wm.flicker.statusBarLayerPositionAtEnd
+import com.android.server.wm.traces.common.ComponentMatcher
+import org.junit.Assume
 import org.junit.FixMethodOrder
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.MethodSorters
@@ -87,35 +90,43 @@
     @Test
     override fun appWindowBecomesTopWindow() = super.appWindowBecomesTopWindow()
 
-    /**
-     * Checks the position of the navigation bar at the start and end of the transition
-     *
-     * Differently from the normal usage of this assertion, check only the final state of the
-     * transition because the display is off at the start and the NavBar is never visible
-     */
-    @Postsubmit
+    /** {@inheritDoc} */
     @Test
-    override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerPositionEnd()
+    @Ignore("Display is off at the start")
+    override fun navBarLayerPositionAtStartAndEnd() { }
 
     /**
-     * Checks the position of the status bar at the start and end of the transition
-     *
-     * Differently from the normal usage of this assertion, check only the final state of the
-     * transition because the display is off at the start and the NavBar is never visible
+     * Checks the position of the [ComponentMatcher.NAV_BAR] at the end of the transition
      */
     @Postsubmit
     @Test
-    override fun statusBarLayerRotatesScales() = testSpec.statusBarLayerPositionEnd()
+    fun navBarLayerPositionAtEnd() {
+        Assume.assumeFalse(testSpec.isTablet)
+        testSpec.navBarLayerPositionAtEnd()
+    }
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Display is off at the start")
+    override fun statusBarLayerPositionAtStartAndEnd() { }
+
+    /**
+     * Checks the position of the [ComponentMatcher.STATUS_BAR] at the start and end of the
+     * transition
+     */
+    @Postsubmit
+    @Test
+    fun statusBarLayerPositionEnd() = testSpec.statusBarLayerPositionAtEnd()
 
     /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
+    override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
 
     /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun navBarWindowIsVisible() = super.navBarWindowIsVisible()
+    override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
 
     /** {@inheritDoc} */
     @Postsubmit
@@ -125,7 +136,7 @@
     /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun statusBarWindowIsVisible() = super.statusBarWindowIsVisible()
+    override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
 
     /** {@inheritDoc} */
     @Postsubmit
@@ -135,7 +146,8 @@
     /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun statusBarLayerIsVisible() = super.statusBarLayerIsVisible()
+    override fun statusBarLayerIsVisibleAtStartAndEnd() =
+        super.statusBarLayerIsVisibleAtStartAndEnd()
 
     /** {@inheritDoc} */
     @Postsubmit
@@ -143,6 +155,12 @@
     override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
         super.visibleLayersShownMoreThanOneConsecutiveEntry()
 
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun appWindowIsTopWindowAtEnd() =
+        super.appWindowIsTopWindowAtEnd()
+
     companion object {
         /**
          * Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
index 3d5f317..9ed1bde 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
@@ -18,16 +18,19 @@
 
 import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.Postsubmit
+import android.platform.test.annotations.Presubmit
 import android.platform.test.annotations.RequiresDevice
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group1
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.navBarLayerPositionEnd
-import com.android.server.wm.flicker.statusBarLayerPositionEnd
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.flicker.navBarLayerPositionAtEnd
+import com.android.server.wm.flicker.statusBarLayerPositionAtEnd
+import com.android.server.wm.traces.common.ComponentMatcher
+import org.junit.Assume
 import org.junit.FixMethodOrder
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.MethodSorters
@@ -83,16 +86,16 @@
         testSpec.assertWm {
             this.hasNoVisibleAppWindow()
                     .then()
-                    .isAppWindowOnTop(FlickerComponentName.SNAPSHOT, isOptional = true)
+                    .isAppWindowOnTop(ComponentMatcher.SNAPSHOT, isOptional = true)
                     .then()
-                    .isAppWindowOnTop(FlickerComponentName.SPLASH_SCREEN, isOptional = true)
+                    .isAppWindowOnTop(ComponentMatcher.SPLASH_SCREEN, isOptional = true)
                     .then()
-                    .isAppWindowOnTop(testApp.component)
+                    .isAppWindowOnTop(testApp)
         }
     }
 
     /**
-     * Checks that the screen is locked.
+     * Checks that the screen is locked at the start of the transition
      */
     @Test
     @Postsubmit
@@ -113,35 +116,43 @@
     override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
         super.visibleWindowsShownMoreThanOneConsecutiveEntry()
 
-    /**
-     * Checks the position of the navigation bar at the start and end of the transition
-     *
-     * Differently from the normal usage of this assertion, check only the final state of the
-     * transition because the display is off at the start and the NavBar is never visible
-     */
-    @Postsubmit
+    /** {@inheritDoc} */
     @Test
-    override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerPositionEnd()
+    @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+    override fun navBarLayerPositionAtStartAndEnd() { }
 
     /**
-     * Checks the position of the status bar at the start and end of the transition
-     *
-     * Differently from the normal usage of this assertion, check only the final state of the
-     * transition because the display is off at the start and the NavBar is never visible
+     * Checks the position of the [ComponentMatcher.NAV_BAR] at the end of the transition
      */
     @Postsubmit
     @Test
-    override fun statusBarLayerRotatesScales() = testSpec.statusBarLayerPositionEnd()
+    fun navBarLayerPositionAtEnd() {
+        Assume.assumeFalse(testSpec.isTablet)
+        testSpec.navBarLayerPositionAtEnd()
+    }
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+    override fun statusBarLayerPositionAtStartAndEnd() { }
+
+    /**
+     * Checks the position of the [ComponentMatcher.STATUS_BAR] at the start and end of the
+     * transition
+     */
+    @Postsubmit
+    @Test
+    fun statusBarLayerPositionEnd() = testSpec.statusBarLayerPositionAtEnd()
 
     /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
+    override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
 
     /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun navBarWindowIsVisible() = super.navBarWindowIsVisible()
+    override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
 
     /** {@inheritDoc} */
     @Postsubmit
@@ -151,7 +162,7 @@
     /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun statusBarWindowIsVisible() = super.statusBarWindowIsVisible()
+    override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
 
     /** {@inheritDoc} */
     @Postsubmit
@@ -166,7 +177,8 @@
     /** {@inheritDoc} */
     @Postsubmit
     @Test
-    override fun statusBarLayerIsVisible() = super.statusBarLayerIsVisible()
+    override fun statusBarLayerIsVisibleAtStartAndEnd() =
+        super.statusBarLayerIsVisibleAtStartAndEnd()
 
     /** {@inheritDoc} */
     @Postsubmit
@@ -174,6 +186,18 @@
     override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
         super.visibleLayersShownMoreThanOneConsecutiveEntry()
 
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun appWindowIsTopWindowAtEnd() =
+        super.appWindowIsTopWindowAtEnd()
+
+    /** {@inheritDoc} */
+    @Presubmit
+    @Test
+    override fun appWindowBecomesTopWindow_ShellTransit() =
+        super.appWindowBecomesTopWindow_ShellTransit()
+
     companion object {
         /**
          * Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt
index 446faa7..2973059 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt
@@ -26,9 +26,7 @@
 import com.android.server.wm.flicker.dsl.FlickerBuilder
 import com.android.server.wm.flicker.helpers.ShowWhenLockedAppHelper
 import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-import com.android.server.wm.flicker.navBarLayerPositionEnd
-import com.android.server.wm.flicker.statusBarLayerPositionEnd
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -67,7 +65,7 @@
                     // Launch an activity that is shown when the device is locked
                     showWhenLockedApp.launchViaIntent(wmHelper)
                     wmHelper.StateSyncBuilder()
-                        .withFullScreenApp(showWhenLockedApp.component)
+                        .withFullScreenApp(showWhenLockedApp)
                         .waitForAndVerify()
 
                     device.sleep()
@@ -90,9 +88,9 @@
         testSpec.assertWm {
             this.hasNoVisibleAppWindow()
                     .then()
-                    .isAppWindowOnTop(FlickerComponentName.SNAPSHOT, isOptional = true)
+                    .isAppWindowOnTop(ComponentMatcher.SNAPSHOT, isOptional = true)
                     .then()
-                    .isAppWindowOnTop(showWhenLockedApp.component)
+                    .isAppWindowOnTop(showWhenLockedApp)
         }
     }
 
@@ -100,11 +98,11 @@
     @Postsubmit
     fun showWhenLockedAppLayerBecomesVisible() {
         testSpec.assertLayers {
-            this.isInvisible(showWhenLockedApp.component)
+            this.isInvisible(showWhenLockedApp)
                     .then()
-                    .isVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
+                    .isVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
                     .then()
-                    .isVisible(showWhenLockedApp.component)
+                    .isVisible(showWhenLockedApp)
         }
     }
 
@@ -113,73 +111,11 @@
     @Test
     override fun entireScreenCovered() = super.entireScreenCovered()
 
-    /**
-     * Checks the position of the navigation bar at the start and end of the transition
-     *
-     * Differently from the normal usage of this assertion, check only the final state of the
-     * transition because the display is off at the start and the NavBar is never visible
-     */
-    @Postsubmit
-    @Test
-    override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerPositionEnd()
-
-    /**
-     * Checks the position of the status bar at the start and end of the transition
-     *
-     * Differently from the normal usage of this assertion, check only the final state of the
-     * transition because the display is off at the start and the NavBar is never visible
-     */
-    @Postsubmit
-    @Test
-    override fun statusBarLayerRotatesScales() = testSpec.statusBarLayerPositionEnd()
-
-    /** {@inheritDoc} */
-    @Postsubmit
-    @Test
-    override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
-
-    /** {@inheritDoc} */
-    @Postsubmit
-    @Test
-    override fun navBarWindowIsVisible() = super.navBarWindowIsVisible()
-
-    /** {@inheritDoc} */
-    @Postsubmit
-    @Test
-    override fun appLayerBecomesVisible() = super.appLayerBecomesVisible()
-
-    /** {@inheritDoc} */
-    @Postsubmit
-    @Test
-    override fun statusBarWindowIsVisible() = super.statusBarWindowIsVisible()
-
     /** {@inheritDoc} */
     @Postsubmit
     @Test
     override fun appWindowBecomesTopWindow() = super.appWindowBecomesTopWindow()
 
-    /** {@inheritDoc} */
-    @Postsubmit
-    @Test
-    override fun appWindowBecomesVisible() = super.appWindowBecomesVisible()
-
-    /** {@inheritDoc} */
-    @Postsubmit
-    @Test
-    override fun statusBarLayerIsVisible() = super.statusBarLayerIsVisible()
-
-    /** {@inheritDoc} */
-    @Postsubmit
-    @Test
-    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
-        super.visibleLayersShownMoreThanOneConsecutiveEntry()
-
-    /** {@inheritDoc} */
-    @Postsubmit
-    @Test
-    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
-        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
     companion object {
         /**
          * Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt
index 85024e7..1d8b0a6 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt
@@ -17,13 +17,14 @@
 package com.android.server.wm.flicker.launch
 
 import android.platform.test.annotations.FlakyTest
-import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.navBarLayerPositionEnd
-import com.android.server.wm.flicker.statusBarLayerPositionEnd
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.flicker.navBarLayerPositionAtEnd
+import com.android.server.wm.flicker.statusBarLayerPositionAtEnd
+import com.android.server.wm.traces.common.ComponentMatcher
+import org.junit.Assume
+import org.junit.Ignore
 import org.junit.Test
 
 /**
@@ -35,26 +36,25 @@
     /**
      * Defines the transition used to run the test
      */
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            super.transition(this)
-            setup {
-                eachRun {
-                    device.sleep()
-                    wmHelper.StateSyncBuilder()
-                        .withoutTopVisibleAppWindows()
-                        .waitForAndVerify()
-                }
-            }
-            teardown {
-                eachRun {
-                    testApp.exit(wmHelper)
-                }
-            }
-            transitions {
-                testApp.launchViaIntent(wmHelper)
+    override val transition: FlickerBuilder.() -> Unit = {
+        super.transition(this)
+        setup {
+            eachRun {
+                device.sleep()
+                wmHelper.StateSyncBuilder()
+                    .withoutTopVisibleAppWindows()
+                    .waitForAndVerify()
             }
         }
+        teardown {
+            eachRun {
+                testApp.exit(wmHelper)
+            }
+        }
+        transitions {
+            testApp.launchViaIntent(wmHelper)
+        }
+    }
 
     /**
      * Check that we go from no focus to focus on the [testApp]
@@ -77,17 +77,16 @@
         testSpec.assertWm {
             this.hasNoVisibleAppWindow()
                     .then()
-                    .isAppWindowOnTop(FlickerComponentName.SNAPSHOT, isOptional = true)
+                    .isAppWindowOnTop(ComponentMatcher.SNAPSHOT, isOptional = true)
                     .then()
-                    .isAppWindowOnTop(FlickerComponentName.SPLASH_SCREEN, isOptional = true)
+                    .isAppWindowOnTop(ComponentMatcher.SPLASH_SCREEN, isOptional = true)
                     .then()
-                    .isAppWindowOnTop(testApp.component)
+                    .isAppWindowOnTop(testApp)
         }
     }
 
     /**
-     * Checks that the screen is locked at the start of the transition ([colorFadComponent])
-     * layer is visible
+     * Checks that the screen is locked at the start of the transition
      */
     @Presubmit
     @Test
@@ -102,36 +101,58 @@
     @Test
     override fun appWindowBecomesVisible() = super.appWindowBecomesVisible()
 
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+    override fun navBarLayerPositionAtStartAndEnd() { }
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+    override fun statusBarLayerPositionAtStartAndEnd() { }
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+    override fun taskBarLayerIsVisibleAtStartAndEnd() { }
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+    override fun taskBarWindowIsAlwaysVisible() { }
+
     /**
-     * Checks the position of the navigation bar at the start and end of the transition
-     *
-     * Differently from the normal usage of this assertion, check only the final state of the
-     * transition because the display is off at the start and the NavBar is never visible
+     * Checks the position of the [ComponentMatcher.NAV_BAR] at the end of the transition
      */
     @Presubmit
     @Test
-    override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerPositionEnd()
+    open fun navBarLayerPositionAtEnd() {
+        Assume.assumeFalse(testSpec.isTablet)
+        testSpec.navBarLayerPositionAtEnd()
+    }
 
     /**
-     * Checks the position of the status bar at the start and end of the transition
-     *
-     * Differently from the normal usage of this assertion, check only the final state of the
-     * transition because the display is off at the start and the NavBar is never visible
+     * Checks the position of the [ComponentMatcher.STATUS_BAR] at the end of the transition
      */
-    @Postsubmit
+    @Presubmit
     @Test
-    override fun statusBarLayerRotatesScales() = testSpec.statusBarLayerPositionEnd()
+    fun statusBarLayerPositionAtEnd() = testSpec.statusBarLayerPositionAtEnd()
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+    override fun statusBarLayerIsVisibleAtStartAndEnd() { }
 
     /**
-     * Checks that the status bar layer is visible at the end of the trace
+     * Checks that the [ComponentMatcher.STATUS_BAR] layer is visible at the end of the trace
      *
      * It is not possible to check at the start because the screen is off
      */
     @Presubmit
     @Test
-    override fun statusBarLayerIsVisible() {
+    fun statusBarLayerIsVisibleAtEnd() {
         testSpec.assertLayersEnd {
-            this.isVisible(FlickerComponentName.STATUS_BAR)
+            this.isVisible(ComponentMatcher.STATUS_BAR)
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt
index 68e8e46..dbe5418 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt
@@ -42,8 +42,10 @@
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group1
 @Postsubmit
-open class OpenAppFromNotificationCold(testSpec: FlickerTestParameter) :
-    OpenAppFromNotificationWarm(testSpec) {
+open class OpenAppFromNotificationCold(
+    testSpec: FlickerTestParameter
+) : OpenAppFromNotificationWarm(testSpec) {
+    /** {@inheritDoc} */
     override val transition: FlickerBuilder.() -> Unit
         get() = {
             super.transition(this)
@@ -59,14 +61,91 @@
             }
         }
 
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerIsVisibleAtStartAndEnd() =
+        super.statusBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun entireScreenCovered() = super.entireScreenCovered()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun notificationAppWindowVisibleAtEnd() = super.notificationAppWindowVisibleAtEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun notificationAppWindowOnTopAtEnd() = super.notificationAppWindowOnTopAtEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun notificationAppLayerVisibleAtEnd() = super.notificationAppLayerVisibleAtEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun appWindowBecomesTopWindow() = super.appWindowBecomesTopWindow()
+
+    /** {@inheritDoc} */
     @Test
     @Postsubmit
     override fun appWindowBecomesVisible() = appWindowBecomesVisible_coldStart()
 
+    /** {@inheritDoc} */
     @Test
     @Postsubmit
     override fun appLayerBecomesVisible() = appLayerBecomesVisible_coldStart()
 
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun appWindowIsTopWindowAtEnd() =
+        super.appWindowIsTopWindowAtEnd()
+
     companion object {
         /**
          * Creates the test configurations.
@@ -78,7 +157,7 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                    .getConfigNonRotationTests(repetitions = 3)
+                .getConfigNonRotationTests(repetitions = 3)
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt
index 6d59111..6e3e74d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt
@@ -52,12 +52,14 @@
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group1
 @Postsubmit
-open class OpenAppFromNotificationWarm(testSpec: FlickerTestParameter) :
-    OpenAppTransition(testSpec) {
+open class OpenAppFromNotificationWarm(
+    testSpec: FlickerTestParameter
+) : OpenAppTransition(testSpec) {
     override val testApp: NotificationAppHelper = NotificationAppHelper(instrumentation)
 
     open val openingNotificationsFromLockScreen = false
 
+    /** {@inheritDoc} */
     override val transition: FlickerBuilder.() -> Unit
         get() = {
             setup {
@@ -68,7 +70,7 @@
                 eachRun {
                     testApp.launchViaIntent(wmHelper)
                     wmHelper.StateSyncBuilder()
-                        .withFullScreenApp(testApp.component)
+                        .withFullScreenApp(testApp)
                         .waitForAndVerify()
                     testApp.postNotification(wmHelper)
                     tapl.goHome()
@@ -83,11 +85,14 @@
                 var endY = 3 * device.displayHeight / 4
                 var steps = 25
                 if (openingNotificationsFromLockScreen) {
-                    val wm = instrumentation.context.getSystemService(WindowManager::class.java)
+                    val wm: WindowManager =
+                        instrumentation.context.getSystemService(WindowManager::class.java)
+                            ?: error("Unable to connect to WindowManager service")
                     val metricInsets = wm.currentWindowMetrics.windowInsets
                     val insets = metricInsets.getInsetsIgnoringVisibility(
-                            WindowInsets.Type.statusBars()
-                                    or WindowInsets.Type.displayCutout())
+                        WindowInsets.Type.statusBars()
+                            or WindowInsets.Type.displayCutout()
+                    )
 
                     startY = insets.top + 100
                     endY = device.displayHeight / 2
@@ -101,14 +106,17 @@
                 instrumentation.uiAutomation.syncInputTransactions()
 
                 // Launch the activity by clicking the notification
-                val notification = device.wait(Until.findObject(
-                        By.text("Flicker Test Notification")), 2000L)
+                val notification = device.wait(
+                    Until.findObject(
+                        By.text("Flicker Test Notification")
+                    ), 2000L
+                )
                 notification?.click() ?: error("Notification not found")
                 instrumentation.uiAutomation.syncInputTransactions()
 
                 // Wait for the app to launch
                 wmHelper.StateSyncBuilder()
-                    .withFullScreenApp(testApp.component)
+                    .withFullScreenApp(testApp)
                     .waitForAndVerify()
             }
 
@@ -119,52 +127,92 @@
             }
         }
 
-    @Test
+    /** {@inheritDoc} */
     @Postsubmit
-    override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
+    @Test
+    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
 
-    @Test
+    /** {@inheritDoc} */
     @Postsubmit
-    override fun statusBarLayerIsVisible() = super.statusBarLayerIsVisible()
+    @Test
+    override fun statusBarLayerIsVisibleAtStartAndEnd() =
+        super.statusBarLayerIsVisibleAtStartAndEnd()
 
-    @Test
+    /** {@inheritDoc} */
     @Postsubmit
-    override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
+    @Test
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
 
-    @Test
+    /** {@inheritDoc} */
     @Postsubmit
+    @Test
     override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
-            super.visibleLayersShownMoreThanOneConsecutiveEntry()
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
 
-    @Test
+    /** {@inheritDoc} */
     @Postsubmit
+    @Test
     override fun appWindowBecomesVisible() = appWindowBecomesVisible_warmStart()
 
-    @Test
+    /** {@inheritDoc} */
     @Postsubmit
+    @Test
     override fun appLayerBecomesVisible() = appLayerBecomesVisible_warmStart()
 
-    @Test
+    /** {@inheritDoc} */
     @Postsubmit
-    fun notificationAppWindowVisibleAtEnd() {
+    @Test
+    override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun entireScreenCovered() = super.entireScreenCovered()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun appWindowIsTopWindowAtEnd() =
+        super.appWindowIsTopWindowAtEnd()
+
+    @Postsubmit
+    @Test
+    open fun notificationAppWindowVisibleAtEnd() {
         testSpec.assertWmEnd {
-            this.isAppWindowVisible(testApp.component)
+            this.isAppWindowVisible(testApp)
         }
     }
 
-    @Test
     @Postsubmit
-    fun notificationAppWindowOnTopAtEnd() {
+    @Test
+    open fun notificationAppWindowOnTopAtEnd() {
         testSpec.assertWmEnd {
-            this.isAppWindowOnTop(testApp.component)
+            this.isAppWindowOnTop(testApp)
         }
     }
 
-    @Test
     @Postsubmit
-    fun notificationAppLayerVisibleAtEnd() {
+    @Test
+    open fun notificationAppLayerVisibleAtEnd() {
         testSpec.assertLayersEnd {
-            this.isVisible(testApp.component)
+            this.isVisible(testApp)
         }
     }
 
@@ -178,37 +226,11 @@
 
     @FlakyTest(bugId = 229738092)
     @Test
-    fun appWindowBecomesTopWindow_ShellTransit() {
+    open fun appWindowBecomesTopWindow_ShellTransit() {
         Assume.assumeTrue(isShellTransitionsEnabled)
         super.appWindowBecomesTopWindow()
     }
 
-    /** {@inheritDoc} */
-    @Postsubmit
-    @Test
-    override fun statusBarWindowIsVisible() = super.statusBarWindowIsVisible()
-
-    /** {@inheritDoc} */
-    @Postsubmit
-    @Test
-    override fun entireScreenCovered() = super.entireScreenCovered()
-
-    /** {@inheritDoc} */
-    @Postsubmit
-    @Test
-    override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
-
-    /** {@inheritDoc} */
-    @Postsubmit
-    @Test
-    override fun navBarWindowIsVisible() = super.navBarWindowIsVisible()
-
-    /** {@inheritDoc} */
-    @Postsubmit
-    @Test
-    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
-        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
     companion object {
         /**
          * Creates the test configurations.
@@ -220,7 +242,7 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                    .getConfigNonRotationTests(repetitions = 3)
+                .getConfigNonRotationTests(repetitions = 3)
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
index c7883d65..34c0b23 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
@@ -25,9 +25,7 @@
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group1
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import com.android.server.wm.flicker.helpers.setRotation
-import org.junit.Assume
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -58,8 +56,9 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group1
-open class OpenAppFromOverviewTest(testSpec: FlickerTestParameter) :
-    OpenAppFromLauncherTransition(testSpec) {
+open class OpenAppFromOverviewTest(
+    testSpec: FlickerTestParameter
+) : OpenAppFromLauncherTransition(testSpec) {
 
     /**
      * Defines the transition used to run the test
@@ -77,8 +76,12 @@
                     wmHelper.StateSyncBuilder()
                         .withHomeActivityVisible()
                         .waitForAndVerify()
-                    // Launcher is always ROTATION_0
-                    tapl.setExpectedRotation(Surface.ROTATION_0)
+                    // By default, launcher doesn't rotate on phones, but rotates on tablets
+                    if (testSpec.isTablet) {
+                        tapl.setExpectedRotation(testSpec.startRotation)
+                    } else {
+                        tapl.setExpectedRotation(Surface.ROTATION_0)
+                    }
                     tapl.workspace.switchToOverview()
                     wmHelper.StateSyncBuilder()
                         .withRecentsActivityVisible()
@@ -89,17 +92,12 @@
             transitions {
                 tapl.overview.currentTask.open()
                 wmHelper.StateSyncBuilder()
-                    .withFullScreenApp(testApp.component)
+                    .withFullScreenApp(testApp)
                     .waitForAndVerify()
             }
         }
 
     /** {@inheritDoc} */
-    @FlakyTest(bugId = 206753786)
-    @Test
-    override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
-
-    /** {@inheritDoc} */
     @Presubmit
     @Test
     override fun appLayerReplacesLauncher() = super.appLayerReplacesLauncher()
@@ -107,17 +105,7 @@
     /** {@inheritDoc} */
     @FlakyTest
     @Test
-    override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
-
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
-
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun navBarWindowIsVisible() = super.navBarWindowIsVisible()
+    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
 
     /** {@inheritDoc} */
     @Presubmit
@@ -129,41 +117,6 @@
     @Test
     override fun appWindowBecomesVisible() = super.appWindowBecomesVisible_warmStart()
 
-    /** {@inheritDoc} */
-    @FlakyTest(bugId = 229735718)
-    @Test
-    override fun entireScreenCovered() = super.entireScreenCovered()
-
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun appWindowReplacesLauncherAsTopWindow() {
-        Assume.assumeFalse(isShellTransitionsEnabled)
-        super.appWindowReplacesLauncherAsTopWindow()
-    }
-
-    @FlakyTest(bugId = 229738092)
-    @Test
-    fun appWindowReplacesLauncherAsTopWindow_ShellTransit() {
-        Assume.assumeTrue(isShellTransitionsEnabled)
-        super.appWindowReplacesLauncherAsTopWindow()
-    }
-
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun appWindowBecomesTopWindow() {
-        Assume.assumeFalse(isShellTransitionsEnabled)
-        super.appWindowBecomesTopWindow()
-    }
-
-    @FlakyTest(bugId = 229738092)
-    @Test
-    fun appWindowBecomesTopWindow_ShellTransit() {
-        Assume.assumeTrue(isShellTransitionsEnabled)
-        super.appWindowBecomesTopWindow()
-    }
-
     companion object {
         /**
          * Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
index 0452339..1ad5426 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
@@ -27,10 +27,11 @@
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group1
 import com.android.server.wm.flicker.helpers.NonResizeableAppHelper
-import com.android.server.wm.flicker.helpers.WindowUtils
-import com.android.server.wm.flicker.navBarLayerPositionEnd
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.flicker.statusBarLayerPositionAtEnd
+import com.android.server.wm.traces.common.ComponentMatcher
+import org.junit.Assume
 import org.junit.FixMethodOrder
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.MethodSorters
@@ -65,16 +66,16 @@
     override val testApp = NonResizeableAppHelper(instrumentation)
 
     /**
-     * Checks that the nav bar layer starts invisible, becomes visible during unlocking animation
-     * and remains visible at the end
+     * Checks that the [ComponentMatcher.NAV_BAR] layer starts invisible, becomes visible during
+     * unlocking animation and remains visible at the end
      */
     @FlakyTest(bugId = 227083463)
     @Test
     fun navBarLayerVisibilityChanges() {
         testSpec.assertLayers {
-            this.isInvisible(FlickerComponentName.NAV_BAR)
+            this.isInvisible(ComponentMatcher.NAV_BAR)
                 .then()
-                .isVisible(FlickerComponentName.NAV_BAR)
+                .isVisible(ComponentMatcher.NAV_BAR)
         }
     }
 
@@ -85,63 +86,94 @@
     @Test
     fun appWindowBecomesVisibleAtEnd() {
         testSpec.assertWmEnd {
-            this.isAppWindowVisible(testApp.component)
+            this.isAppWindowVisible(testApp)
         }
     }
 
     /**
-     * Checks that the nav bar starts the transition invisible, then becomes visible during
-     * the unlocking animation and remains visible at the end of the transition
+     * Checks that the [ComponentMatcher.NAV_BAR] starts the transition invisible, then becomes
+     * visible during the unlocking animation and remains visible at the end of the transition
      */
     @Presubmit
     @Test
     fun navBarWindowsVisibilityChanges() {
+        Assume.assumeFalse(testSpec.isTablet)
         testSpec.assertWm {
-            this.isNonAppWindowInvisible(FlickerComponentName.NAV_BAR)
+            this.isNonAppWindowInvisible(ComponentMatcher.NAV_BAR)
                 .then()
-                .isAboveAppWindowVisible(FlickerComponentName.NAV_BAR)
+                .isAboveAppWindowVisible(ComponentMatcher.NAV_BAR)
         }
     }
 
     /**
-     * Checks that the status bar layer is visible at the end of the trace
+     * Checks that the [ComponentMatcher.TASK_BAR] starts the transition invisible, then becomes
+     * visible during the unlocking animation and remains visible at the end of the transition
+     */
+    @Presubmit
+    @Test
+    fun taskBarLayerIsVisibleAtEnd() {
+        Assume.assumeTrue(testSpec.isTablet)
+        testSpec.assertLayersEnd {
+            this.isVisible(ComponentMatcher.TASK_BAR)
+        }
+    }
+
+    /**
+     * Checks that the [ComponentMatcher.STATUS_BAR] layer is visible at the end of the trace
      *
      * It is not possible to check at the start because the screen is off
      */
     @Presubmit
     @Test
-    override fun statusBarLayerIsVisible() {
+    override fun statusBarLayerIsVisibleAtStartAndEnd() {
         testSpec.assertLayersEnd {
-            this.isVisible(FlickerComponentName.STATUS_BAR)
+            this.isVisible(ComponentMatcher.STATUS_BAR)
         }
     }
 
     /** {@inheritDoc} */
-    @FlakyTest(bugId = 206753786)
     @Test
-    override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
+    @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+    override fun taskBarLayerIsVisibleAtStartAndEnd() { }
 
     /** {@inheritDoc} */
-    @FlakyTest(bugId = 206753786)
     @Test
-    fun statusBarLayerPositionAtEnd() {
-        testSpec.assertLayersEnd {
-            val display = this.entry.displays.minByOrNull { it.id }
-                ?: error("There is no display!")
-            this.visibleRegion(FlickerComponentName.STATUS_BAR)
-                .coversExactly(WindowUtils.getStatusBarPosition(display))
-        }
-    }
+    @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+    override fun navBarLayerIsVisibleAtStartAndEnd() { }
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+    override fun taskBarWindowIsAlwaysVisible() { }
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+    override fun navBarWindowIsAlwaysVisible() { }
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+    override fun statusBarWindowIsAlwaysVisible() { }
 
     /**
-     * Checks the position of the navigation bar at the start and end of the transition
-     *
-     * Differently from the normal usage of this assertion, check only the final state of the
-     * transition because the display is off at the start and the NavBar is never visible
+     * Checks the position of the [ComponentMatcher.STATUS_BAR] at the end of the
+     * transition
+     */
+    @Presubmit
+    @Test
+    fun statusBarLayerPositionEnd() = testSpec.statusBarLayerPositionAtEnd()
+
+    /**
+     * Checks the [ComponentMatcher.NAV_BAR] is visible at the end of the transition
      */
     @Postsubmit
     @Test
-    override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerPositionEnd()
+    fun navBarLayerIsVisibleAtEnd() {
+        testSpec.assertLayersEnd {
+            this.isVisible(ComponentMatcher.NAV_BAR)
+        }
+    }
 
     /** {@inheritDoc} */
     @FlakyTest
@@ -150,6 +182,22 @@
             super.visibleLayersShownMoreThanOneConsecutiveEntry()
 
     /** {@inheritDoc} */
+    @Presubmit
+    @Test
+    override fun appLayerBecomesVisible() {
+        Assume.assumeFalse(testSpec.isTablet)
+        super.appLayerBecomesVisible()
+    }
+
+    /** {@inheritDoc} */
+    @FlakyTest(bugId = 227143265)
+    @Test
+    fun appLayerBecomesVisibleTablet() {
+        Assume.assumeTrue(testSpec.isTablet)
+        super.appLayerBecomesVisible()
+    }
+
+    /** {@inheritDoc} */
     @FlakyTest
     @Test
     override fun entireScreenCovered() = super.entireScreenCovered()
@@ -159,6 +207,11 @@
     override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
             super.visibleWindowsShownMoreThanOneConsecutiveEntry()
 
+    @FlakyTest(bugId = 227143265)
+    @Test
+    override fun appWindowBecomesTopWindow() =
+        super.appWindowBecomesTopWindow()
+
     companion object {
         /**
          * Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
index 9c97970..5d2b567 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
@@ -16,39 +16,25 @@
 
 package com.android.server.wm.flicker.launch
 
-import android.app.Instrumentation
 import android.platform.test.annotations.Presubmit
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
 import com.android.server.wm.flicker.helpers.StandardAppHelper
 import com.android.server.wm.flicker.helpers.setRotation
 import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
 import org.junit.Test
 
 /**
  * Base class for app launch tests
  */
-abstract class OpenAppTransition(protected val testSpec: FlickerTestParameter) {
-    protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+abstract class OpenAppTransition(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
     protected open val testApp: StandardAppHelper = SimpleAppHelper(instrumentation)
-    protected val tapl = LauncherInstrumentation()
 
-    /**
-     * Defines the transition used to run the test
-     */
-    protected open val transition: FlickerBuilder.() -> Unit = {
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
         setup {
             test {
                 tapl.setExpectedRotation(testSpec.startRotation)
@@ -64,129 +50,43 @@
     }
 
     /**
-     * Entry point for the test runner. It will use this method to initialize and cache
-     * flicker executions
+     * Checks that the [testApp] layer doesn't exist or is invisible at the start of the
+     * transition, but is created and/or becomes visible during the transition.
      */
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            transition()
-        }
+    @Presubmit
+    @Test
+    open fun appLayerBecomesVisible() {
+        appLayerBecomesVisible_coldStart()
     }
 
-    /**
-     * Checks that the navigation bar window is visible during the whole transition
-     */
-    open fun navBarWindowIsVisible() {
-        testSpec.navBarWindowIsVisible()
-    }
-
-    /**
-     * Checks that the navigation bar layer is visible at the start and end of the trace
-     */
-    open fun navBarLayerIsVisible() {
-        testSpec.navBarLayerIsVisible()
-    }
-
-    /**
-     * Checks the position of the navigation bar at the start and end of the transition
-     */
-    @Presubmit
-    @Test
-    open fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
-    /**
-     * Checks that the status bar window is visible during the whole transition
-     */
-    @Presubmit
-    @Test
-    open fun statusBarWindowIsVisible() {
-        testSpec.statusBarWindowIsVisible()
-    }
-
-    /**
-     * Checks that the status bar layer is visible at the start and end of the trace
-     */
-    @Presubmit
-    @Test
-    open fun statusBarLayerIsVisible() {
-        testSpec.statusBarLayerIsVisible()
-    }
-
-    /**
-     * Checks the position of the status bar at the start and end of the transition
-     */
-    @Presubmit
-    @Test
-    open fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
-    /**
-     * Checks that all windows that are visible on the trace, are visible for at least 2
-     * consecutive entries.
-     */
-    @Presubmit
-    @Test
-    open fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
-        testSpec.assertWm {
-            this.visibleWindowsShownMoreThanOneConsecutiveEntry()
-        }
-    }
-
-    /**
-     * Checks that all layers that are visible on the trace, are visible for at least 2
-     * consecutive entries.
-     */
-    @Presubmit
-    @Test
-    open fun visibleLayersShownMoreThanOneConsecutiveEntry() {
-        testSpec.assertLayers {
-            this.visibleLayersShownMoreThanOneConsecutiveEntry()
-        }
-    }
-
-    /**
-     * Checks that all parts of the screen are covered during the transition
-     */
-    @Presubmit
-    @Test
-    open fun entireScreenCovered() = testSpec.entireScreenCovered()
-
-    /**
-     * Checks that the app layer doesn't exist or is invisible at the start of the transition, but
-     * is created and/or becomes visible during the transition.
-     */
-    @Presubmit
-    @Test
-    open fun appLayerBecomesVisible() = appLayerBecomesVisible_coldStart()
-
     protected fun appLayerBecomesVisible_coldStart() {
         testSpec.assertLayers {
-            this.notContains(testApp.component)
-                    .then()
-                    .isInvisible(testApp.component, isOptional = true)
-                    .then()
-                    .isVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
-                    .then()
-                    .isVisible(FlickerComponentName.SPLASH_SCREEN, isOptional = true)
-                    .then()
-                    .isVisible(testApp.component)
+            this.notContains(testApp)
+                .then()
+                .isInvisible(testApp, isOptional = true)
+                .then()
+                .isVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
+                .then()
+                .isVisible(ComponentMatcher.SPLASH_SCREEN, isOptional = true)
+                .then()
+                .isVisible(testApp)
         }
     }
 
     protected fun appLayerBecomesVisible_warmStart() {
         testSpec.assertLayers {
-            this.isInvisible(testApp.component)
-                    .then()
-                    .isVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
-                    .then()
-                    .isVisible(FlickerComponentName.SPLASH_SCREEN, isOptional = true)
-                    .then()
-                    .isVisible(testApp.component)
+            this.isInvisible(testApp)
+                .then()
+                .isVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
+                .then()
+                .isVisible(ComponentMatcher.SPLASH_SCREEN, isOptional = true)
+                .then()
+                .isVisible(testApp)
         }
     }
 
     /**
-     * Checks that the app window doesn't exist at the start of the transition, that it is
+     * Checks that the [testApp] window doesn't exist at the start of the transition, that it is
      * created (invisible - optional) and becomes visible during the transition
      *
      * The `isAppWindowInvisible` step is optional because we log once per frame, upon logging,
@@ -198,23 +98,23 @@
 
     protected fun appWindowBecomesVisible_coldStart() {
         testSpec.assertWm {
-            this.notContains(testApp.component)
-                    .then()
-                    .isAppWindowInvisible(testApp.component, isOptional = true)
-                    .then()
-                    .isAppWindowVisible(testApp.component)
+            this.notContains(testApp)
+                .then()
+                .isAppWindowInvisible(testApp, isOptional = true)
+                .then()
+                .isAppWindowVisible(testApp)
         }
     }
 
     protected fun appWindowBecomesVisible_warmStart() {
         testSpec.assertWm {
-            this.isAppWindowInvisible(testApp.component)
-                    .then()
-                    .isAppWindowVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
-                    .then()
-                    .isAppWindowVisible(FlickerComponentName.SPLASH_SCREEN, isOptional = true)
-                    .then()
-                    .isAppWindowVisible(testApp.component)
+            this.isAppWindowInvisible(testApp)
+                .then()
+                .isAppWindowVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
+                .then()
+                .isAppWindowVisible(ComponentMatcher.SPLASH_SCREEN, isOptional = true)
+                .then()
+                .isAppWindowVisible(testApp)
         }
     }
 
@@ -226,13 +126,13 @@
     @Test
     open fun appWindowBecomesTopWindow() {
         testSpec.assertWm {
-            this.isAppWindowNotOnTop(testApp.component)
-                    .then()
-                    .isAppWindowOnTop(
-                        testApp.component
-                            .or(FlickerComponentName.SNAPSHOT)
-                            .or(FlickerComponentName.SPLASH_SCREEN)
-                    )
+            this.isAppWindowNotOnTop(testApp)
+                .then()
+                .isAppWindowOnTop(
+                    testApp
+                        .or(ComponentMatcher.SNAPSHOT)
+                        .or(ComponentMatcher.SPLASH_SCREEN)
+                )
         }
     }
 
@@ -244,7 +144,7 @@
     @Test
     open fun appWindowIsTopWindowAtEnd() {
         testSpec.assertWmEnd {
-            this.isAppWindowOnTop(testApp.component)
+            this.isAppWindowOnTop(testApp)
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
index 88e2b2d..bc5ab7d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
@@ -87,24 +87,7 @@
     /** {@inheritDoc} */
     @FlakyTest(bugId = 206753786)
     @Test
-    override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
-
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun appWindowReplacesLauncherAsTopWindow() =
-            super.appWindowReplacesLauncherAsTopWindow()
-
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
-            super.visibleLayersShownMoreThanOneConsecutiveEntry()
-
-    /** {@inheritDoc} */
-    @FlakyTest
-    @Test
-    override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
+    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
 
     /** {@inheritDoc} */
     @Presubmit
@@ -114,16 +97,6 @@
     /** {@inheritDoc} */
     @Presubmit
     @Test
-    override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
-
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun navBarWindowIsVisible() = super.navBarWindowIsVisible()
-
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
     override fun appLayerBecomesVisible() = super.appLayerBecomesVisible_warmStart()
 
     /** {@inheritDoc} */
@@ -131,10 +104,6 @@
     @Test
     override fun appWindowBecomesVisible() = super.appWindowBecomesVisible_warmStart()
 
-    @FlakyTest(bugId = 229735718)
-    @Test
-    override fun entireScreenCovered() = super.entireScreenCovered()
-
     companion object {
         /**
          * Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
index 99df1f4b..4beb5d0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
@@ -20,26 +20,20 @@
 import android.app.WallpaperManager
 import android.platform.test.annotations.Postsubmit
 import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group4
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
 import com.android.server.wm.flicker.helpers.NewTasksAppHelper
 import com.android.server.wm.flicker.helpers.WindowUtils
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarWindowIsVisible
 import com.android.server.wm.flicker.testapp.ActivityOptions.LAUNCH_NEW_TASK_ACTIVITY_COMPONENT_NAME
 import com.android.server.wm.flicker.testapp.ActivityOptions.SIMPLE_ACTIVITY_AUTO_FOCUS_COMPONENT_NAME
-import com.android.server.wm.traces.common.FlickerComponentName
-import com.android.server.wm.traces.common.FlickerComponentName.Companion.SPLASH_SCREEN
-import com.android.server.wm.traces.common.FlickerComponentName.Companion.WALLPAPER_BBQ_WRAPPER
+import com.android.server.wm.traces.common.ComponentMatcher
+import com.android.server.wm.traces.common.ComponentMatcher.Companion.SPLASH_SCREEN
+import com.android.server.wm.traces.common.ComponentMatcher.Companion.WALLPAPER_BBQ_WRAPPER
+import com.android.server.wm.traces.common.IComponentMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 import org.junit.FixMethodOrder
 import org.junit.Test
@@ -62,83 +56,81 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group4
-class TaskTransitionTest(val testSpec: FlickerTestParameter) {
-    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
-    private val tapl = LauncherInstrumentation()
-    private val mTestApp: NewTasksAppHelper = NewTasksAppHelper(instrumentation)
-    private val mWallpaper by lazy {
+class TaskTransitionTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
+    private val testApp: NewTasksAppHelper = NewTasksAppHelper(instrumentation)
+    private val wallpaper by lazy {
         getWallpaperPackage(instrumentation) ?: error("Unable to obtain wallpaper")
     }
 
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            setup {
-                eachRun {
-                    mTestApp.launchViaIntent(wmHelper)
-                }
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            eachRun {
+                testApp.launchViaIntent(wmHelper)
             }
-            teardown {
-                test {
-                    mTestApp.exit(wmHelper)
-                }
+        }
+        teardown {
+            test {
+                testApp.exit(wmHelper)
             }
-            transitions {
-                mTestApp.openNewTask(device, wmHelper)
-                tapl.pressBack()
-                wmHelper.StateSyncBuilder()
-                    .withFullScreenApp(mTestApp.component)
-                    .waitForAndVerify()
-            }
+        }
+        transitions {
+            testApp.openNewTask(device, wmHelper)
+            tapl.pressBack()
+            wmHelper.StateSyncBuilder()
+                .withFullScreenApp(testApp)
+                .waitForAndVerify()
         }
     }
 
     /**
-     * Checks that the wallpaper window is never visible when performing task transitions.
+     * Checks that the [wallpaper] window is never visible when performing task transitions.
      * A solid color background should be shown instead.
      */
     @Postsubmit
     @Test
     fun wallpaperWindowIsNeverVisible() {
         testSpec.assertWm {
-            this.isNonAppWindowInvisible(mWallpaper)
+            this.isNonAppWindowInvisible(wallpaper)
         }
     }
 
     /**
-     * Checks that the wallpaper layer is never visible when performing task transitions.
+     * Checks that the [wallpaper] layer is never visible when performing task transitions.
      * A solid color background should be shown instead.
      */
     @Postsubmit
     @Test
     fun wallpaperLayerIsNeverVisible() {
         testSpec.assertLayers {
-            this.isInvisible(mWallpaper)
+            this.isInvisible(wallpaper)
             this.isInvisible(WALLPAPER_BBQ_WRAPPER)
         }
     }
 
     /**
-     * Check that the launcher window is never visible when performing task transitions.
+     * Check that the [ComponentMatcher.LAUNCHER] window is never visible when performing task
+     * transitions.
      * A solid color background should be shown above it.
      */
     @Postsubmit
     @Test
     fun launcherWindowIsNeverVisible() {
         testSpec.assertWm {
-            this.isAppWindowInvisible(FlickerComponentName.LAUNCHER)
+            this.isAppWindowInvisible(ComponentMatcher.LAUNCHER)
         }
     }
 
     /**
-     * Checks that the launcher layer is never visible when performing task transitions.
+     * Checks that the [ComponentMatcher.LAUNCHER] layer is never visible when performing task
+     * transitions.
      * A solid color background should be shown above it.
      */
     @Postsubmit
     @Test
     fun launcherLayerIsNeverVisible() {
         testSpec.assertLayers {
-            this.isInvisible(FlickerComponentName.LAUNCHER)
+            this.isInvisible(ComponentMatcher.LAUNCHER)
         }
     }
 
@@ -148,13 +140,13 @@
     @Postsubmit
     @Test
     fun colorLayerIsVisibleDuringTransition() {
-        val bgColorLayer = FlickerComponentName("", "colorBackgroundLayer")
+        val bgColorLayer = ComponentMatcher("", "colorBackgroundLayer")
         val displayBounds = WindowUtils.getDisplayBounds(testSpec.startRotation)
 
         testSpec.assertLayers {
             this.invoke("LAUNCH_NEW_TASK_ACTIVITY coversExactly displayBounds") {
-                    it.visibleRegion(LAUNCH_NEW_TASK_ACTIVITY).coversExactly(displayBounds)
-                }
+                it.visibleRegion(LAUNCH_NEW_TASK_ACTIVITY).coversExactly(displayBounds)
+            }
                 .isInvisible(bgColorLayer)
                 .then()
                 // Transitioning
@@ -186,58 +178,82 @@
     fun newTaskOpensOnTopAndThenCloses() {
         testSpec.assertWm {
             this.isAppWindowOnTop(LAUNCH_NEW_TASK_ACTIVITY)
-                    .then()
-                    .isAppWindowOnTop(SPLASH_SCREEN, isOptional = true)
-                    .then()
-                    .isAppWindowOnTop(SIMPLE_ACTIVITY)
-                    .then()
-                    .isAppWindowOnTop(SPLASH_SCREEN, isOptional = true)
-                    .then()
-                    .isAppWindowOnTop(LAUNCH_NEW_TASK_ACTIVITY)
+                .then()
+                .isAppWindowOnTop(SPLASH_SCREEN, isOptional = true)
+                .then()
+                .isAppWindowOnTop(SIMPLE_ACTIVITY)
+                .then()
+                .isAppWindowOnTop(SPLASH_SCREEN, isOptional = true)
+                .then()
+                .isAppWindowOnTop(LAUNCH_NEW_TASK_ACTIVITY)
         }
     }
 
-    /**
-     * Checks that all parts of the screen are covered at the start and end of the transition
-     */
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
-    fun entireScreenCovered() = testSpec.entireScreenCovered()
+    override fun entireScreenCovered() = super.entireScreenCovered()
 
-    /**
-     * Checks that the navbar window is visible throughout the transition
-     */
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
+    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
 
-    /**
-     * Checks that the navbar layer is visible throughout the transition
-     */
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
-    fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
+    override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
 
-    /**
-     * Checks that the status bar window is visible throughout the transition
-     */
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
+    override fun statusBarLayerIsVisibleAtStartAndEnd() =
+        super.statusBarLayerIsVisibleAtStartAndEnd()
 
-    /**
-     * Checks that the status bar layer is visible throughout the transition
-     */
+    /** {@inheritDoc} */
     @Postsubmit
     @Test
-    fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible()
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+    /** {@inheritDoc} */
+    @Postsubmit
+    @Test
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
 
     companion object {
         private val LAUNCH_NEW_TASK_ACTIVITY =
-                LAUNCH_NEW_TASK_ACTIVITY_COMPONENT_NAME.toFlickerComponent()
+            LAUNCH_NEW_TASK_ACTIVITY_COMPONENT_NAME.toFlickerComponent()
         private val SIMPLE_ACTIVITY = SIMPLE_ACTIVITY_AUTO_FOCUS_COMPONENT_NAME.toFlickerComponent()
 
-        private fun getWallpaperPackage(instrumentation: Instrumentation): FlickerComponentName? {
+        private fun getWallpaperPackage(instrumentation: Instrumentation): IComponentMatcher? {
             val wallpaperManager = WallpaperManager.getInstance(instrumentation.targetContext)
 
             return wallpaperManager.wallpaperInfo?.component?.toFlickerComponent()
@@ -247,7 +263,7 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                    .getConfigNonRotationTests(repetitions = 3)
+                .getConfigNonRotationTests(repetitions = 3)
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
index 1a71284..45b7be5 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
@@ -16,15 +16,12 @@
 
 package com.android.server.wm.flicker.quickswitch
 
-import android.app.Instrumentation
-import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.platform.test.annotations.RequiresDevice
 import android.view.Surface
 import android.view.WindowManagerPolicyConstants
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
@@ -33,12 +30,7 @@
 import com.android.server.wm.flicker.helpers.NonResizeableAppHelper
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
 import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
 import com.android.server.wm.traces.common.Rect
 import org.junit.Assume
 import org.junit.Before
@@ -64,10 +56,9 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group1
-open class QuickSwitchBetweenTwoAppsBackTest(private val testSpec: FlickerTestParameter) {
-    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
-    private val tapl = LauncherInstrumentation()
-
+open class QuickSwitchBetweenTwoAppsBackTest(
+    testSpec: FlickerTestParameter
+) : BaseTest(testSpec) {
     private val testApp1 = SimpleAppHelper(instrumentation)
     private val testApp2 = NonResizeableAppHelper(instrumentation)
 
@@ -76,32 +67,31 @@
         Assume.assumeFalse(isShellTransitionsEnabled)
     }
 
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            setup {
-                test {
-                    tapl.setExpectedRotation(testSpec.startRotation)
-                }
-                eachRun {
-                    testApp1.launchViaIntent(wmHelper)
-                    testApp2.launchViaIntent(wmHelper)
-                    startDisplayBounds = wmHelper.currentState.layerState
-                        .physicalDisplayBounds ?: error("Display not found")
-                }
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            test {
+                tapl.setExpectedRotation(testSpec.startRotation)
             }
-            transitions {
-                tapl.launchedAppState.quickSwitchToPreviousApp()
-                wmHelper.StateSyncBuilder()
-                    .withNavBarStatusBarVisible()
-                    .waitForAndVerify()
+            eachRun {
+                testApp1.launchViaIntent(wmHelper)
+                testApp2.launchViaIntent(wmHelper)
+                startDisplayBounds = wmHelper.currentState.layerState
+                    .physicalDisplayBounds ?: error("Display not found")
             }
+        }
+        transitions {
+            tapl.launchedAppState.quickSwitchToPreviousApp()
+            wmHelper.StateSyncBuilder()
+                .withNavOrTaskBarVisible()
+                .withStatusBarVisible()
+                .waitForAndVerify()
+        }
 
-            teardown {
-                test {
-                    testApp1.exit(wmHelper)
-                    testApp2.exit(wmHelper)
-                }
+        teardown {
+            test {
+                testApp1.exit(wmHelper)
+                testApp2.exit(wmHelper)
             }
         }
     }
@@ -112,9 +102,9 @@
      */
     @Presubmit
     @Test
-    fun startsWithApp2WindowsCoverFullScreen() {
+    open fun startsWithApp2WindowsCoverFullScreen() {
         testSpec.assertWmStart {
-            this.frameRegion(testApp2.component).coversExactly(startDisplayBounds)
+            this.visibleRegion(testApp2).coversExactly(startDisplayBounds)
         }
     }
 
@@ -124,9 +114,9 @@
      */
     @Presubmit
     @Test
-    fun startsWithApp2LayersCoverFullScreen() {
+    open fun startsWithApp2LayersCoverFullScreen() {
         testSpec.assertLayersStart {
-            this.visibleRegion(testApp2.component).coversExactly(startDisplayBounds)
+            this.visibleRegion(testApp2).coversExactly(startDisplayBounds)
         }
     }
 
@@ -135,103 +125,103 @@
      */
     @Presubmit
     @Test
-    fun startsWithApp2WindowBeingOnTop() {
+    open fun startsWithApp2WindowBeingOnTop() {
         testSpec.assertWmStart {
-            this.isAppWindowOnTop(testApp2.component)
+            this.isAppWindowOnTop(testApp2)
         }
     }
 
     /**
-     * Checks that [testApp1] windows fill the entire screen (i.e. is "fullscreen") at the end of the
-     * transition once we have fully quick switched from [testApp2] back to the [testApp1].
+     * Checks that [testApp1] windows fill the entire screen (i.e. is "fullscreen") at the end of
+     * the transition once we have fully quick switched from [testApp2] back to the [testApp1].
      */
     @Presubmit
     @Test
-    fun endsWithApp1WindowsCoveringFullScreen() {
+    open fun endsWithApp1WindowsCoveringFullScreen() {
         testSpec.assertWmEnd {
-            this.frameRegion(testApp1.component).coversExactly(startDisplayBounds)
+            this.visibleRegion(testApp1).coversExactly(startDisplayBounds)
         }
     }
 
     /**
-     * Checks that [testApp1] layers fill the entire screen (i.e. is "fullscreen") at the end of the
-     * transition once we have fully quick switched from [testApp2] back to the [testApp1].
+     * Checks that [testApp1] layers fill the entire screen (i.e. is "fullscreen") at the end of
+     * the transition once we have fully quick switched from [testApp2] back to the [testApp1].
      */
     @Presubmit
     @Test
     fun endsWithApp1LayersCoveringFullScreen() {
         testSpec.assertLayersEnd {
-            this.visibleRegion(testApp1.component).coversExactly(startDisplayBounds)
+            this.visibleRegion(testApp1).coversExactly(startDisplayBounds)
         }
     }
 
     /**
-     * Checks that [testApp1] is the top window at the end of the transition once we have fully quick
-     * switched from [testApp2] back to the [testApp1].
+     * Checks that [testApp1] is the top window at the end of the transition once we have fully
+     * quick switched from [testApp2] back to the [testApp1].
      */
     @Presubmit
     @Test
-    fun endsWithApp1BeingOnTop() {
+    open fun endsWithApp1BeingOnTop() {
         testSpec.assertWmEnd {
-            this.isAppWindowOnTop(testApp1.component)
+            this.isAppWindowOnTop(testApp1)
         }
     }
 
     /**
-     * Checks that [testApp1]'s window starts off invisible and becomes visible at some point before
-     * the end of the transition and then stays visible until the end of the transition.
+     * Checks that [testApp1]'s window starts off invisible and becomes visible at some point
+     * before the end of the transition and then stays visible until the end of the transition.
      */
     @Presubmit
     @Test
-    fun app1WindowBecomesAndStaysVisible() {
+    open fun app1WindowBecomesAndStaysVisible() {
         testSpec.assertWm {
-            this.isAppWindowInvisible(testApp1.component)
-                    .then()
-                    .isAppWindowVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
-                    .then()
-                    .isAppWindowVisible(testApp1.component)
+            this.isAppWindowInvisible(testApp1)
+                .then()
+                .isAppWindowVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
+                .then()
+                .isAppWindowVisible(testApp1)
         }
     }
 
     /**
-     * Checks that [testApp1]'s layer starts off invisible and becomes visible at some point before
-     * the end of the transition and then stays visible until the end of the transition.
+     * Checks that [testApp1]'s layer starts off invisible and becomes visible at some point
+     * before the end of the transition and then stays visible until the end of the transition.
      */
     @Presubmit
     @Test
-    fun app1LayerBecomesAndStaysVisible() {
+    open fun app1LayerBecomesAndStaysVisible() {
         testSpec.assertLayers {
-            this.isInvisible(testApp1.component)
-                    .then()
-                    .isVisible(testApp1.component)
+            this.isInvisible(testApp1)
+                .then()
+                .isVisible(testApp1)
         }
     }
 
     /**
-     * Checks that [testApp2]'s window starts off visible and becomes invisible at some point before
-     * the end of the transition and then stays invisible until the end of the transition.
+     * Checks that [testApp2]'s window starts off visible and becomes invisible at some point
+     * before the end of the transition and then stays invisible until the end of the transition.
      */
     @Presubmit
     @Test
-    fun app2WindowBecomesAndStaysInvisible() {
+    open fun app2WindowBecomesAndStaysInvisible() {
         testSpec.assertWm {
-            this.isAppWindowVisible(testApp2.component)
-                    .then()
-                    .isAppWindowInvisible(testApp2.component)
+            this.isAppWindowVisible(testApp2)
+                .then()
+                .isAppWindowInvisible(testApp2)
         }
     }
 
     /**
-     * Checks that [testApp2]'s layer starts off visible and becomes invisible at some point before
-     * the end of the transition and then stays invisible until the end of the transition.
+     * Checks that [testApp2]'s layer starts off visible and becomes invisible at some point
+     * before the end of the transition and then stays invisible until the end of the transition.
      */
     @Presubmit
     @Test
-    fun app2LayerBecomesAndStaysInvisible() {
+    open fun app2LayerBecomesAndStaysInvisible() {
         testSpec.assertLayers {
-            this.isVisible(testApp2.component)
-                    .then()
-                    .isInvisible(testApp2.component)
+            this.isVisible(testApp2)
+                .then()
+                .isInvisible(testApp2)
         }
     }
 
@@ -242,16 +232,16 @@
      */
     @Presubmit
     @Test
-    fun app1WindowIsVisibleOnceApp2WindowIsInvisible() {
+    open fun app1WindowIsVisibleOnceApp2WindowIsInvisible() {
         testSpec.assertWm {
-            this.isAppWindowVisible(testApp2.component)
-                    .then()
-                    // TODO: Do we actually want to test this? Seems too implementation specific...
-                    .isAppWindowVisible(FlickerComponentName.LAUNCHER, isOptional = true)
-                    .then()
-                    .isAppWindowVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
-                    .then()
-                    .isAppWindowVisible(testApp1.component)
+            this.isAppWindowVisible(testApp2)
+                .then()
+                // TODO: Do we actually want to test this? Seems too implementation specific...
+                .isAppWindowVisible(ComponentMatcher.LAUNCHER, isOptional = true)
+                .then()
+                .isAppWindowVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
+                .then()
+                .isAppWindowVisible(testApp1)
         }
     }
 
@@ -262,54 +252,28 @@
      */
     @Presubmit
     @Test
-    fun app1LayerIsVisibleOnceApp2LayerIsInvisible() {
+    open fun app1LayerIsVisibleOnceApp2LayerIsInvisible() {
         testSpec.assertLayers {
-            this.isVisible(testApp2.component)
-                    .then()
-                    .isVisible(FlickerComponentName.LAUNCHER, isOptional = true)
-                    .then()
-                    .isVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
-                    .then()
-                    .isVisible(testApp1.component)
+            this.isVisible(testApp2)
+                .then()
+                .isVisible(ComponentMatcher.LAUNCHER, isOptional = true)
+                .then()
+                .isVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
+                .then()
+                .isVisible(testApp1)
         }
     }
 
-    /**
-     * Checks that the navbar window is visible throughout the entire transition.
-     */
-    @Presubmit
+    /** {@inheritDoc} */
+    @Postsubmit
     @Test
-    fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsVisible()
+    override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
 
-    /**
-     * Checks that the navbar layer is visible throughout the entire transition.
-     */
-    @Presubmit
+    /** {@inheritDoc} */
+    @Postsubmit
     @Test
-    fun navBarLayerAlwaysIsVisible() = testSpec.navBarLayerIsVisible()
-
-    /**
-     * Checks that the navbar is always in the right position and covers the expected region.
-     *
-     * NOTE: This doesn't check that the navbar is visible or not.
-     */
-    @FlakyTest
-    @Test
-    fun navbarIsAlwaysInRightPosition() = testSpec.navBarLayerRotatesAndScales()
-
-    /**
-     * Checks that the status bar window is visible throughout the entire transition.
-     */
-    @Presubmit
-    @Test
-    fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsVisible()
-
-    /**
-     * Checks that the status bar layer is visible throughout the entire transition.
-     */
-    @Presubmit
-    @Test
-    fun statusBarLayerIsAlwaysVisible() = testSpec.statusBarLayerIsVisible()
+    override fun statusBarLayerIsVisibleAtStartAndEnd() =
+        super.statusBarLayerIsVisibleAtStartAndEnd()
 
     companion object {
         private var startDisplayBounds = Rect.EMPTY
@@ -318,13 +282,13 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                    .getConfigNonRotationTests(
-                            repetitions = 3,
-                            supportedNavigationModes = listOf(
-                                    WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
-                            ),
-                            supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90)
-                    )
+                .getConfigNonRotationTests(
+                    repetitions = 3,
+                    supportedNavigationModes = listOf(
+                        WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+                    ),
+                    supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90)
+                )
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest_ShellTransit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest_ShellTransit.kt
index cabae50..e007fe3 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest_ShellTransit.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest_ShellTransit.kt
@@ -16,8 +16,8 @@
 
 package com.android.server.wm.flicker.quickswitch
 
-import android.platform.test.annotations.RequiresDevice
 import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.RequiresDevice
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.annotation.Group1
@@ -25,6 +25,7 @@
 import org.junit.Assume
 import org.junit.Before
 import org.junit.FixMethodOrder
+import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.MethodSorters
 import org.junit.runners.Parameterized
@@ -45,11 +46,34 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group1
-@FlakyTest(bugId = 228009808)
-open class QuickSwitchBetweenTwoAppsBackTest_ShellTransit(testSpec: FlickerTestParameter)
-    : QuickSwitchBetweenTwoAppsBackTest(testSpec) {
+open class QuickSwitchBetweenTwoAppsBackTest_ShellTransit(
+    testSpec: FlickerTestParameter
+) : QuickSwitchBetweenTwoAppsBackTest(testSpec) {
     @Before
     override fun before() {
         Assume.assumeTrue(isShellTransitionsEnabled)
     }
+
+    @FlakyTest(bugId = 228009808)
+    @Test
+    override fun app1LayerIsVisibleOnceApp2LayerIsInvisible() =
+        super.app1LayerIsVisibleOnceApp2LayerIsInvisible()
+
+    @FlakyTest(bugId = 228009808)
+    @Test
+    override fun app1WindowBecomesAndStaysVisible() = super.app1WindowBecomesAndStaysVisible()
+
+    @FlakyTest(bugId = 228009808)
+    @Test
+    override fun endsWithApp1BeingOnTop() = super.endsWithApp1BeingOnTop()
+
+    @FlakyTest(bugId = 239147075)
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+    @FlakyTest(bugId = 239147075)
+    @Test
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
index 9e43a97..4ce3b15 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
@@ -16,15 +16,13 @@
 
 package com.android.server.wm.flicker.quickswitch
 
-import android.app.Instrumentation
 import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.platform.test.annotations.RequiresDevice
 import android.view.Surface
 import android.view.WindowManagerPolicyConstants
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
@@ -33,12 +31,7 @@
 import com.android.server.wm.flicker.helpers.NonResizeableAppHelper
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
 import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
 import com.android.server.wm.traces.common.Rect
 import org.junit.Assume
 import org.junit.Before
@@ -64,10 +57,9 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group1
-open class QuickSwitchBetweenTwoAppsForwardTest(private val testSpec: FlickerTestParameter) {
-    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
-    private val tapl = LauncherInstrumentation()
-
+open class QuickSwitchBetweenTwoAppsForwardTest(
+    testSpec: FlickerTestParameter
+) : BaseTest(testSpec) {
     private val testApp1 = SimpleAppHelper(instrumentation)
     private val testApp2 = NonResizeableAppHelper(instrumentation)
 
@@ -76,36 +68,36 @@
         Assume.assumeFalse(isShellTransitionsEnabled)
     }
 
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            setup {
-                test {
-                    tapl.setExpectedRotation(testSpec.startRotation)
-                }
-                eachRun {
-                    testApp1.launchViaIntent(wmHelper)
-                    testApp2.launchViaIntent(wmHelper)
-                    tapl.launchedAppState.quickSwitchToPreviousApp()
-                    wmHelper.StateSyncBuilder()
-                        .withNavBarStatusBarVisible()
-                        .waitForAndVerify()
-                    startDisplayBounds = wmHelper.currentState.layerState
-                        .physicalDisplayBounds ?: error("Display not found")
-                }
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            test {
+                tapl.setExpectedRotation(testSpec.startRotation)
             }
-            transitions {
-                tapl.launchedAppState.quickSwitchToPreviousAppSwipeLeft()
+            eachRun {
+                testApp1.launchViaIntent(wmHelper)
+                testApp2.launchViaIntent(wmHelper)
+                tapl.launchedAppState.quickSwitchToPreviousApp()
                 wmHelper.StateSyncBuilder()
-                    .withNavBarStatusBarVisible()
+                    .withNavOrTaskBarVisible()
+                    .withStatusBarVisible()
                     .waitForAndVerify()
+                startDisplayBounds = wmHelper.currentState.layerState
+                    .physicalDisplayBounds ?: error("Display not found")
             }
+        }
+        transitions {
+            tapl.launchedAppState.quickSwitchToPreviousAppSwipeLeft()
+            wmHelper.StateSyncBuilder()
+                .withNavOrTaskBarVisible()
+                .withStatusBarVisible()
+                .waitForAndVerify()
+        }
 
-            teardown {
-                test {
-                    testApp1.exit(wmHelper)
-                    testApp2.exit(wmHelper)
-                }
+        teardown {
+            test {
+                testApp1.exit(wmHelper)
+                testApp2.exit(wmHelper)
             }
         }
     }
@@ -118,7 +110,7 @@
     @Test
     open fun startsWithApp1WindowsCoverFullScreen() {
         testSpec.assertWmStart {
-            this.frameRegion(testApp1.component, FlickerComponentName.LETTERBOX)
+            this.visibleRegion(testApp1.or(ComponentMatcher.LETTERBOX))
                 .coversExactly(startDisplayBounds)
         }
     }
@@ -131,7 +123,7 @@
     @Test
     open fun startsWithApp1LayersCoverFullScreen() {
         testSpec.assertLayersStart {
-            this.visibleRegion(testApp1.component).coversExactly(startDisplayBounds)
+            this.visibleRegion(testApp1).coversExactly(startDisplayBounds)
         }
     }
 
@@ -142,7 +134,7 @@
     @Test
     open fun startsWithApp1WindowBeingOnTop() {
         testSpec.assertWmStart {
-            this.isAppWindowOnTop(testApp1.component)
+            this.isAppWindowOnTop(testApp1)
         }
     }
 
@@ -154,7 +146,7 @@
     @Test
     open fun endsWithApp2WindowsCoveringFullScreen() {
         testSpec.assertWmEnd {
-            this.frameRegion(testApp2.component).coversExactly(startDisplayBounds)
+            this.visibleRegion(testApp2).coversExactly(startDisplayBounds)
         }
     }
 
@@ -166,7 +158,7 @@
     @Test
     open fun endsWithApp2LayersCoveringFullScreen() {
         testSpec.assertLayersEnd {
-            this.visibleRegion(testApp2.component, FlickerComponentName.LETTERBOX)
+            this.visibleRegion(testApp2.or(ComponentMatcher.LETTERBOX))
                 .coversExactly(startDisplayBounds)
         }
     }
@@ -179,7 +171,7 @@
     @Test
     open fun endsWithApp2BeingOnTop() {
         testSpec.assertWmEnd {
-            this.isAppWindowOnTop(testApp2.component)
+            this.isAppWindowOnTop(testApp2)
         }
     }
 
@@ -191,11 +183,11 @@
     @Test
     open fun app2WindowBecomesAndStaysVisible() {
         testSpec.assertWm {
-            this.isAppWindowInvisible(testApp2.component)
+            this.isAppWindowInvisible(testApp2)
                     .then()
-                    .isAppWindowVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
+                    .isAppWindowVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
                     .then()
-                    .isAppWindowVisible(testApp2.component)
+                    .isAppWindowVisible(testApp2)
         }
     }
 
@@ -207,9 +199,9 @@
     @Test
     open fun app2LayerBecomesAndStaysVisible() {
         testSpec.assertLayers {
-            this.isInvisible(testApp2.component)
+            this.isInvisible(testApp2)
                     .then()
-                    .isVisible(testApp2.component)
+                    .isVisible(testApp2)
         }
     }
 
@@ -221,9 +213,9 @@
     @Test
     open fun app1WindowBecomesAndStaysInvisible() {
         testSpec.assertWm {
-            this.isAppWindowVisible(testApp1.component)
+            this.isAppWindowVisible(testApp1)
                     .then()
-                    .isAppWindowInvisible(testApp1.component)
+                    .isAppWindowInvisible(testApp1)
         }
     }
 
@@ -235,9 +227,9 @@
     @Test
     open fun app1LayerBecomesAndStaysInvisible() {
         testSpec.assertLayers {
-            this.isVisible(testApp1.component)
+            this.isVisible(testApp1)
                     .then()
-                    .isInvisible(testApp1.component)
+                    .isInvisible(testApp1)
         }
     }
 
@@ -250,13 +242,13 @@
     @Test
     open fun app2WindowIsVisibleOnceApp1WindowIsInvisible() {
         testSpec.assertWm {
-            this.isAppWindowVisible(testApp1.component)
+            this.isAppWindowVisible(testApp1)
                     .then()
-                    .isAppWindowVisible(FlickerComponentName.LAUNCHER, isOptional = true)
+                    .isAppWindowVisible(ComponentMatcher.LAUNCHER, isOptional = true)
                     .then()
-                    .isAppWindowVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
+                    .isAppWindowVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
                     .then()
-                    .isAppWindowVisible(testApp2.component)
+                    .isAppWindowVisible(testApp2)
         }
     }
 
@@ -269,62 +261,38 @@
     @Test
     open fun app2LayerIsVisibleOnceApp1LayerIsInvisible() {
         testSpec.assertLayers {
-            this.isVisible(testApp1.component)
+            this.isVisible(testApp1)
                     .then()
-                    .isVisible(FlickerComponentName.LAUNCHER, isOptional = true)
+                    .isVisible(ComponentMatcher.LAUNCHER, isOptional = true)
                     .then()
-                    .isVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
+                    .isVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
                     .then()
-                    .isVisible(testApp2.component)
+                    .isVisible(testApp2)
         }
     }
 
-    /**
-     * Checks that the navbar window is visible throughout the entire transition.
-     */
-    @Presubmit
+    /** {@inheritDoc} */
+    @Postsubmit
     @Test
-    open fun navBarWindowIsAlwaysVisible() {
-        testSpec.navBarWindowIsVisible()
-    }
+    override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
 
-    /**
-     * Checks that the navbar layer is visible throughout the entire transition.
-     */
-    @Presubmit
+    /** {@inheritDoc} */
+    @FlakyTest(bugId = 239148258)
     @Test
-    open fun navBarLayerAlwaysIsVisible() {
-        testSpec.navBarLayerIsVisible()
-    }
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
 
-    /**
-     * Checks that the navbar is always in the right position and covers the expected region.
-     *
-     * NOTE: This doesn't check that the navbar is visible or not.
-     */
-    @FlakyTest
+    /** {@inheritDoc} */
+    @Postsubmit
     @Test
-    open fun navbarIsAlwaysInRightPosition() {
-        testSpec.navBarLayerRotatesAndScales()
-    }
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
 
-    /**
-     * Checks that the status bar window is visible throughout the entire transition.
-     */
-    @Presubmit
+    /** {@inheritDoc} */
+    @FlakyTest(bugId = 239148258)
     @Test
-    open fun statusBarWindowIsAlwaysVisible() {
-        testSpec.statusBarWindowIsVisible()
-    }
-
-    /**
-     * Checks that the status bar layer is visible throughout the entire transition.
-     */
-    @Presubmit
-    @Test
-    open fun statusBarLayerIsAlwaysVisible() {
-        testSpec.statusBarLayerIsVisible()
-    }
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
 
     companion object {
         private var startDisplayBounds = Rect.EMPTY
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest_ShellTransit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest_ShellTransit.kt
index 86ba7cb..6f78ba8 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest_ShellTransit.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest_ShellTransit.kt
@@ -16,8 +16,8 @@
 
 package com.android.server.wm.flicker.quickswitch
 
-import android.platform.test.annotations.RequiresDevice
 import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.RequiresDevice
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.annotation.Group1
@@ -25,6 +25,7 @@
 import org.junit.Assume
 import org.junit.Before
 import org.junit.FixMethodOrder
+import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.MethodSorters
 import org.junit.runners.Parameterized
@@ -45,11 +46,24 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group1
-@FlakyTest(bugId = 228009808)
-open class QuickSwitchBetweenTwoAppsForwardTest_ShellTransit(testSpec: FlickerTestParameter)
-    : QuickSwitchBetweenTwoAppsForwardTest(testSpec) {
+open class QuickSwitchBetweenTwoAppsForwardTest_ShellTransit(
+    testSpec: FlickerTestParameter
+) : QuickSwitchBetweenTwoAppsForwardTest(testSpec) {
     @Before
     override fun before() {
         Assume.assumeTrue(isShellTransitionsEnabled)
     }
+
+    @FlakyTest(bugId = 228009808)
+    @Test
+    override fun app2LayerIsVisibleOnceApp1LayerIsInvisible() =
+        super.app2LayerIsVisibleOnceApp1LayerIsInvisible()
+
+    @FlakyTest(bugId = 228009808)
+    @Test
+    override fun app2WindowBecomesAndStaysVisible() = super.app2WindowBecomesAndStaysVisible()
+
+    @FlakyTest(bugId = 228009808)
+    @Test
+    override fun endsWithApp2BeingOnTop() = super.endsWithApp2BeingOnTop()
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
index 4ea1f1c..2c3fce9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
@@ -16,27 +16,20 @@
 
 package com.android.server.wm.flicker.quickswitch
 
-import android.app.Instrumentation
+import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.platform.test.annotations.RequiresDevice
 import android.view.Surface
 import android.view.WindowManagerPolicyConstants
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group1
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
 import com.android.server.wm.traces.common.Rect
 import org.junit.FixMethodOrder
 import org.junit.Test
@@ -60,44 +53,40 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group1
-class QuickSwitchFromLauncherTest(private val testSpec: FlickerTestParameter) {
-    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
-    private val taplInstrumentation = LauncherInstrumentation()
-
+class QuickSwitchFromLauncherTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
     private val testApp = SimpleAppHelper(instrumentation)
 
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            setup {
-                test {
-                    taplInstrumentation.setExpectedRotation(testSpec.startRotation)
-                }
-
-                eachRun {
-                    testApp.launchViaIntent(wmHelper)
-                    device.pressHome()
-                    wmHelper.StateSyncBuilder()
-                        .withHomeActivityVisible()
-                        .withWindowSurfaceDisappeared(testApp.component)
-                        .waitForAndVerify()
-
-                    startDisplayBounds = wmHelper.currentState.layerState
-                        .physicalDisplayBounds ?: error("Display not found")
-                }
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            test {
+                tapl.setExpectedRotation(testSpec.startRotation)
             }
-            transitions {
-                taplInstrumentation.workspace.quickSwitchToPreviousApp()
+
+            eachRun {
+                testApp.launchViaIntent(wmHelper)
+                device.pressHome()
                 wmHelper.StateSyncBuilder()
-                    .withFullScreenApp(testApp.component)
-                    .withNavBarStatusBarVisible()
+                    .withHomeActivityVisible()
+                    .withWindowSurfaceDisappeared(testApp)
                     .waitForAndVerify()
-            }
 
-            teardown {
-                eachRun {
-                    testApp.exit(wmHelper)
-                }
+                startDisplayBounds = wmHelper.currentState.layerState
+                    .physicalDisplayBounds ?: error("Display not found")
+            }
+        }
+        transitions {
+            tapl.workspace.quickSwitchToPreviousApp()
+            wmHelper.StateSyncBuilder()
+                .withFullScreenApp(testApp)
+                .withNavOrTaskBarVisible()
+                .withStatusBarVisible()
+                .waitForAndVerify()
+        }
+
+        teardown {
+            eachRun {
+                testApp.exit(wmHelper)
             }
         }
     }
@@ -110,7 +99,7 @@
     @Test
     fun endsWithAppWindowsCoveringFullScreen() {
         testSpec.assertWmEnd {
-            this.frameRegion(testApp.component).coversExactly(startDisplayBounds)
+            this.visibleRegion(testApp).coversExactly(startDisplayBounds)
         }
     }
 
@@ -122,7 +111,7 @@
     @Test
     fun endsWithAppLayersCoveringFullScreen() {
         testSpec.assertLayersEnd {
-            this.visibleRegion(testApp.component).coversExactly(startDisplayBounds)
+            this.visibleRegion(testApp).coversExactly(startDisplayBounds)
         }
     }
 
@@ -134,7 +123,7 @@
     @Test
     fun endsWithAppBeingOnTop() {
         testSpec.assertWmEnd {
-            this.isAppWindowOnTop(testApp.component)
+            this.isAppWindowOnTop(testApp)
         }
     }
 
@@ -150,37 +139,37 @@
     }
 
     /**
-     * Checks that the transition starts with the launcher windows filling/covering exactly the
-     * entirety of the display.
+     * Checks that the transition starts with the [ComponentMatcher.LAUNCHER] windows
+     * filling/covering exactly display size
      */
     @Presubmit
     @Test
     fun startsWithLauncherWindowsCoverFullScreen() {
         testSpec.assertWmStart {
-            this.frameRegion(FlickerComponentName.LAUNCHER).coversExactly(startDisplayBounds)
+            this.visibleRegion(ComponentMatcher.LAUNCHER).coversExactly(startDisplayBounds)
         }
     }
 
     /**
-     * Checks that the transition starts with the launcher layers filling/covering exactly the
-     * entirety of the display.
+     * Checks that the transition starts with the [ComponentMatcher.LAUNCHER] layers
+     * filling/covering exactly the display size.
      */
     @Presubmit
     @Test
     fun startsWithLauncherLayersCoverFullScreen() {
         testSpec.assertLayersStart {
-            this.visibleRegion(FlickerComponentName.LAUNCHER).coversExactly(startDisplayBounds)
+            this.visibleRegion(ComponentMatcher.LAUNCHER).coversExactly(startDisplayBounds)
         }
     }
 
     /**
-     * Checks that the transition starts with the launcher being the top window.
+     * Checks that the transition starts with the [ComponentMatcher.LAUNCHER] being the top window.
      */
     @Presubmit
     @Test
     fun startsWithLauncherBeingOnTop() {
         testSpec.assertWmStart {
-            this.isAppWindowOnTop(FlickerComponentName.LAUNCHER)
+            this.isAppWindowOnTop(ComponentMatcher.LAUNCHER)
         }
     }
 
@@ -204,9 +193,9 @@
     @Test
     fun appWindowBecomesAndStaysVisible() {
         testSpec.assertWm {
-            this.isAppWindowInvisible(testApp.component)
+            this.isAppWindowInvisible(testApp)
                     .then()
-                    .isAppWindowVisible(testApp.component)
+                    .isAppWindowVisible(testApp)
         }
     }
 
@@ -218,117 +207,94 @@
     @Test
     fun appLayerBecomesAndStaysVisible() {
         testSpec.assertLayers {
-            this.isInvisible(testApp.component)
+            this.isInvisible(testApp)
                     .then()
-                    .isVisible(testApp.component)
+                    .isVisible(testApp)
         }
     }
 
     /**
-     * Checks that the launcher window starts off visible and becomes invisible at some point before
+     * Checks that the [ComponentMatcher.LAUNCHER] window starts off visible and becomes invisible
+     * at some point before
      * the end of the transition and then stays invisible until the end of the transition.
      */
     @Presubmit
     @Test
     fun launcherWindowBecomesAndStaysInvisible() {
         testSpec.assertWm {
-            this.isAppWindowOnTop(FlickerComponentName.LAUNCHER)
+            this.isAppWindowOnTop(ComponentMatcher.LAUNCHER)
                     .then()
-                    .isAppWindowNotOnTop(FlickerComponentName.LAUNCHER)
+                    .isAppWindowNotOnTop(ComponentMatcher.LAUNCHER)
         }
     }
 
     /**
-     * Checks that the launcher layer starts off visible and becomes invisible at some point before
+     * Checks that the [ComponentMatcher.LAUNCHER] layer starts off visible and becomes invisible
+     * at some point before
      * the end of the transition and then stays invisible until the end of the transition.
      */
     @Presubmit
     @Test
     fun launcherLayerBecomesAndStaysInvisible() {
         testSpec.assertLayers {
-            this.isVisible(FlickerComponentName.LAUNCHER)
+            this.isVisible(ComponentMatcher.LAUNCHER)
                     .then()
-                    .isInvisible(FlickerComponentName.LAUNCHER)
+                    .isInvisible(ComponentMatcher.LAUNCHER)
         }
     }
 
     /**
-     * Checks that the launcher window is visible at least until the app window is visible. Ensures
+     * Checks that the [ComponentMatcher.LAUNCHER] window is visible at least until the app window
+     * is visible. Ensures
      * that at any point, either the launcher or [testApp] windows are at least partially visible.
      */
     @Presubmit
     @Test
     fun appWindowIsVisibleOnceLauncherWindowIsInvisible() {
         testSpec.assertWm {
-            this.isAppWindowOnTop(FlickerComponentName.LAUNCHER)
+            this.isAppWindowOnTop(ComponentMatcher.LAUNCHER)
                     .then()
-                    .isAppWindowVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
+                    .isAppWindowVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
                     .then()
-                    .isAppWindowVisible(testApp.component)
+                    .isAppWindowVisible(testApp)
         }
     }
 
     /**
-     * Checks that the launcher layer is visible at least until the app layer is visible. Ensures
-     * that at any point, either the launcher or [testApp] layers are at least partially visible.
+     * Checks that the [ComponentMatcher.LAUNCHER] layer is visible at least until the app layer
+     * is visible. Ensures that at any point, either the launcher or [testApp] layers are at least
+     * partially visible.
      */
     @Presubmit
     @Test
     fun appLayerIsVisibleOnceLauncherLayerIsInvisible() {
         testSpec.assertLayers {
-            this.isVisible(FlickerComponentName.LAUNCHER)
+            this.isVisible(ComponentMatcher.LAUNCHER)
                     .then()
-                    .isVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
+                    .isVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
                     .then()
-                    .isVisible(testApp.component)
+                    .isVisible(testApp)
         }
     }
 
-    /**
-     * Checks that the navbar window is visible throughout the entire transition.
-     */
-    @Presubmit
+    /** {@inheritDoc} */
+    @Postsubmit
     @Test
-    fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsVisible()
+    override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
 
-    /**
-     * Checks that the navbar layer is visible throughout the entire transition.
-     */
-    @Presubmit
+    /** {@inheritDoc} */
+    @FlakyTest(bugId = 239148258)
     @Test
-    fun navBarLayerAlwaysIsVisible() = testSpec.navBarLayerIsVisible()
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
 
-    /**
-     * Checks that the navbar is always in the right position and covers the expected region.
-     *
-     * NOTE: This doesn't check that the navbar is visible or not.
-     */
-    @Presubmit
+    @FlakyTest(bugId = 239148258)
     @Test
-    fun navbarIsAlwaysInRightPosition() = testSpec.navBarLayerRotatesAndScales()
-
-    /**
-     * Checks that the status bar window is visible throughout the entire transition.
-     */
-    @Presubmit
-    @Test
-    fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsVisible()
-
-    /**
-     * Checks that the status bar layer is visible throughout the entire transition.
-     */
-    @Presubmit
-    @Test
-    fun statusBarLayerIsAlwaysVisible() = testSpec.statusBarLayerIsVisible()
-
-    /**
-     * Checks that the screen is always fully covered by visible layers throughout the transition.
-     */
-    @Presubmit
-    @Test
-    fun screenIsAlwaysFilled() = testSpec.entireScreenCovered()
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
 
     companion object {
+        /** {@inheritDoc} */
         private var startDisplayBounds = Rect.EMPTY
 
         @Parameterized.Parameters(name = "{0}")
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index ae32520..5e80fab 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -16,8 +16,8 @@
 
 package com.android.server.wm.flicker.rotation
 
-import android.platform.test.annotations.Presubmit
 import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.Presubmit
 import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
@@ -25,10 +25,7 @@
 import com.android.server.wm.flicker.annotation.Group3
 import com.android.server.wm.flicker.dsl.FlickerBuilder
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -102,22 +99,22 @@
     }
 
     /**
-     * Checks that the [FlickerComponentName.ROTATION] layer appears during the transition,
+     * Checks that the [ComponentMatcher.ROTATION] layer appears during the transition,
      * doesn't flicker, and disappears before the transition is complete
      */
     fun rotationLayerAppearsAndVanishesAssertion() {
         testSpec.assertLayers {
-            this.isVisible(testApp.component)
+            this.isVisible(testApp)
                 .then()
-                .isVisible(FlickerComponentName.ROTATION)
+                .isVisible(ComponentMatcher.ROTATION)
                 .then()
-                .isVisible(testApp.component)
-                .isInvisible(FlickerComponentName.ROTATION)
+                .isVisible(testApp)
+                .isInvisible(ComponentMatcher.ROTATION)
         }
     }
 
     /**
-     * Checks that the [FlickerComponentName.ROTATION] layer appears during the transition,
+     * Checks that the [ComponentMatcher.ROTATION] layer appears during the transition,
      * doesn't flicker, and disappears before the transition is complete
      */
     @Presubmit
@@ -126,38 +123,11 @@
         rotationLayerAppearsAndVanishesAssertion()
     }
 
-    /**
-     * Checks that the status bar window is visible and above the app windows in all WM
-     * trace entries
-     */
-    @Presubmit
-    @Test
-    fun statusBarWindowIsVisible() {
-        testSpec.statusBarWindowIsVisible()
-    }
-
-    /**
-     * Checks that the status bar layer is visible at the start and end of the transition
-     */
-    @Presubmit
-    @Test
-    fun statusBarLayerIsVisible() {
-        testSpec.statusBarLayerIsVisible()
-    }
-
-    /**
-     * Checks the position of the status bar at the start and end of the transition
-     */
+    /** {@inheritDoc} */
     @FlakyTest(bugId = 206753786)
     @Test
-    fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
-    /** {@inheritDoc} */
-    @FlakyTest
-    @Test
-    override fun navBarLayerRotatesAndScales() {
-        super.navBarLayerRotatesAndScales()
-    }
+    override fun navBarLayerPositionAtStartAndEnd() =
+        super.navBarLayerPositionAtStartAndEnd()
 
     /** {@inheritDoc} */
     @FlakyTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
index 586be06..36a1521 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
@@ -16,30 +16,23 @@
 
 package com.android.server.wm.flicker.rotation
 
-import android.app.Instrumentation
 import android.platform.test.annotations.Presubmit
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
 import com.android.server.wm.flicker.helpers.StandardAppHelper
 import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
 import org.junit.Test
 
 /**
  * Base class for app rotation tests
  */
-abstract class RotationTransition(protected val testSpec: FlickerTestParameter) {
+abstract class RotationTransition(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
     protected abstract val testApp: StandardAppHelper
 
-    protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
-
-    protected open val transition: FlickerBuilder.() -> Unit = {
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
         setup {
             eachRun {
                 this.setRotation(testSpec.startRotation)
@@ -55,80 +48,22 @@
         }
     }
 
-    /**
-     * Entry point for the test runner. It will use this method to initialize and cache
-     * flicker executions
-     */
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            transition()
-        }
-    }
-
-    /**
-     * Checks that the navigation bar window is visible and above the app windows in all WM
-     * trace entries
-     */
+    /** {@inheritDoc} */
     @Presubmit
     @Test
-    open fun navBarWindowIsVisible() {
-        testSpec.navBarWindowIsVisible()
-    }
-
-    /**
-     * Checks that the navigation bar layer is visible at the start and end of the transition
-     */
-    @Presubmit
-    @Test
-    open fun navBarLayerIsVisible() {
-        testSpec.navBarLayerIsVisible()
-    }
-
-    /**
-     * Checks the position of the navigation bar at the start and end of the transition
-     */
-    @Presubmit
-    @Test
-    open fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
-    /**
-     * Checks that all layers that are visible on the trace, are visible for at least 2
-     * consecutive entries.
-     */
-    @Presubmit
-    @Test
-    open fun visibleLayersShownMoreThanOneConsecutiveEntry() {
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() {
         testSpec.assertLayers {
             this.visibleLayersShownMoreThanOneConsecutiveEntry(
-                ignoreLayers = listOf(FlickerComponentName.SPLASH_SCREEN,
-                    FlickerComponentName.SNAPSHOT,
-                    FlickerComponentName("", "SecondaryHomeHandle")
+                ignoreLayers = listOf(
+                    ComponentMatcher.SPLASH_SCREEN,
+                    ComponentMatcher.SNAPSHOT,
+                    ComponentMatcher("", "SecondaryHomeHandle")
                 )
             )
         }
     }
 
     /**
-     * Checks that all windows that are visible on the trace, are visible for at least 2
-     * consecutive entries.
-     */
-    @Presubmit
-    @Test
-    open fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
-        testSpec.assertWm {
-            this.visibleWindowsShownMoreThanOneConsecutiveEntry()
-        }
-    }
-
-    /**
-     * Checks that all parts of the screen are covered during the transition
-     */
-    @Presubmit
-    @Test
-    open fun entireScreenCovered() = testSpec.entireScreenCovered()
-
-    /**
      * Checks that [testApp] layer covers the entire screen at the start of the transition
      */
     @Presubmit
@@ -136,7 +71,7 @@
     open fun appLayerRotates_StartingPos() {
         testSpec.assertLayersStart {
             this.entry.displays.map { display ->
-                this.visibleRegion(testApp.component).coversExactly(display.layerStackSpace)
+                this.visibleRegion(testApp).coversExactly(display.layerStackSpace)
             }
         }
     }
@@ -149,7 +84,7 @@
     open fun appLayerRotates_EndingPos() {
         testSpec.assertLayersEnd {
             this.entry.displays.map { display ->
-                this.visibleRegion(testApp.component).coversExactly(display.layerStackSpace)
+                this.visibleRegion(testApp).coversExactly(display.layerStackSpace)
             }
         }
     }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
index a14e4bc..1e3caa4 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
@@ -16,10 +16,10 @@
 
 package com.android.server.wm.flicker.rotation
 
+import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.Presubmit
 import android.platform.test.annotations.RequiresDevice
 import android.view.WindowManager
-import android.platform.test.annotations.FlakyTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
@@ -27,8 +27,9 @@
 import com.android.server.wm.flicker.dsl.FlickerBuilder
 import com.android.server.wm.flicker.helpers.SeamlessRotationAppHelper
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
 import org.junit.FixMethodOrder
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.MethodSorters
@@ -81,14 +82,18 @@
 ) : RotationTransition(testSpec) {
     override val testApp = SeamlessRotationAppHelper(instrumentation)
 
+    /** {@inheritDoc} */
     override val transition: FlickerBuilder.() -> Unit
         get() = {
             super.transition(this)
             setup {
                 test {
-                    testApp.launchViaIntent(wmHelper,
-                        stringExtras = mapOf(ActivityOptions.EXTRA_STARVE_UI_THREAD
-                            to testSpec.starveUiThread.toString())
+                    testApp.launchViaIntent(
+                        wmHelper,
+                        stringExtras = mapOf(
+                            ActivityOptions.EXTRA_STARVE_UI_THREAD
+                                to testSpec.starveUiThread.toString()
+                        )
                     )
                 }
             }
@@ -122,8 +127,10 @@
                 val appWindow = it.windowState(testApp.`package`)
                 val rotationAnimation = appWindow.windowState?.attributes?.rotationAnimation ?: 0
                 appWindow.verify("isRotationSeamless")
-                    .that(rotationAnimation
-                        .and(WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS))
+                    .that(
+                        rotationAnimation
+                            .and(WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS)
+                    )
                     .isGreaterThan(0)
             }
         }
@@ -136,7 +143,7 @@
     @Test
     fun appLayerAlwaysVisible() {
         testSpec.assertLayers {
-            isVisible(testApp.component)
+            isVisible(testApp)
         }
     }
 
@@ -149,33 +156,49 @@
         testSpec.assertLayers {
             this.invoke("entireScreenCovered") { entry ->
                 entry.entry.displays.map { display ->
-                    entry.visibleRegion(testApp.component).coversExactly(display.layerStackSpace)
+                    entry.visibleRegion(testApp)
+                        .coversExactly(display.layerStackSpace)
                 }
             }
         }
     }
 
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Not applicable to this CUJ. App is full screen")
+    override fun statusBarLayerPositionAtStartAndEnd() { }
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Not applicable to this CUJ. App is full screen")
+    override fun statusBarLayerIsVisibleAtStartAndEnd() { }
+
+    /** {@inheritDoc} */
+    @Test
+    @Ignore("Not applicable to this CUJ. App is full screen")
+    override fun statusBarWindowIsAlwaysVisible() { }
+
     /**
-     * Checks that the [FlickerComponentName.STATUS_BAR] window is invisible during the whole
+     * Checks that the [ComponentMatcher.STATUS_BAR] window is invisible during the whole
      * transition
      */
     @Presubmit
     @Test
     fun statusBarWindowIsAlwaysInvisible() {
         testSpec.assertWm {
-            this.isAboveAppWindowInvisible(FlickerComponentName.STATUS_BAR)
+            this.isAboveAppWindowInvisible(ComponentMatcher.STATUS_BAR)
         }
     }
 
     /**
-     * Checks that the [FlickerComponentName.STATUS_BAR] layer is invisible during the whole
+     * Checks that the [ComponentMatcher.STATUS_BAR] layer is invisible during the whole
      * transition
      */
     @Presubmit
     @Test
     fun statusBarLayerIsAlwaysInvisible() {
         testSpec.assertLayers {
-            this.isInvisible(FlickerComponentName.STATUS_BAR)
+            this.isInvisible(ComponentMatcher.STATUS_BAR)
         }
     }
 
@@ -193,7 +216,7 @@
     /** {@inheritDoc} */
     @FlakyTest
     @Test
-    override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
+    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
 
     companion object {
         private val FlickerTestParameter.starveUiThread
diff --git a/tests/FlickerTests/test-apps/flickerapp/Android.bp b/tests/FlickerTests/test-apps/flickerapp/Android.bp
index 78660c0..0c698ab 100644
--- a/tests/FlickerTests/test-apps/flickerapp/Android.bp
+++ b/tests/FlickerTests/test-apps/flickerapp/Android.bp
@@ -26,6 +26,11 @@
     srcs: ["**/*.java"],
     sdk_version: "current",
     test_suites: ["device-tests"],
+    static_libs: [
+        "androidx.test.ext.junit",
+        "wm-flicker-common-app-helpers",
+        "wm-flicker-window-extensions",
+    ],
 }
 
 java_library {
diff --git a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
index 3e2130d..387f19b 100644
--- a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
@@ -15,12 +15,14 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-     package="com.android.server.wm.flicker.testapp">
+    package="com.android.server.wm.flicker.testapp">
 
     <uses-sdk android:minSdkVersion="29"
          android:targetSdkVersion="29"/>
     <application android:allowBackup="false"
          android:supportsRtl="true">
+        <uses-library android:name="androidx.window.extensions" android:required="false"/>
+
         <activity android:name=".SimpleActivity"
              android:taskAffinity="com.android.server.wm.flicker.testapp.SimpleActivity"
              android:theme="@style/CutoutShortEdges"
@@ -163,5 +165,33 @@
                 <category android:name="android.intent.category.LAUNCHER"/>
             </intent-filter>
         </activity>
+
+        <activity
+            android:name=".ActivityEmbeddingMainActivity"
+            android:label="ActivityEmbedding Main"
+            android:taskAffinity="com.android.server.wm.flicker.testapp.ActivityEmbedding"
+            android:theme="@style/CutoutShortEdges"
+            android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
+            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=".ActivityEmbeddingPlaceholderPrimaryActivity"
+            android:label="ActivityEmbedding Placeholder Primary"
+            android:taskAffinity="com.android.server.wm.flicker.testapp.ActivityEmbedding"
+            android:theme="@style/CutoutShortEdges"
+            android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
+            android:exported="false">
+        </activity>
+        <activity
+            android:name=".ActivityEmbeddingPlaceholderSecondaryActivity"
+            android:label="ActivityEmbedding Placeholder Secondary"
+            android:taskAffinity="com.android.server.wm.flicker.testapp.ActivityEmbedding"
+            android:theme="@style/CutoutShortEdges"
+            android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
+            android:exported="false"/>
     </application>
 </manifest>
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_base_layout.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_base_layout.xml
new file mode 100644
index 0000000..3a02cad
--- /dev/null
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_base_layout.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2022 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.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/root_activity_layout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+</LinearLayout>
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_main_layout.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_main_layout.xml
new file mode 100644
index 0000000..19c81a8
--- /dev/null
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_main_layout.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2022 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.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:background="@android:color/holo_orange_light">
+
+    <Button
+        android:id="@+id/launch_placeholder_split_button"
+        android:layout_width="wrap_content"
+        android:layout_height="48dp"
+        android:layout_centerHorizontal="true"
+        android:onClick="launchPlaceholderSplit"
+        android:text="Launch Placeholder Split" />
+
+</LinearLayout>
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingBaseActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingBaseActivity.java
new file mode 100644
index 0000000..cd23e9f
--- /dev/null
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingBaseActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.testapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/** Base activity of ActivityEmbedding split activities. */
+public abstract class ActivityEmbeddingBaseActivity extends Activity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_embedding_base_layout);
+        findViewById(R.id.root_activity_layout).setBackgroundColor(getBackgroundColor());
+    }
+
+    /** Sets different colors to visually distinguish split pairs. */
+    abstract int getBackgroundColor();
+}
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingMainActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingMainActivity.java
new file mode 100644
index 0000000..166e3ca
--- /dev/null
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingMainActivity.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.testapp;
+
+import static com.android.server.wm.flicker.testapp.ActivityOptions.ACTIVITY_EMBEDDING_PLACEHOLDER_PRIMARY_ACTIVITY_COMPONENT_NAME;
+import static com.android.server.wm.flicker.testapp.ActivityOptions.ACTIVITY_EMBEDDING_PLACEHOLDER_SECONDARY_ACTIVITY_COMPONENT_NAME;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.ArraySet;
+import android.util.Log;
+import android.view.View;
+
+import androidx.window.extensions.embedding.ActivityEmbeddingComponent;
+import androidx.window.extensions.embedding.EmbeddingRule;
+import androidx.window.extensions.embedding.SplitPlaceholderRule;
+
+import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper;
+
+import java.util.Set;
+
+/** Main activity of the ActivityEmbedding test app to launch other embedding activities. */
+public class ActivityEmbeddingMainActivity extends Activity {
+    private static final String TAG = "ActivityEmbeddingMainActivity";
+    private static final float DEFAULT_SPLIT_RATIO = 0.5f;
+
+    private ActivityEmbeddingComponent mEmbeddingComponent;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_embedding_main_layout);
+
+        initializeSplitRules();
+    }
+
+    /** R.id.launch_placeholder_split_button onClick */
+    public void launchPlaceholderSplit(View view) {
+        startActivity(new Intent().setComponent(
+                ACTIVITY_EMBEDDING_PLACEHOLDER_PRIMARY_ACTIVITY_COMPONENT_NAME));
+    }
+
+    private void initializeSplitRules() {
+        mEmbeddingComponent = ActivityEmbeddingAppHelper.getActivityEmbeddingComponent();
+        if (mEmbeddingComponent == null) {
+            // Embedding not supported
+            Log.d(TAG, "ActivityEmbedding is not supported on this device");
+            finish();
+            return;
+        }
+
+        mEmbeddingComponent.setEmbeddingRules(getSplitRules());
+    }
+
+    private Set<EmbeddingRule> getSplitRules() {
+        final Set<EmbeddingRule> rules = new ArraySet<>();
+
+        final SplitPlaceholderRule placeholderRule = new SplitPlaceholderRule.Builder(
+                new Intent().setComponent(
+                        ACTIVITY_EMBEDDING_PLACEHOLDER_SECONDARY_ACTIVITY_COMPONENT_NAME),
+                activity -> activity instanceof ActivityEmbeddingPlaceholderPrimaryActivity,
+                intent -> intent.getComponent().equals(
+                        ACTIVITY_EMBEDDING_PLACEHOLDER_PRIMARY_ACTIVITY_COMPONENT_NAME),
+                windowMetrics -> true)
+                .setSplitRatio(DEFAULT_SPLIT_RATIO)
+                .build();
+        rules.add(placeholderRule);
+        return rules;
+    }
+}
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingPlaceholderPrimaryActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingPlaceholderPrimaryActivity.java
new file mode 100644
index 0000000..05c7a0b
--- /dev/null
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingPlaceholderPrimaryActivity.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.testapp;
+
+import android.graphics.Color;
+
+/**
+ * Primary activity that will launch {@link ActivityEmbeddingPlaceholderSecondaryActivity} to split
+ * as placeholder based on the placeholder rule.
+ */
+public class ActivityEmbeddingPlaceholderPrimaryActivity extends ActivityEmbeddingBaseActivity {
+    @Override
+    int getBackgroundColor() {
+        return Color.BLUE;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingPlaceholderSecondaryActivity.java
similarity index 60%
copy from packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java
copy to tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingPlaceholderSecondaryActivity.java
index 2aaf6a5..a9a51cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingPlaceholderSecondaryActivity.java
@@ -14,17 +14,17 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone;
+package com.android.server.wm.flicker.testapp;
 
-import com.android.systemui.dagger.SysUISingleton;
+import android.graphics.Color;
 
-import dagger.Binds;
-import dagger.Module;
-
-/** Provides a {@link NotifPanelEvents} in {@link SysUISingleton} scope. */
-@Module
-public abstract class NotifPanelEventsModule {
-    @Binds
-    abstract NotifPanelEvents bindPanelEvents(
-            NotificationPanelViewController.PanelEventsEmitter impl);
+/**
+ * Activity to be used as the secondary placeholder activity to split with
+ * {@link ActivityEmbeddingPlaceholderPrimaryActivity}.
+ */
+public class ActivityEmbeddingPlaceholderSecondaryActivity extends ActivityEmbeddingBaseActivity {
+    @Override
+    int getBackgroundColor() {
+        return Color.GREEN;
+    }
 }
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
index 6cda482..19fafb7 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
@@ -87,4 +87,17 @@
     public static final ComponentName NOTIFICATION_ACTIVITY_COMPONENT_NAME =
             new ComponentName(FLICKER_APP_PACKAGE,
                     FLICKER_APP_PACKAGE + ".NotificationActivity");
+
+    public static final String ACTIVITY_EMBEDDING_LAUNCHER_NAME = "ActivityEmbeddingMainActivity";
+    public static final ComponentName ACTIVITY_EMBEDDING_MAIN_ACTIVITY_COMPONENT_NAME =
+            new ComponentName(FLICKER_APP_PACKAGE,
+                    FLICKER_APP_PACKAGE + ".ActivityEmbeddingMainActivity");
+    public static final ComponentName
+            ACTIVITY_EMBEDDING_PLACEHOLDER_PRIMARY_ACTIVITY_COMPONENT_NAME = new ComponentName(
+                    FLICKER_APP_PACKAGE,
+            FLICKER_APP_PACKAGE + ".ActivityEmbeddingPlaceholderPrimaryActivity");
+    public static final ComponentName
+            ACTIVITY_EMBEDDING_PLACEHOLDER_SECONDARY_ACTIVITY_COMPONENT_NAME = new ComponentName(
+                    FLICKER_APP_PACKAGE,
+            FLICKER_APP_PACKAGE + ".ActivityEmbeddingPlaceholderSecondaryActivity");
 }
diff --git a/tests/StagedInstallTest/Android.bp b/tests/StagedInstallTest/Android.bp
index cce0dde..1709e15 100644
--- a/tests/StagedInstallTest/Android.bp
+++ b/tests/StagedInstallTest/Android.bp
@@ -57,6 +57,7 @@
     data: [
         ":apex.apexd_test",
         ":com.android.apex.apkrollback.test_v1",
+        ":com.android.apex.apkrollback.test_v2",
         ":StagedInstallTestApexV2",
         ":StagedInstallTestApexV2_WrongSha",
         ":TestAppAv1",
diff --git a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
index ab83997..0375f66 100644
--- a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
@@ -66,6 +66,7 @@
 @RunWith(JUnit4.class)
 public class StagedInstallInternalTest {
     private static final String APK_IN_APEX_TESTAPEX_NAME = "com.android.apex.apkrollback.test";
+    private static final String REBOOTLESS_APEX_PACKAGE_NAME = "test.apex.rebootless";
     private static final TestApp TEST_APEX_WITH_APK_V2 = new TestApp("TestApexWithApkV2",
             APK_IN_APEX_TESTAPEX_NAME, 2, /*isApex*/true, APK_IN_APEX_TESTAPEX_NAME + "_v2.apex");
     private static final TestApp APEX_WRONG_SHA_V2 = new TestApp(
@@ -594,6 +595,28 @@
         assertThat(InstallUtils.getInstalledVersion(packageName)).isEqualTo(1);
     }
 
+    @Test
+    public void testVendorApex_VerifyFactory() throws Exception {
+        final PackageManager pm =
+                InstrumentationRegistry.getInstrumentation().getContext().getPackageManager();
+        PackageInfo pi = pm.getPackageInfo(REBOOTLESS_APEX_PACKAGE_NAME, PackageManager.MATCH_APEX);
+        assertThat(pi.getLongVersionCode()).isEqualTo(1);
+        assertThat(pi.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR)
+                .isEqualTo(ApplicationInfo.PRIVATE_FLAG_VENDOR);
+        assertThat(pi.applicationInfo.sourceDir).startsWith("/vendor/apex");
+    }
+
+    @Test
+    public void testVendorApex_VerifyData() throws Exception {
+        final PackageManager pm =
+                InstrumentationRegistry.getInstrumentation().getContext().getPackageManager();
+        PackageInfo pi = pm.getPackageInfo(REBOOTLESS_APEX_PACKAGE_NAME, PackageManager.MATCH_APEX);
+        assertThat(pi.getLongVersionCode()).isEqualTo(2);
+        assertThat(pi.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR)
+                .isEqualTo(ApplicationInfo.PRIVATE_FLAG_VENDOR);
+        assertThat(pi.applicationInfo.sourceDir).startsWith("/data/apex");
+    }
+
     private IPackageManagerNative getPackageManagerNative() {
         IBinder binder = ServiceManager.waitForService("package_native");
         assertThat(binder).isNotNull();
diff --git a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
index 7e0a55f..c4cb33d 100644
--- a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
@@ -31,6 +31,7 @@
 import com.android.ddmlib.Log;
 import com.android.tests.rollback.host.AbandonSessionsRule;
 import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.PackageInfo;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 import com.android.tradefed.util.CommandResult;
@@ -63,6 +64,8 @@
     private static final String APK_IN_APEX_TESTAPEX_NAME = "com.android.apex.apkrollback.test";
     private static final String APEXD_TEST_APEX = "apex.apexd_test.apex";
     private static final String FAKE_APEX_SYSTEM_SERVER_APEX = "test_com.android.server.apex";
+    private static final String REBOOTLESS_V1 = "test.rebootless_apex_v1.apex";
+    private static final String REBOOTLESS_V2 = "test.rebootless_apex_v2.apex";
 
     private static final String TEST_VENDOR_APEX_ALLOW_LIST =
             "/vendor/etc/sysconfig/test-vendor-apex-allow-list.xml";
@@ -94,6 +97,7 @@
                 "/data/apex/active/" + APK_IN_APEX_TESTAPEX_NAME + "*.apex",
                 "/data/apex/active/" + SHIM_APEX_PACKAGE_NAME + "*.apex",
                 "/system/apex/test.rebootless_apex_v*.apex",
+                "/vendor/apex/test.rebootless_apex_v*.apex",
                 "/data/apex/active/test.apex.rebootless*.apex",
                 "/system/app/TestApp/TestAppAv1.apk",
                 TEST_VENDOR_APEX_ALLOW_LIST);
@@ -137,13 +141,17 @@
     }
 
     private void pushTestApex(String fileName) throws Exception {
+        pushTestApex(fileName, "system");
+    }
+
+    private void pushTestApex(String fileName, String partition) throws Exception {
         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
         final File apex = buildHelper.getTestFile(fileName);
         if (!getDevice().isAdbRoot()) {
             getDevice().enableAdbRoot();
         }
         getDevice().remountSystemWritable();
-        assertTrue(getDevice().pushFile(apex, "/system/apex/" + fileName));
+        assertTrue(getDevice().pushFile(apex, "/" + partition + "/apex/" + fileName));
     }
 
     private void pushTestVendorApexAllowList(String installerPackageName) throws Exception {
@@ -196,6 +204,28 @@
         runPhase("testDuplicateApkInApexShouldFail_Verify");
     }
 
+    /**
+     * Tests the cache of apk-in-apex is pruned and rebuilt correctly.
+     */
+    @Test
+    @LargeTest
+    public void testApkInApexPruneCache() throws Exception {
+        final String apkInApexPackageName = "com.android.cts.install.lib.testapp.A";
+
+        pushTestApex(APK_IN_APEX_TESTAPEX_NAME + "_v1.apex");
+        getDevice().reboot();
+        PackageInfo pi = getDevice().getAppPackageInfo(apkInApexPackageName);
+        assertThat(Integer.parseInt(pi.getVersionCode())).isEqualTo(1);
+        assertThat(pi.getCodePath()).startsWith("/apex/" + APK_IN_APEX_TESTAPEX_NAME);
+
+        installPackage(APK_IN_APEX_TESTAPEX_NAME + "_v2.apex", "--staged");
+        getDevice().reboot();
+        pi = getDevice().getAppPackageInfo(apkInApexPackageName);
+        // The version code of apk-in-apex will be stale if the cache is not rebuilt
+        assertThat(Integer.parseInt(pi.getVersionCode())).isEqualTo(2);
+        assertThat(pi.getCodePath()).startsWith("/apex/" + APK_IN_APEX_TESTAPEX_NAME);
+    }
+
     @Test
     public void testSystemServerRestartDoesNotAffectStagedSessions() throws Exception {
         runPhase("testSystemServerRestartDoesNotAffectStagedSessions_Commit");
@@ -497,6 +527,33 @@
         runPhase("testVendorApexCorrectInstaller_nonStaged");
     }
 
+    /**
+     * Tests correctness of {@link android.content.pm.ApplicationInfo} for APEXes on /vendor.
+     */
+    @Test
+    @LargeTest
+    public void testVendorApex_Staged() throws Exception {
+        pushTestApex(REBOOTLESS_V1, "vendor");
+        getDevice().reboot();
+        runPhase("testVendorApex_VerifyFactory");
+        installPackage(REBOOTLESS_V2, "--staged");
+        getDevice().reboot();
+        runPhase("testVendorApex_VerifyData");
+    }
+
+    /**
+     * Tests correctness of {@link android.content.pm.ApplicationInfo} for APEXes on /vendor.
+     */
+    @Test
+    @LargeTest
+    public void testVendorApex_NonStaged() throws Exception {
+        pushTestApex(REBOOTLESS_V1, "vendor");
+        getDevice().reboot();
+        runPhase("testVendorApex_VerifyFactory");
+        installPackage(REBOOTLESS_V2, "--force-non-staged");
+        runPhase("testVendorApex_VerifyData");
+    }
+
     @Test
     public void testRebootlessUpdates() throws Exception {
         pushTestApex("test.rebootless_apex_v1.apex");
diff --git a/tests/UsbManagerTests/lib/src/com/android/server/usblib/UsbManagerTestLib.java b/tests/UsbManagerTests/lib/src/com/android/server/usblib/UsbManagerTestLib.java
index 782439f..d133f6f 100644
--- a/tests/UsbManagerTests/lib/src/com/android/server/usblib/UsbManagerTestLib.java
+++ b/tests/UsbManagerTests/lib/src/com/android/server/usblib/UsbManagerTestLib.java
@@ -117,6 +117,7 @@
         testGetCurrentFunctionsMock_Matched(UsbManager.FUNCTION_PTP);
         testGetCurrentFunctionsMock_Matched(UsbManager.FUNCTION_MIDI);
         testGetCurrentFunctionsMock_Matched(UsbManager.FUNCTION_RNDIS);
+        testGetCurrentFunctionsMock_Matched(UsbManager.FUNCTION_NCM);
     }
 
     public void testSetCurrentFunctions_shouldMatched() {
@@ -125,5 +126,6 @@
         testSetCurrentFunctionsMock_Matched(UsbManager.FUNCTION_PTP);
         testSetCurrentFunctionsMock_Matched(UsbManager.FUNCTION_MIDI);
         testSetCurrentFunctionsMock_Matched(UsbManager.FUNCTION_RNDIS);
+        testSetCurrentFunctionsMock_Matched(UsbManager.FUNCTION_NCM);
     }
 }
diff --git a/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java b/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java
index 861d221..86bcb72 100644
--- a/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java
+++ b/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java
@@ -182,6 +182,14 @@
 
     @SmallTest
     @Test
+    public void setFunctionsNcm() {
+        mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS,
+                UsbManager.FUNCTION_NCM));
+        assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_NCM, 0);
+    }
+
+    @SmallTest
+    @Test
     public void setFunctionsNcmAndRndis() {
         final long rndisPlusNcm = UsbManager.FUNCTION_RNDIS | UsbManager.FUNCTION_NCM;
 
diff --git a/tools/lint/Android.bp b/tools/lint/Android.bp
index 17547ef..3458359 100644
--- a/tools/lint/Android.bp
+++ b/tools/lint/Android.bp
@@ -29,6 +29,7 @@
         "auto_service_annotations",
         "lint_api",
     ],
+    kotlincflags: ["-Xjvm-default=all"],
 }
 
 java_test_host {